如何防止在Word文档中共享VBA变量?

时间:2012-01-26 06:07:45

标签: vba ms-word scope word-vba

我有一个VBA模板项目,它在打开Word文档时自动运行。但是,如果我打开多个文档,它们都共享变量值。如何声明这些变量只与活动窗口或活动文档相关联?

我尝试在类模块中声明它们,但这没有帮助。在打开的文档之间切换我可以看到这些变量是共享的。

赞赏任何意见......

这就是我的模块中的内容:

Option Private Module
  Dim CurrentCommand As String

  Public Function SetCurrentCommand(command)
    CurrentCommand = command
  End Function

  Public Function GetCurrentCommand()
    GetCurrentCommand = CurrentCommand
  End Function

更多信息:代码/宏从AutoExec开始,如下所示:

Public Sub Main()      
  Set oAppClass.oApp = Word.Application
  If PollingRate <> "" Then Application.OnTime Now + TimeValue(PollingRate), "CaptureUserViewState"
End Sub

CaptureUserViewState是一个Sub,它驻留在一个不同的模块中并执行所有teh检查(将新值与最后记录的值进行比较)以及此Sub如何进行检查:

If WL_GetterAndSetter.GetLastPageVerticalPercentage <> pageVerticalPercentScrolled Then
  'Update the last value variable
   WL_GetterAndSetter.SetLastPageVerticalPercentage (pageVerticalPercentScrolled)
  'log change
End If

3 个答案:

答案 0 :(得分:3)

您没有向我们提供太多信息,但我假设您在模块级别声明了公共变量,如下所示:

Public myString As String
Public myDouble As Double

来自VBA文档:

  

使用Public语句声明的变量可用于所有应用程序中所有模块中的所有过程,除非Option Private Module生效;在这种情况下,变量仅在它们所在的项目中是公共的。

答案是使用Option Private Module

  

在允许跨多个项目引用的主机应用程序中使用时,Option Private Module会阻止在其项目之外引用模块的内容。

     

[...]如果使用,Option Private语句必须在任何程序之前出现在模块级别。

编辑您现在已澄清您在模块级别使用Dim声明变量。在这种情况下,Option Private Module无关紧要。

  

模块级别用Dim声明的变量可供模块中的所有过程使用。

即。无论您是否使用Option Private Module

如果您发现在运行之间保留了值,则必须是因为您正在从同一工作簿中的同一模块运行过程。你可能认为自己在做别的事情,但实际上这就是你正在做的事情。

修改

在您的课程模块中,而不是Dim CurrentCommand As String尝试Private CurrentCommand As String。没有更多信息,很难调试您的程序。我只是在这里随机拍摄。

答案 1 :(得分:0)

您需要做的是存储多个版本的变量,每个文档一个。 所以我建议你创建一个简单的类来保存不同的值。 然后,将它们存储在一个集合中,该集合将数据集映射为文档名称或类似的密钥。

在classmodule(MyData)中,标记为public:

Public data1 as String
Public data2 as Integer

在包含事件处理程序的模块中:

Dim c as new Collection 'module global declaration

Sub AddData()
  Dim d as new MyData 'Your data set
  d.data1 = "Some value"
  d.data2 = 42
  c.add Value:=d, Key:=ActiveDocument.name
End Sub

然后,当您输入事件处理程序时,您将检索数据并使用当前活动文档的特定集。

Sub EventHandler()
  Dim d as MyData
  set d = c.item(ActiveDocument.name)
  'use data
  'd.data1...
End Sub

请注意,此代码只是概念级别的代码。它不起作用,你必须将它应用到你的问题,但它应该让你知道你需要做什么。你需要添加很多错误处理,检查项目是否已经在集合中,等等,但我希望你理解这个概念继续自己尝试。

原因是,正如我从您的问题中了解情况,您只运行了一个版本的脚本,但只有多个文档。因此,脚本必须知道所有不同的文档。

另一方面,如果每个文档都有自己的代码/事件处理程序,因此运行了多个版本的脚本,那么您不需要上面提供的解决方案。相反,您需要小心在脚本中引用的文档实例。通过始终使用“ThisDocument”而不是“ActiveDocument”,如果将代码放在每个打开的文档中,您就可以实现隔离。

但是,据我了解,您只运行一个版本的脚本,与打开的文档分开,因此第一个解决方案适用。

祝你好运!

答案 2 :(得分:0)

您可能希望使用存储特定于文档的详细信息 Document.CustomDocumentProperties属性 http://msdn.microsoft.com/en-us/library/office/aa212718(v=office.11).aspx

这会返回一个 DocumentProperties集合 您可以在其中添加新属性

Document.CustomDocumentProperties.Add(PropertyName, LinkToContent, Value, Type)

然后阅读使用

Document.CustomDocumentProperties.Item(PropertyName)

缺点或奖励是,除非您删除属性,否则属性将保留在文档中。

这可能是好事还是坏事