[英]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. 单元格B3
和B4
被分配了正确的值,但是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
,它也不起作用。
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. 这有助于防止错误,使代码更易于遵循,并利用组合。
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
. 在您的情况下ProjectName
和ProjectNumber
。
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
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
. 在此块中,我们可以访问我们公开的属性: ProjectName
, ProjectNumber
, IsCancelled
。
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.