全局变量自动重置

时间:2015-09-08 12:03:39

标签: excel vba excel-vba global-variables

我想将一个全局变量定义为打开文件的工作表,所以我使用了以下代码:

在Module1中:

Public mySheet As Worksheet

在ThisWorkbook中:

Sub Workbook_Open()  
    Set mySheet = Sheet1   
End Sub

然后我想在各种过程中使用mySheet来引用这个特定的工作表,其中一些过程会引用这个工作表并打开一个新文件。

最初有效 - 当我打开文件时,变量已设置,并且涉及mySheet.UnprotectmySheet.ProtectmySheet.Range("A1")的宏有效。但是,当我尝试再次运行时,我收到错误Object variable or With block variable not set,调试将我带到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

3 个答案:

答案 0 :(得分:6)

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

以下是我建议绕过这个问题。

在模块中创建过程。名字叫Init

Public mySheet As Worksheet

Sub Init()
   Set mySheet = Sheet1
End Sub

然后在Workbook_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

答案 1 :(得分:6)

我个人建议您创建一个返回该表的函数。然后你基本上可以使用函数名作为Worksheet变量。 (虽然如果你总是想要同一张纸,你可以使用Sheet1代号)

Function MySheet() As Excel.Worksheet
    Set MySheet = Sheet1
End Function

并使用,例如:

Sub foo()
    MsgBox MySheet.Name
End Sub

答案 2 :(得分:2)

请参阅here for a very similar post ...要重申所说的内容,此行为可能由以下原因引起:

  1. 使用“结束”(不是“结束子”,只是它自己的“End”声明。)
  2. 未处理的运行时错误(因此,如果您的任何代码抛出错误,则会丢失全局变量)
  3. 编辑代码(包括按停止按钮)
  4. 关闭包含VB项目的工作簿(您已经在评论部分中已经排除了这些内容)。
  5. 一种解决方案是使用子程序简化公共变量重新初始化。然后可以在单行的其他开头调用该子例程,或者根据需要从错误处理调用该子例程。不断重新初始化变量的不利之处在于它们在保存可变信息时失去了可靠性。