【问题标题】:Passing the name of a form so it can be used by another Sub传递表单的名称,以便另一个子可以使用它
【发布时间】:2022-03-23 22:28:58
【问题描述】:

我在 Excel VBA 中有一个主 Sub,它使用几个用户窗体。

我需要从主 Sub 调用另一个使用相同表单的 Sub。

主 Sub 使用 myForm.show 显示表单,然后更改诸如 myForm.label1 = "Hello" 之类的内容。

我被困的地方是将名称传递给另一个 Sub 并让另一个 Sub 使用它。

这是我编写的代码的简化示例:

Private Sub Mainsub()
   myForm.show
   myForm.label1 = "Hello"
   call otherSub("myForm")
End Sub

Private Sub otherSub(frm as String)
   Dim objForm as Object
   Set objForm = UserForms.Add(frm)
   objForm.label1 = "Byebye"
End Sub

我没有收到任何错误,但是表单上的标签没有改变,在这种情况下用 F8 调试也没有用。

【问题讨论】:

  • 您的代码最后只是缺少objForm.Show。当我测试它时,该标签甚至可以与您的代码一起使用。还要注意表单的 .ShowModal 属性,因为您的代码将根据该设置表现不同。

标签: excel vba


【解决方案1】:

我不确定我是否正确理解了这个问题,但这里有一些提示。

  1. 表单就是对象

您正在做的是使用 myForm 的默认实例,应该避免这种情况。相反,最好更新表单,如下所示:

dim frm as myForm ' Assuming myForm is the name of the form in the name field of the properties.
set frm = new myForm ' Now you have an instance of myForm, which you can pass along to other subs.
frm.label1 = "Hello"
frm.show

othersub frm


end Sub
public sub otherSub(byref frm as myForm)
frm.label1 = "byebye"
frm.show
end sub
  1. 如果您有 myForm1 和 myForm2,即具有不同类型的两个不同表单,并且您希望能够将一个或另一个传递给 OtherSub 并更改标签,该怎么办。

在这种情况下,我会做的是使用changeLabel(byval lbl as string) 方法创建一个接口。

为此,您需要创建一个名为 ILabelModifiable 的类模块(例如),您将在其中声明:

public sub changelabel(byval lbl as string)
public sub show() ' You need this method to be able to show the form.

然后,在 myForm1 和 myForm2 中,您将在代码隐藏的顶部添加: Implements ILabelModifiable 并在表单的主体中,创建以下子

private sub ILabelModifiable_changelabel(byval lbl as string)
    me.label1 = lbl
end

private sub ILabelModifiable_show()
    me.show
end  

完成此操作后,主要代码变为:

dim frm as iLabelModifiable 
set frm = new myForm1 

frm.changelabel "Hello"
frm.show

othersub frm

end Sub

public sub otherSub(byref frm as ILabelModifiable)
frm.changelabel "byebye"
frm.show
end sub

此方法的一个额外好处是您的代码不需要知道实际调用的标签是什么。可以在Myform1中调用label1,在myForm2中调用label2,没关系,代码只调用changeLabel。

  1. 杂项

在您的示例中,您无法控制用户的操作,例如您不会检查用户是否单击了确定,或者是否通过取消按钮或单击窗口右上角的“X”取消。我认为这是因为您希望尽可能地保持示例的重点,但以防万一,不要忘记这样做。请注意,如果表单在 firstSub 中被销毁(例如,因为您将其设置为空,而不是在用户单击取消按钮或“X”时将其隐藏),则 otherSub 将出错。

【讨论】:

    【解决方案2】:

    您也可以使用CallByName 按名称获取表单对象。

    Function Form(Name As String) As Object
      Set Form = CallByName(UserForms, "Add", VbMethod, Name)
    End Function
    

    用法:(包括如何通过名称引用表单上的控件)

    Sub Test()
      With Form("UserForm1")
        .Caption = "This is the form title"
        .Controls("Label1").Caption = "Byebye"
        .Show vbModal ' or vbModeless
      End With
    End Sub
    

    【讨论】:

      猜你喜欢
      • 2017-05-20
      • 2015-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-09
      • 2022-11-21
      • 1970-01-01
      • 2013-08-26
      相关资源
      最近更新 更多