VBA中公共variables的替代方法

我有几个模块引用的公共variables。 我知道如果你debugging或停止variables被清除。 我一直在写这些variables到一个电子表格,所以我有他们的情况下,他们被清除,但这是混乱。 我宁愿把它存储在代码中。 是否有任何替代公共variables永远不会被清除?

一个简单的解决scheme是将您的variables存储在registry中,并根据需要读取/写入它们。 这还具有在多个Excel会话中保存值的好处(甚至在计算机重新启动或崩溃之后 – 假设您的registry存活了!)。

编辑:也请参阅约翰·沃肯巴赫的书了解更多信息。

编辑:见下面的评论Ioannis的重要考虑。


锅盖警告: 这里是龙 ,Windows的registry,在你的危险Twiddle等等


上述警告尽pipe意识到几乎Windows计算机上的每个程序都与registry有关,但这样做并不是固有的危险。 只要确保您的代码只更改/删除由您的Excel应用程序创build的registry项。


使用Windows脚本的示例过程(我没有写这些;从快速search ):

从registry中读取:

 'reads the value for the registry key i_RegKey 'if the key cannot be found, the return value is "" Function RegKeyRead(i_RegKey As String) As String Dim myWS As Object On Error Resume Next 'access Windows scripting Set myWS = CreateObject("WScript.Shell") 'read key from registry RegKeyRead = myWS.RegRead(i_RegKey) End Function 

检查是否存在registry项:

 'returns True if the registry key i_RegKey was found 'and False if not Function RegKeyExists(i_RegKey As String) As Boolean Dim myWS As Object On Error GoTo ErrorHandler 'access Windows scripting Set myWS = CreateObject("WScript.Shell") 'try to read the registry key myWS.RegRead i_RegKey 'key was found RegKeyExists = True Exit Function ErrorHandler: 'key was not found RegKeyExists = False End Function 

保存registry项:

 'sets the registry key i_RegKey to the 'value i_Value with type i_Type 'if i_Type is omitted, the value will be saved as string 'if i_RegKey wasn't found, a new registry key will be created Sub RegKeySave(i_RegKey As String, _ i_Value As String, _ Optional i_Type As String = "REG_SZ") Dim myWS As Object 'access Windows scripting Set myWS = CreateObject("WScript.Shell") 'write registry key myWS.RegWrite i_RegKey, i_Value, i_Type End Sub 

从registry中删除一个密钥:

 'deletes i_RegKey from the registry 'returns True if the deletion was successful, 'and False if not (the key couldn't be found) Function RegKeyDelete(i_RegKey As String) As Boolean Dim myWS As Object On Error GoTo ErrorHandler 'access Windows scripting Set myWS = CreateObject("WScript.Shell") 'delete registry key myWS.RegDelete i_RegKey 'deletion was successful RegKeyDelete = True Exit Function ErrorHandler: 'deletion wasn't successful RegKeyDelete = False End Function 

下面是CustomDocumentProperties的一个例子,我最近开始使用它来存储一些元信息(比处理CustomXMLParts更容易)。

下面的例子只存储string数据,但你也可以使用date,数字和是/否(你可以把它作为布尔值)。 string数据限制为255个字符。

  Sub Test() '## Assign a CDP SetCustomProperty "myProperty", "some value I want to store" End Sub 

您可以从Backstage |查看CPD 信息| 属性| 高级属性| 自定义:

在这里输入图像说明

如果您运行完了,您可以从CDP恢复值,您可以通过以下方式查询属性值:

myVar = ActiveWorkbook.CustomDocumentProperties("myProperty").Value

您可以使用像这样的函数来设置CustomDocumentProperties集合中的属性:

 Sub SetCustomProperty(property$, val$) Dim cdp As Variant Dim hasProperty As Boolean If HasCustomProperty(property) Then ActiveWorkbook.CustomDocumentProperties(property).Value = val Else ActiveWorkbook.CustomDocumentProperties.Add property, False, msoPropertyTypeString, val End If End Sub Private Function HasCustomProperty(property$) As Boolean Dim cdp As Variant Dim boo As Boolean For Each cdp In ActiveWorkbook.CustomDocumentProperties If cdp.name = property Then boo = True Exit For End If Next HasCustomProperty = boo End Function 

公共variables在debugging(中断)模式下不会从内存中被清除,如果在代码中仍有引用指向它们的话。 事实上,在某些情况下,如果将鼠标移动到variables上,它会告诉你中断处的值。

如果你希望variables持续存在,我将使用与你当前使用的方法相同的方法(将它们写在Excel工作表上)或数据库中。

如果你写下这些variables,我build议你不要直接修改variables,而是使用适合你的模型的setter和getters。 例如,如果您将其写入工作表,则可以使用以下内容:

 public sub setVariable(v as String) worksheets("Sheet1").Range("A1").value = v end sub public function getVariable() as String getVariable = worksheets("Sheet1").range("A1").value End Function 

这是另一个解决scheme,可能比我的第一个答案更好(使用registry)取决于用例。

您可以将值存储在“非常隐藏”工作表中 。 这具有以下优点:

  1. 防止variables意外被破坏(它们对用户是完全不可见的)
  2. 允许工作簿的多个副本拥有自己的variables版本,而不是从registry中访问相同值的所有实例
  3. 防止工作簿的多个实例尝试同时编辑registry项
  4. 允许工作簿在多台机器上使用并通过电子邮件等方式保持其值

TempVars集合是公共variables的一个很好的select。 会话之间不会持续,但持续整个A会话。

您将需要添加对Microsoft Access 14.0对象库的引用。 TempVars仅在2007年以后提供。