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

我想由位于另一个模块中的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

第一次调用该过程时,它返回Vs_Label =“其他”。 第二次调用该过程时,它返回Label_S.Capiton =“ something”。

有人可以向我解释这里发生了什么吗?

k12play 回答:VBA将用户窗体控件作为参数传递

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仍然是vbNullString,而Label_S.Caption是“某物”。

Call ChangeLabel(Vs_Label)

现在,我们将Vs_Label变量指针传递给该过程,该过程将其分配给“其他”。请注意,这将是等效的,并且可以说是更简洁的代码:

ChangeLabel Vs_Label

此语句返回后,Vs_Label是“其他”,而Label_S.Caption仍然是“其他”。

Label_S.Caption = Vs_Label

现在Vs_LabelLabel_S.Caption都包含“其他”。

Call ChangeLabel(Label_S.Caption)

此调用现在有所不同:我们不是传递变量引用,而是成员表达式。

因此,对成员表达式进行求值(“其他”),并将对该值的引用(调用者不保留)传递给过程,该过程将其分配给“其他”(不变),然后引用被丢弃:第二次调用无效。

因此,在过程结束时,Vs_LabelLabel_S.Caption都是“别的东西”。

要使标签的Caption为“某物”,在该代码的末尾,您需要使用其他代码。

在过程(F9)顶部附近放置一个断点,运行代码,然后使用F8逐步检查标签和变量:您将发现此代码与为什么标签上写着“某物”。

在要查找的两个地方验证正在使用的表单的哪个实例-并确保两个地方都在同一个对象实例上工作。 Activate处理程序将在每次激活表单时运行 -如果未将表单显示为模式对话框,则每个实例可能多次。

本文链接:https://www.f2er.com/2940367.html

大家都在问