Excel 全局变量在不同子系统中不可访问?
我在模块1的顶部全局声明了projname。它在userform中分配,并在createWB子系统中成功访问。但是,当我在模块1的addWindow子系统中访问它时,它变为空(“”)。我不确定为什么会发生这种情况,因为我认为既然变量是全局声明的,我应该能够在任何子类中访问它 单元1Excel 全局变量在不同子系统中不可访问?,excel,vba,userform,Excel,Vba,Userform,我在模块1的顶部全局声明了projname。它在userform中分配,并在createWB子系统中成功访问。但是,当我在模块1的addWindow子系统中访问它时,它变为空(“”)。我不确定为什么会发生这种情况,因为我认为既然变量是全局声明的,我应该能够在任何子类中访问它 单元1 Option Explicit Public outputWorkbook As Workbook Public globalcounter As Integer Public projname As String
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
单元格
B3
和B4
分配了正确的值,但是addWindow()
行会导致下标超出范围错误。当我用Debug.Print
测试它时,我看到projname=”“。我还简单地尝试了outputWorkbook.Activate
,这也不起作用。您可以尝试使用Module1作为前缀吗,就像这个代码一样
Public Sub CommandButton1_Click()
Module1.projname = Me.TextBox1.Text
Module1.projnum = Me.TextBox2.Text
Me.Hide
End Sub
避免全球污染
除非有很好的理由使用它们,否则请尝试使用它们。我们希望避免污染全局名称空间行星船长警告过我们这一点
相反,尝试在需要时通过各种方法传递参数。这有助于防止错误,使代码更容易理解,并利用组合
使用用户表单存储和公开属性 尝试使用
With
语句实例化您的用户表单,这样您就有了它的一个捕获实例,您可以访问它公开的各种属性。在您的情况下,ProjectName
和ProjectNumber
此外,应该有一个属性来检查userform是否被取消或按下了X
按钮
您的userform将如下所示:
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
实例化用户表单 下面是现在调用您的userform的示例(请将名称从Userform2更改)。请注意,我们正在使用
With
块捕获您的userform实例。在此块中,我们可以访问我们公开的属性: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
现在可以从用户表单访问ProjectName
,并将其作为参数传递给addWindow
方法
Private Sub addWindow(ByVal projName As String)
Workbooks(Replace(projName, " ", "") + ".xlsx").Activate
End Sub
有关以这种方式使用userforms的更多信息,请参阅此帮助。听起来projname的作用域是模块1,而不是全局的-您能显示您的声明吗?我刚刚添加了它!
.SaveAs
方法能否重置全局变量?我认为最重要的是如何/在何处调用addWindow()
。如果您在整个过程之外调用它,那么projName
将是“
”。例如,如果在运行creatWB
时包含调用者,则将存储projName
,您将能够访问它。是的,问题存在,因为您似乎将它们作为独立进程调用。如果将calladdwindow
包含到createWb()
中,您将看到不会出现该错误,因为该信息是基于createWb()
例程存储的。否则它只是将默认状态返回为“”