在Excel-VBA中创建公共对象的最佳实践?

时间:2014-01-27 12:19:50

标签: vba excel-vba data-structures excel

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

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

注意:此问题是Checking if a value is a member of a list

的扩展

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:5)

对于那些习惯于使用友好的OOP友好语言(如Java和C#)的人来说,VBA会让人感到沮丧。我们需要接受VBA的限制,并尽可能地利用它所提供的功能。

你所描述的几乎听起来就像你在其他语言中宣称为单身人士一样。

我的解决方案是创建一个“Main”模块(不是Class模块)。在那里,创建一个私有字典,并为它创建一个公共访问器功能。这将允许您的其他方法 - er - functions / subs盲目访问它。

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