添加表单控件时,全局变量会莫名其妙地重置

时间:2018-05-09 17:59:41

标签: excel vba excel-vba

我有一个包含宏的MS Excel电子表格,并且多年来一直运行良好。我已经无数次地复制和修改了电子表格。直到今天。我制作了一份现有的,功能正常的文件的副本,并遇到了一个无法解释的问题:

电子表格包含一个收集某些数据的用户表单,其中一些数据来自框架中包含的选项按钮。收集的数据与全局变量进行比较,其全局变量的值在工作簿的Workbook_Open子例程中设置。对于现有的工作簿,我可以在没有问题的情况下尽可能地打败表单。在副本中,我向框架添加了一个选项按钮(它没有别的!),并且在单击表单的“提交”按钮时,全局变量的值将丢失。 (这不是选择新的选项按钮。)

此行为是可重复的,没有任何意义。任何人都可以建议为什么Excel表现得这么奇怪?注意 - 该文件没有任何外部引用。

更新:当任何新控件添加到表单时会发生此行为...

1 个答案:

答案 0 :(得分:4)

因为缺乏适当的背景而抓住吸管,但这是最可能出现的情况。

您可能会像这样分配全局变量:

Private Sub Workbook_Open()
    SomeGlobalVariable = 42
    AnotherGlobalVariable = "foo"
End Sub

将其拉出处理程序:

Private Sub Workbook_Open()
    AssignGlobalDefaults
End Sub

...让这个AssignGlobalDefaults程序存在于标准模块(.bas)中:

Option Explicit
Option Private Module
Public SomeGlobalVariable As Long
Public AnotherGlobalVariable As String

Public Sub AssignGlobalDefaults()
    SomeGlobalVariable = 42
    AnotherGlobalVariable = "foo"
End Sub

现在,当您对需要重新编译VBA代码的项目进行更改时,请在测试代码之前转到立即窗格(Ctrl + G)并键入AssignGlobalDefaults

保存,然后关闭。现在重新打开。还是坏了?毫无疑问。

全局变量存在于运行时上下文中。如果代码正在运行,那么它们就会活着。当你杀死那个上下文时,仍然可以访问全局变量,但是因为Workbook_Open是唯一分配它们的东西(对吗?)并且该处理程序只在运行工作簿时运行 ,那么这些价值就不会自动重新分配。

End关键字会杀死执行上下文 - 如果该关键字位于代码中的任何位置,则将其删除。在即时窗格中键入End也会这样做。

更改项目引用也会终止执行上下文。从项目中删除模块也是如此。

换句话说,您永远不能假设您可以对VBA项目进行更改并保留全局变量值。有时它有效,有时它不会,取决于你改变了什么以及它如何影响潜在的P代码。

解决方案是让一个程序负责初始化全局变量,并在需要初始化全局变量时调用它。