VBA 将用户窗体控件作为参数传递

VBA passing userform controls as parameters

我想让位于另一个模块中的 Sub 修改用户窗体标签的 .Caption

  Private Sub UserForm_Activate()

    Dim Vs_Label as string
    Label_S.Caption = "something"

    Call ChangeLabel(Vs_Label)
    Label_S.Caption = Vs_Label

    Call ChangeLabel(Label_S.Caption)
  end

  Sub ChangeLabel(Vs_Label)
    Vs_Label = "something else"
  end

第一次调用过程时,它 returns Vs_Label = "something else"。 第二次调用程序 returns Label_S.Capiton= "something".

谁能给我解释一下这是怎么回事?

Sub ChangeLabel(Vs_Label)

首先,让我们通过显式显示所有修饰符和类型来使事情更清楚。

Public Sub ChangeLabel(ByRef Vs_Label As Variant)

我们得到了一个名为 Vs_Label 的局部变量,其初始值为 vbNullString.

Dim Vs_Label as String
Label_S.Caption = "something"

此时Vs_Label还是vbNullStringLabel_S.Caption是"something"。

Call ChangeLabel(Vs_Label)

现在我们将 Vs_Label 变量指针传递给过程,该过程将其分配给 "something else"。请注意,这将是等效的,并且可以说是更清晰的代码:

ChangeLabel Vs_Label

这条语句returns之后,Vs_Label就是"somethign else",而Label_S.Caption还是"something"。

Label_S.Caption = Vs_Label

现在 Vs_LabelLabel_S.Caption 都包含 "something else"。

Call ChangeLabel(Label_S.Caption)

这个调用现在不同了:我们传入的不是变量引用,而是成员表达式。

因此成员表达式被计算 ("something else"),并且对 那个值 的引用(调用者没有持有)被传递给过程,将其分配给 "something else"(无变化),...然后丢弃引用:第二次调用没有任何效果。

所以在程序结束时 Vs_LabelLabel_S.Caption 都是 "something else".

为了使标签的 Caption 成为 "something",在该代码的末尾,您需要使用不同的代码。

在过程顶部附近放置一个断点 (F9),运行 代码,然后使用 F8 单步执行并检查您的标签和变量:您会发现这段代码有与标签为何显示 "something".

无关

在您正在查看的两个地方验证您正在使用的表单实例 - 并确保这两个地方都在使用相同的对象实例。 Activate 处理程序将 运行 每次激活表单时 - 如果表单未显示为模态对话框,则每次可能多次实例.