无法在其他子目录中访问全局变量?

时间:2019-07-23 12:53:16

标签: excel vba userform

我在模块1的顶部全局声明了projname。它在用户窗体中分配,并在createWB子目录中成功访问。但是,当我也在模块1的addWindow子目录中访问它时,它变为空(“”)。我不确定为什么会这样,因为我认为既然变量是全局声明的,那么我应该可以在任何子目录中访问它。

模块1

Option Explicit

Public outputWorkbook As Workbook
Public globalcounter As Integer
Public projname As String
Public projnum As String

createWB()
    Dim uf2 As New UserForm2
    uf2.Show

    Set outputWorkbook = Workbooks.Add(xlWBATWorksheet)
    outputWorkbook.SaveAs Filename:=Environ("userprofile") & "\Desktop\" & 
    Replace(projname, " ", "") & ".xlsx"

    outputWorkbook.Activate

    Range("B3") = projname
    Range("B4") = projnum
End Sub

addWindow()
    Workbooks(Replace(projname, " ", "") + ".xlsx").Activate
End Sub

用户代码

Public Sub CommandButton1_Click()
    projname = Me.TextBox1.Text
    projnum = Me.TextBox2.Text
    Me.Hide
End Sub

为单元格B3B4分配了正确的值,但是addWindow()行导致下标超出范围错误。当我用Debug.Print测试时,我看到projname =“”。我也只是尝试了outputWorkbook.Activate,它也没有用。

2 个答案:

答案 0 :(得分:1)

避免全球污染

除非有充分的理由使用它们,否则请尝试avoid global variables。我们要避免污染全局名称空间。 星球队长警告过我们

Captain planet

相反,请根据需要尝试通过各种方法传递参数。这有助于防止错误,使代码更易于遵循,并利用组合。


使用用户窗体存储和公开您的属性

尝试使用With语句实例化您的用户窗体,以便您拥有它的捕获实例,您可以在其中访问所公开的各种属性。就您而言,ProjectNameProjectNumber

此外,还应该有一个属性来检查是否取消了用户窗体或按下了X按钮。

您的用户表单应如下所示:

Option Explicit

Private cancelled As Boolean

Public Property Get ProjectName() As String
    ProjectName = TextBox1.Value
End Property

Public Property Get ProjectNumber() As Long
    ProjectNumber = TextBox2.Value
End Property

Public Property Get IsCancelled() As Boolean
    IsCancelled = cancelled
End Property

Private Sub CommandButton1_Click()
    Me.Hide
End Sub

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    If CloseMode = VbQueryClose.vbFormControlMenu Then
        Cancel = True
        OnCancel
    End If
End Sub

Private Sub OnCancel()
    cancelled = True
    Hide
End Sub

实例化用户表单

这里是现在调用用户表单的示例( P.S。从Userform2更改名称)。注意,我们正在使用With块捕获您的用户表单实例。在此块中,我们可以访问我们公开的属性:ProjectNameProjectNumberIsCancelled

Private Sub createWB()
    With New UserForm2
        .Show
        If Not .IsCancelled Then
            ' Do neccessaray steps here...

            ' You have access to ProjectName and Project number.
            ' Pass this to your addWindow method.
            addWindow .ProjectName

        End If
    End With
End Sub

ProjectName现在可以从您的用户表单中访问,并作为参数传递给您的addWindow方法。

Private Sub addWindow(ByVal projName As String)
    Workbooks(Replace(projName, " ", "") + ".xlsx").Activate
End Sub

有关以这种方式使用用户表单的更多信息,请参见此有用的Rubberduck Blog Post

答案 1 :(得分:0)

您可以尝试使用Module1作为前缀吗? ,就像这样的代码

 Public Sub CommandButton1_Click()
        Module1.projname = Me.TextBox1.Text
        Module1.projnum = Me.TextBox2.Text
        Me.Hide
    End Sub