2014-01-27 57 views
5

创建可由应用程序的所有成员访问的Excel-VBA数据对象(字典,列表等)的最佳做法是什么?它应该被声明为一个单独的模块还是一个类模块?在Excel-VBA中创建公共对象的最佳实践?

例如,我想创建一个字典对象,其中不同的子例程将检查用户输入(如果它包含与否)。这个字典对象应该是它自己的模块,类模块,还是包含使用它的子例程的模块的一部分?

注:这个问题是Checking if a value is a member of a list

+2

“Dictionary”对象本身是Dictionary类的一个实例。因此,您将该实例设置为“公共”变量,以便在整个VBA项目中都可以访问该变量。创建一个覆盖'Dictionary'(*或Collection *)类的类是没有意义的,因为标准类所具有的方法和函数足以满足您的需求。用'Public'替换'Dim'并将声明粘贴到任何程序之外 – 2014-01-27 12:26:49

回答

7

您可以使用下面建造一个扩展(声明你myList对象作为Public在模块的顶部):

Public myList As Object 

Sub Main() 

    Call InitializeList 

    'Do something with your Dictionary object 

End Sub 

Sub InitializeList() 
    If Not myList Is Nothing Then Exit Sub 

    Set myList = CreateObject("Scripting.Dictionary") 

    myList.Add "item1", 1 
    myList.Add "item2", 2 
    myList.Add "item3", 3 
End Sub 
3

VBA可能是令人沮丧的人谁习惯于像Java和C#这样的好的面向对象的语言。我们需要接受VBA的限制,并尽我们所能提供最好的服务。

你所描述的几乎听起来像是你会声明为其他语言中的单例。

我的解决方案是创建一个“主”模块(不是Class模块)。在那里,创建一个私人字典,并为它创建一个Public访问器函数。这将允许您的其他方法 - 呃 - 函数/潜艇来盲目访问它。

Private pMyList as Scripting.Dictionary 

Public Property Get MyList() as Scripting.Dictionary 

    If pMyList = Nothing Then 
     Set pMyList = new Scripting.Dictionary 
     pMyList("One") = "Red" 
     pMyList("Two") = "Blue" 
     pMyList("Three") = "Green" 
    EndIf 

    Set MyList = pMyList 

End Property 

Public Sub Cleanup 
    Set pMyList = Nothing 
    ' To deallocate arrays, use: 
    ' Erase pArray 
End Sub 

'-------------------------------- 

Public Sub SomeRandomSubInAnotherModule() 

    Dim theList As Scripting.Dictionary 

    Set theList = MyList ' If not yet initialized, will initialize 
    ' Do whatever you need to do with theList 
    Set theList = Nothing ' Release the memory 

End Sub 

顺便说一句,“清理”子程序只是一个很好的做法。在宏的末尾,您应该调用“清理”子例程来释放Excel可能为已创建的任何对象分配的内存。对于类模块,你可以把你的清理代码放在

Public Sub Class_Terminate() 

它会被自动调用。

注 - 前面的代码需要添加“Microsoft Scripting Runtime”作为参考。当您在编码时使用字典时,这会为您提供有用的类型提示。如果你不想这样做,请使用以下代码:

Private pMyList as Object 

Public Property Get MyList() as Object 

    If pMyList = Nothing Then 
     Set pMyList = CreateObject("Scripting.Dictionary") 
     pMyList("One") = "Red" 
     pMyList("Two") = "Blue" 
     pMyList("Three") = "Green" 
    EndIf 

    Set MyList = pMyList 

End Property 

Public Sub Cleanup 
    Set pMyList = Nothing 
End Sub