在Userform中定义要在模块中使用的变量

时间:2013-09-23 13:15:36

标签: excel-vba vba excel

我在这个论坛和其他人看到过类似的问题,在发布之前我尝试了所有我能想到的组合。我还引用了一些关于用户形式的教科书和更多技术网站,似乎无法做到正确。

我在用户表单中创建变量,然后在模块中引用。我已经尝试将它们标记为全局,在用户窗体和模块上,仅在用户窗体上,在模块上以及一些其他组合上定义它们但是没有正确。

这就是我现在所拥有的,而且我所读到的一切都应该是正确的:

*在Userform的声明部分:

 Dim ABC as Workbook
 Dim Primary as Workbook

*在Userform的命令按钮部分

For j = 0 To (ListBox1.ListCount - 1)
    If ListBox1.List(j) Like "ABC" Then
        Set ABC = Workbooks(ListBox1.List(j))
        ABC.Activate
        Exit For
    End If
Next

For i = 0 To (ListBox1.ListCount - 1)
    If ListBox1.List(i) Like "Aggregate" Then
        Set Primary = Workbooks(ListBox1.List(i))
        Primary.Activate
        Exit For
    End If
Next 

*这会继续增加一些变量,每个变量都以不同的字母编号。

在模块中,我有类似的东西:

        Primary.Sheets("Summary").Range("A5:H40").CopyPicture Appearance:=xlScreen, Format:=xlPicture

我的问题,如上所述,我如何定义这些工作簿(Primary,ABC等),以便我可以在我的模块中使用它们,就像上面的例子一样。

在我的模块中使用时,我可以写

Primary.Sheets(.......)....

或者我需要做工作簿(“小学”)。表格(....)....

也许我应该将Primary作为String Dim并以这种方式去做?

谢谢!

1 个答案:

答案 0 :(得分:2)

在顶部的常规模块中(选项明确下方,在第一个 Sub 之上),请注意以下几行

Public Primary As Workbook
Public ABC As Workbook

Sub Main()

    UserForm1.Show

    If Not ABC is Nothing Then
        ABC.Sheets(1).Range("A1") = "activated ABC workbooks sheet 1"
    End If

    If Not Primary Is Nothing Then
        Primary.Sheets(1).Range("B1") = "activated primary workbook sheet 1"
    End If
    Unload UserForm1

End Sub

Primary and ABC声明为 public workbook objects 可让您在VBA项目的任何位置访问它们。这意味着可以在 Modules, Classes, and Userforms 中访问它们。

如果要声明Public / Global变量,则必须始终使用常规Module对象而不是Userform对象。他们只能拥有私人领域。

现在,您的 Userform1

Private Sub CommandButton1_Click()

    Dim j As Long

    For j = 0 To (ListBox1.ListCount - 1)
        If ListBox1.List(j) Like "ABC" Then
            Set ABC = Workbooks(ListBox1.List(j))
            ABC.Activate
            Exit For
        End If
    Next

    For j = 0 To (ListBox1.ListCount - 1)
        If ListBox1.List(j) Like "Aggregate" Then
            Set Primary = Workbooks(ListBox1.List(j))
            Primary.Activate
            Exit For
        End If
    Next

End Sub

为了向您证明这一点,一旦您 Set ,您的ABCPrimary工作簿会添加Debug.Print ABC.Name行以打印出来名称。如果没有出现任何问题,请使用 CTRL + G 打开 Immediate Window ,您将看到打印出的工作簿名称。


另一种方法是通过字符串参数将工作簿名称发送到代码模块子。您必须在代码模块中创建一个Sub,将工作簿名称作为String参数。所以,仍然是你的*UserForm1 *

For j = 0 To (ListBox1.ListCount - 1)
    If ListBox1.List(j) Like "ABC" Then
        MySubInCodeModule Workbooks(ListBox1.List(j))
        Exit For
    End If
Next

然后在你的代码模块中

Sub MySubInCodeModule(wbName As String)

    Dim wb As Workbook
    Set wb = Workbooks(wbName)

    wb.Sheets(1).Range("A1") = "activate workbook: " & wb.Name
    wb.Sheets(1).Range("B1") = "active sheet: " & wb.ActiveSheet.Name

    'closing the active workbook
    wb.Close
    Set wb = Nothing
End Sub

我希望这是有道理的:)我甚至想不到另一种解释它的方式。