如何在 Excel VBA 中声明全局变量在工作簿中可见

Posted

技术标签:

【中文标题】如何在 Excel VBA 中声明全局变量在工作簿中可见【英文标题】:How to declare Global Variables in Excel VBA to be visible across the Workbook 【发布时间】:2015-02-19 00:05:39 【问题描述】:

我有一个关于全局范围的问题,并将问题抽象为一个简单的示例:

在 Excel 工作簿中: 在 Sheet1 中,我有两 (2) 个按钮。 第一个标记为 SetMe,并链接到 Sheet1 的模块中的子例程:Sheet1 代码:

Option Explicit
Sub setMe()
    Global1 = "Hello"
End Sub

第二个标记为 ShowMe,并链接到 ThisWorkbook 的模块中的子例程:ThisWorkbook 代码:

Option Explicit
Public Global1 As String
Debug.Print("Hello")
Sub showMe()
    Debug.Print (Global1)
End Sub

单击 SetMe 会生成一个编译器 error: variable not defined。 当我创建一个单独的模块并将 Global1 的声明移入其中时,一切正常。

所以我的问题是: 我读过的所有内容都表明,在模块顶部声明的全局变量在任何代码之外都应该对项目中的所有模块可见。显然情况并非如此。 除非我对Module的理解不正确。 工作簿附带的对象Sheet1Sheet2ThisWorkbook...:这些不是能够在全局范围内声明变量的模块吗?

或者是唯一可以在 Modules 类型的单独模块中声明全局的地方。

【问题讨论】:

我相信 UserForms 的代码属于模块类型,尽管它并没有真正列出。对吗? @sancho.s 我删除了它以避免混淆 :) 我错过了 Pearson 的链接并误解了我发布的 MSDN 链接中的一行。今天学到了新东西:) 您在这里找到任何有用的答案了吗?提供反馈总是好的,所以其他 SO 用户可以看到。 【参考方案1】:

您的问题是: 这些模块不能在全局范围内声明变量吗?

回答:是的,他们“有能力”

唯一的一点是在ThisWorkbook 或工作表模块中对全局变量的引用必须是完全限定的(例如,称为ThisWorkbook.Global1) 标准模块中对全局变量的引用只有在有歧义的情况下才需要完全限定(例如,如果有多个标准模块定义了一个名为Global1 的变量,并且您的意思是在第三个模块中使用它)。

例如,放入Sheet1代码

Public glob_sh1 As String

Sub test_sh1()
    Debug.Print (glob_mod)
    Debug.Print (ThisWorkbook.glob_this)
    Debug.Print (Sheet1.glob_sh1)
End Sub

放入ThisWorkbook代码

Public glob_this As String

Sub test_this()
    Debug.Print (glob_mod)
    Debug.Print (ThisWorkbook.glob_this)
    Debug.Print (Sheet1.glob_sh1)
End Sub

在标准模块代码中

Public glob_mod As String

Sub test_mod()
    glob_mod = "glob_mod"
    ThisWorkbook.glob_this = "glob_this"
    Sheet1.glob_sh1 = "glob_sh1"
    Debug.Print (glob_mod)
    Debug.Print (ThisWorkbook.glob_this)
    Debug.Print (Sheet1.glob_sh1)
End Sub

所有三个子都工作正常。

PS1:这个答案基本上基于来自here 的信息。非常值得一读(来自伟大的 Chip Pearson)。

PS2:你的Debug.Print ("Hello") 行会给你编译错误Invalid outside procedure

PS3:您可以(部分)在 VB 编辑器中使用 Debug -> Compile VBAProject 检查您的代码。所有编译错误都会弹出。

PS4:也请查看Put Excel-VBA code in module or sheet?。

PS5:您可能无法在 Sheet1 中声明全局变量,并在其他工作簿的代码中使用它(阅读 http://msdn.microsoft.com/en-us/library/office/gg264241%28v=office.15%29.aspx#sectionSection0; 我没有测试这一点,所以这个问题尚未解决如此确认)。但无论如何,您的示例并不是要这样做。

PS6:在不完全限定全局变量的情况下,有几种情况会导致歧义。你可能会稍微修补一下才能找到它们。它们是编译错误。

【讨论】:

我误解了我发布的链接中的一行。今天学到了一些新东西:)。绝对+1。如果我可以投票不止一次,我会这样做的。 这让我发疯 - 将 Public thing as New Thing 添加到模块而不是 ThisWorkbook 解决了尝试访问 thing.something() 时出现的所有“424”错误问题【参考方案2】:

您可以执行以下操作来学习/测试该概念:

    打开新的 Excel 工作簿并在 Excel VBA 编辑器中右键单击 Modules->Insert->Module

    在新添加的Module1中添加声明; Public Global1 As String

    在Worksheet VBA Module Sheet1(Sheet1)中放入代码sn -p:

Sub setMe()
      Global1 = "Hello"
End Sub
    在Worksheet VBA Module Sheet2(Sheet2)中输入代码sn-p:
Sub showMe()
    Debug.Print (Global1)
End Sub
    依次运行 Sub setMe() 然后 Sub showMe() 以测试 var Global1 的全局可见性/可访问性

希望这会有所帮助。

【讨论】:

简单,谢谢,对我有用。我将一个模块命名为“Globals”,除了定义全局变量之外别无他用——其中没有子函数或函数或任何代码,只是定义了全局变量 不客气!很高兴它对你有用。如果您对解决方案感到满意,请将答案标记为已接受。最好的问候,

以上是关于如何在 Excel VBA 中声明全局变量在工作簿中可见的主要内容,如果未能解决你的问题,请参考以下文章

如何在 VBA 中调暗和设置变量工作簿名称?

将工作簿声明为全局变量

使用循环打开文件路径中的所有excel文件后,有没有办法通过vba创建工作簿变量来引用这些文件?

如何使用vba在excel2010中将保存类型从excel工作簿更改为excel 97-2003?

excel里面我想 用VBA实现调用另一个工作簿中的数据怎么解决

excel如何用vba批量提取指定工作表?