Vba 全局变量自动重置

Vba 全局变量自动重置,vba,excel,global-variables,Vba,Excel,Global Variables,我想在打开文件时将全局变量定义为工作表,因此我使用了以下代码: 在模块1中: Public mySheet As Worksheet 在此工作簿中: Sub Workbook_Open() Set mySheet = Sheet1 End Sub 然后,我想使用mySheet在各个过程中引用此特定工作表,其中一些过程会在打开新文件后引用此工作表 它最初起作用-当我打开文件时,变量被设置,一个涉及mySheet.Unprotect、mySheet.Protect和myShee

我想在打开文件时将全局变量定义为工作表,因此我使用了以下代码:

在模块1中:

Public mySheet As Worksheet
在此工作簿中:

Sub Workbook_Open()  
    Set mySheet = Sheet1   
End Sub
然后,我想使用
mySheet
在各个过程中引用此特定工作表,其中一些过程会在打开新文件后引用此工作表

它最初起作用-当我打开文件时,变量被设置,一个涉及
mySheet.Unprotect
mySheet.Protect
mySheet.Range(“A1”)
的宏起作用。但是,当我再次尝试运行它时,我得到一个错误
对象变量或未设置块变量
,调试将我带到
mySheet.Unprotect
行,这是第一次引用工作表

如何在全局变量中定义此工作表,以使定义保持不变

作为参考,我所指的特定宏如下所示,尽管我对不同的代码位也有类似的问题:

Sub mySub()
    mySheet.Unprotect 
    With Application.FileDialog(msoFileDialogOpen)  
        .AllowMultiSelect = False           
        If .Show <> 0 Then
            mySheet.Range("A1") = .SelectedItems(1)
        End If           
    End With

    mySheet.Protect        
End Sub
Sub mySub()
mySheet.Unprotect
使用Application.FileDialog(msoFileDialogOpen)
.AllowMultiSelect=False
如果。那么显示0
mySheet.Range(“A1”)=选择编辑项(1)
如果结束
以
我的纸,保护我
端接头
请参见。。。重申一下,这种行为可能是由以下原因造成的:

  • 使用“End”(而不是“End Sub”,仅使用“”语句本身)
  • 未处理的运行时错误(因此,如果您的任何代码抛出错误,您将丢失全局变量)
  • 编辑代码(包括按下停止按钮)
  • 关闭包含VB项目的工作簿(您已经在评论部分排除了这一点)

  • 一种解决方案是使用一个子例程简化公共变量的重新初始化。然后,可以在单行中其他子例程的开头调用该子例程,或者根据需要从错误处理调用该子例程。不断重新初始化变量的不利之处在于,它们失去了保存可变信息的可靠性。

    如其他答案中的链接所述,您可以理解为什么会发生这种情况

    下面是我建议绕过这个问题的方法

    在模块中创建一个过程。把它命名为,
    Init

    Public mySheet As Worksheet
    
    Sub Init()
       Set mySheet = Sheet1
    End Sub
    
    然后在
    工作簿中\u Open()
    执行此操作

    Sub Workbook_Open()
        Init
    End Sub
    
    现在,无论您在何处使用该对象,只需再添加一行即可

    Sub mySub()
        If mySheet is Nothing then Call Init '<== Add this
    
        mySheet.Unprotect
    
        With Application.FileDialog(msoFileDialogOpen)
            .AllowMultiSelect = False
            If .Show <> 0 Then
                mySheet.Range("A1") = .SelectedItems(1)
            End If
        End With
        mySheet.Protect
    End Sub
    
    Sub mySub()
    
    如果mySheet什么都不是,那么亲自调用Init',我建议您创建一个返回该工作表的函数。然后基本上可以将函数名用作工作表变量。(尽管如果您总是想要相同的工作表,您可以使用
    Sheet1
    codename)

    并使用,例如:

    Sub foo()
        MsgBox MySheet.Name
    End Sub
    

    sheet1
    mysheet
    定义为
    constant
    ,这样行吗?@emptionalebola VBA不支持对象常量,它们必须在过程内部初始化。请使用局部变量窗口尝试您的代码,以查看变量发生了什么情况。它第一次运行的事实告诉我程序有问题-不是您分配变量的方式。@aprados
    Global
    关键字只允许通过引用另一个项目的项目来访问变量-出于这个问题的目的,
    Public
    Global
    将执行相同的操作。“其中一些操作会在打开新文件后引用此工作表。”-这是否意味着关闭设置变量的工作簿?这将导致代码失败,因为工作表对象不再存在。这应该是注释。你的贡献是什么?你只是简单地传递了链接,从那里复制了信息并对其进行了总结!不,这不应该是评论,因为它回答了为什么会发生这种情况的问题。你不想在评论中隐藏答案。我可以自己独立验证这个答案,并选择包含一个链接来证实它。这不仅仅是一个复制和粘贴,信息已经被添加并根据OP手头的问题进行评估。我假设在给出这些信息的情况下,创建一个单独的变量重新初始化子例程的解决方案是显而易见的。您最近的编辑现在更有意义了。我们扭转了反对票:)嗯,1,3和4绝对不是问题的根源。第二个可能是——我不知道全局变量在错误中丢失了。我会看一看,看看是否有什么东西可能会触发这一点
    Sub foo()
        MsgBox MySheet.Name
    End Sub