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

Evi*_*ine 7 excel vba excel-vba data-structures

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

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

注意:此问题是检查值是否为列表成员的扩展

Dmi*_*liv 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
Run Code Online (Sandbox Code Playgroud)


liv*_*e75 5

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

您所描述的内容几乎听起来就像您在其他语言中声称为Singleton一样.

我的解决方案是创建一个"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
Run Code Online (Sandbox Code Playgroud)

顺便说一下,"清理"子程序只是一种很好的做法.在宏的末尾,您应该调用"清理"子例程来释放Excel可能为您创建的任何对象分配的内存.对于类模块,您可以将清理代码放入

Public Sub Class_Terminate()
Run Code Online (Sandbox Code Playgroud)

它将被自动调用.

注意 - 以前的代码需要您添加"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
Run Code Online (Sandbox Code Playgroud)