【问题标题】:How do I reference the current form in an expression in Microsoft Access?如何在 Microsoft Access 的表达式中引用当前表单?
【发布时间】:2012-02-05 23:05:01
【问题描述】:

我不是 Access 专家,我有一个(希望!)简单的问题...

我有一个包含许多记录的表单。在某些文本框中,我只显示基础表中的值 - 因此它们绑定到相应的字段。

但有些文本框应该包含计算值。有些计算很复杂,涉及表中的许多字段。我将计算编写为 VBA 函数。我可以输入这样的内容作为“控制源”:

=MyFunction([Field1], [Field2], [Field3] ...)

但我不想在函数调用中列出几十个字段。相反,我想将整个表单(或当前记录)作为参数发送,并让函数引用它需要的字段。我可以这样做:

=MyFunction([Forms]![MyForm])

但我不喜欢在通话中为表单命名。没有办法将“当前形式”作为函数参数发送吗?在 VBA 中,您只需使用“Me”关键字,例如“Me![Field1]”。但似乎“我”在表达式中不被接受。

还有其他方法可以引用表达式中的当前表单吗?

(我知道这是一个装饰性问题。但是使用“[Form]![MyForm]”并不是一个好的编程。稍后您将控件复制到另一个表单并忘记更改表达式中的名称...... )

感谢您的帮助! :-)

/安德斯

【问题讨论】:

    标签: forms ms-access reference


    【解决方案1】:

    你可以使用:

    =MyFunction([Form])
    

    代码是:

    Function MyFunction(frm As Form)
    MsgBox frm.Name
    End Function
    

    【讨论】:

      【解决方案2】:

      'me' 只能从相应的表单对象中调用(即在对象的过程、函数和事件中)。

      我最喜欢引用当前表单的方式是调用 screen.activeForm 对象...

      screen.activeForm.recordset.fields(myFieldname).value
      screen.activeForm.controls(myControl).value
      screen.activeForm.name
      ....
      

      当然你可以将表单对象发送到自定义函数

      my Result = myCustomFunction(screen.activeForm)
      

      或者您可以构建一个用户定义的对象。然后可以将所需字段视为内部属性,在相应对象的 Class_Initialize 子中设置。

      【讨论】:

      • Screen.ActiveForm.Name 可以在全局函数中使用!谢谢!
      • 我认为这应该被标记为答案,因为它可以在比将表单名称作为参数传递更多的情况下实现目标,并且根本不需要传递参数 -更整洁,更少混乱的代码。向菲利普·格隆迪尔致敬!这解决了我非常巧妙地解决的一个问题。
      【解决方案3】:

      如果您在表单中使用代码,则“我”将引用当前表单。所以

      Call SomeFunction(me)
      

      但是,“me”不能用于绑定到文本框的表达式的上下文中。

      在这种情况下,您可以按照建议使用 screen.activeform 在例程中选取当前屏幕。

      我经常去:

      Dim f     as form
      Set f = screen.ActiveForm
      

      【讨论】:

      • 很有可能使用控件的属性表将事件甚至对象的控制源设置为函数,我相信您知道,在这种情况下=AFunction([Form]) 可以相当有用。如果您希望将控件剪切并粘贴到多个表单中,它特别有用。我相信 OP 正在考虑的正是这个功能。
      • 天哪,我不知道 [Form] 可以用来代替表达式中的关键字 [me]。这确实有效并且确实传递了表单名称,并且没有硬编码。这个技巧无疑开辟了一些我不知道的可能性。
      • 是的,我不知道表达式中的“Form”类似于 VBA 中的“Me”关键字。非常便利。我似乎找不到这种技术的文档,但它确实有效!
      【解决方案4】:
      Screen.ActiveControl.Parent
      ' or
      someControlVariable.Parent
      

      如果我想要当前子表单(或者如果当前不在子表单中的表单),我会使用它,因为使用Screen.ActiveForm 不会提供当前子表单,而只会提供包含该子表单的表单。请注意您的上下文,如果控件位于选项卡控件中,则其父级是该选项卡控件而不是表单。

      【讨论】:

        【解决方案5】:

        在 ACC2013 中,我无法使用 fionnuala 的答案。于是我改成了:

        属性窗口中的事件处理程序:

        =MyFunction()
        

        我的代码是:

        Function MyFunction()
          Dim frm As Form   
          Set frm = Screen.ActiveForm
          MsgBox frm.Name
        End Function
        

        【讨论】:

        • 如前所述,您可以传递“me”或[form],但必须将“[form]”替换为表单的实际名称。所以 fionnuala 答案会起作用,但你永远不要使用 [Form],而是用表单名称替换表单,例如 FORMS!SomeFormName。我认为最好将“我”传递给例程,因为这样代码可以从表单正确运行,以防启动其他表单或获取焦点,然后您的代码将不会从中出错。但是你使用 Screen.ActiveForm 没问题。
        • 为什么在 Expression Builder 中使用 [Form] 会出现问题?在这种情况下,ActiveForm 甚至是一个选项吗?我认为显式使用表单名称有一个缺点,因为这些名称可以更改,或者您可能想窃取表单的表达式或代码,但为表单使用不同的名称。
        【解决方案6】:

        Philippe Grondier above 采用的方法更通用,特别是当您需要引用表单上的字段时,该字段是表单对象的新实例,并且组合控件查询条件引用同一字段上的另一个字段的值形式。只要它是活动表单,您就可以使用返回值的函数。例如

        Public Function ActiveFormControlValue(strControlName As String) As Variant
            ActiveFormControlValue = Screen.ActiveForm.Controls(strControlName).Value
        End Function
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-02-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-11-21
          • 2012-10-26
          相关资源
          最近更新 更多