简体   繁体   English

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

[英]Global variable not accessible in different sub?

I declared projname globally at the top of the module 1. It is assigned in the userform, and is successfully accessed in the createWB sub. 我在模块1的顶部全局声明了projname。它在用户窗体中分配,并在createWB子目录中成功访问。 However, when I go to access it in the addWindow sub also in module 1, it becomes empty (""). 但是,当我也在模块1的addWindow子目录中访问它时,它变为空(“”)。 I'm unsure of why this is happening because I thought that since the variable was globally declared I should be able to access it in any sub. 我不确定为什么会这样,因为我认为既然变量是全局声明的,那么我应该可以在任何子目录中访问它。

Module 1 模块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

Userform Code 用户表单代码

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

Cells B3 and B4 are assigned the correct value, but the addWindow() line causes a subscript out of range error. 单元格B3B4被分配了正确的值,但是addWindow()行导致下标超出范围错误。 When I test it with Debug.Print , I see that projname = "". 当我使用Debug.Print测试它时,我看到projname =“”。 I also simply tried outputWorkbook.Activate , which did not work either. 我也只是尝试了outputWorkbook.Activate ,它也不起作用。

Avoid Global Pollution 避免全球污染

Unless there is a really good reason to use them, try to avoid global variables . 除非有很好的理由使用它们,否则请尽量避免使用全局变量 We want to avoid polluting the global namespace. 我们要避免污染全局名称空间。 Captain Planet warned us of that . 星球队长警告我们

船长星球

Instead, try passing your parameters through your various methods as they are needed. 而是尝试根据需要通过各种方法传递参数。 This helps prevent errors, makes your code easier to follow, and utilizes composition. 这有助于防止错误,使代码更易于遵循,并利用组合。


Using your userform to store and expose your properties 使用用户表单存储和公开您的属性

Try to instantiate your userform using a With statement so that you have a captured instance of it where you have access to its various properties that you expose. 尝试使用With语句实例化您的用户窗体,以便您拥有它的捕获实例,您可以在其中访问所公开的各种属性。 In your case ProjectName and ProjectNumber . 在您的情况下ProjectNameProjectNumber

Additionally, there should be a property to check if the userform was canceled or the X button was pressed. 另外,应该有一个属性来检查用户表单是否被取消或按下X按钮。

You userform would look something like this: 您的用户表单如下所示:

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

Instantiating the userform 实例化用户表单

Here is the example of now calling your userform ( PS Change the name from Userform2 ). 这是现在调用用户表单的示例( PS从Userform2更改名称 )。 Notice we are capturing our instance of your userform using the With block. 注意,我们正在使用With块来捕获您的用户表单实例。 Within this block, we have access to the properties we exposed: ProjectName , ProjectNumber , IsCancelled . 在此块中,我们可以访问我们公开的属性: 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

The ProjectName now can be accessed from your userform and passed as a parameter to you addWindow method. 现在可以从用户窗体访问ProjectName并将其作为参数传递给addWindow方法。

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

For more information on using userforms in this way see this helpful Rubberduck Blog Post . 有关以这种方式使用用户窗体的更多信息,请参阅此有用的Rubberduck博客文章

could you try using Module1 as prefix? 您可以尝试使用Module1作为前缀吗? , jus like in this code ,就像这样的代码

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在For Loop中使变量全局化或在子或另一个子/表单中可访问? - How to make variable inside a For Loop global or accessible within sub or another sub/form? VBA:全局变量在“Workbook_Open”子后清除 - VBA: Global Variable Cleared after 'Workbook_Open' sub 从其他子变量返回变量不会保留值 - Returning a variable from a different sub does not retain value 公共/全局变量从两个不同的用户窗体发送值 - Public/Global Variable to send a value from two different UserForms 将工作表命名为取自不同工作簿的全局字符串变量 - Naming a sheet a global string variable taken from a different workbook 如何使用VBA在其他工作簿中使用Userform全局变量值 - How to use the Userform Global Variable value in different Workbook using VBA 子程序完成后,Excel VBA全局范围变量超出范围 - Excel VBA Global Range variable out of scope after sub procedure completes 可从用户表单访问的全局字典对象 - Global Dictionary Object Accessible from a Userform 双击复制变量行并在不同工作表上填写表单的私有子项 - Private sub that copies variable row on double click and fills in form on different worksheet 在另一个模块中声明一个子模块/功能,该模块可由其他模块访问,但用户不可访问 - Declaring a Sub/Function in another module accessible by other modules but not by user
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM