VBA中结构的通用列表

时间:2016-03-22 10:05:08

标签: excel vba excel-vba generic-list

我开始使用VBA在Excel中工作,并希望保存某种List。

我的方法如下,但我担心我正在寻找完全错误的方向。

Public Type MyType
  ID As Integer
  Name As String
  MyInt As Integer
End Type

Public ListVar As New Collection

Public Sub MySub
  Dim MyVar As MyType
  MyVar.ID = 1
  MyVar.Name = "name"
  MyVar.MyInt = 2000

  ListVar.Add MyVar, MyVar.ID
End Sub

当尝试执行时,我收到编译错误:"只有公共对象模块中定义的用户定义类型才能被强制转换为变量或从变量强制转移或传递给后期绑定函数。"

我们的目标是拥有一个类似C#的List,我可以添加MyType对象并以C#中的方式找到它们:ListVar.find(p => p.ID == 3)。 此外,如果可行,列表应该在文件中持久化。这不是必需的,因为我可以在关闭时将其写入工作表,反之亦然。

是否可以使用更符合我需求的不同对象类?

2 个答案:

答案 0 :(得分:3)

您可以使用数组列表吗?在您的Sub:

Dim arrayList As Object
Set arrayList = CreateObject("System.Collections.ArrayList")

然后,您可以使用.NET类型ArrayList的所有常用方法,例如.Contains().Sort()等...

编辑: (因为OP使用的是Mac OS)

您可以自己创建一个类,并在集合中使用它。首先创建一个新的类模块( Alt + I ,然后 C

在此模块中使用以下内容:

Private sID     As Integer
Private sName   As String
Private sInt    As Integer

Public Property Let ID(value As Integer)
    sID = value
End Property

Public Property Get ID() As Integer
    ID = sID
End Property

Public Property Let Name(value As String)
    sName = value
End Property

Public Property Get Name() As String
    Name = sName
End Property

Public Property Let MyInt(value As Integer)
    sInt = value
End Property

Public Property Get MyInt() As Integer
    MyInt = sInt
End Property

重要 - 将模块命名为“MyType”,这是您要在代码中使用的名称。

返回普通代码模块中的原始子

Public ListVar As New Collection

Public Sub MySub()

  Dim MyVar As New MyType
  MyVar.ID = 1
  MyVar.Name = "name"
  MyVar.MyInt = 2000

  ListVar.Add MyVar, CStr(MyVar.ID)

End Sub

工作正常。

答案 1 :(得分:1)

不确定你是否可以在Mac上执行此操作,但我使用了与此类似的类

Option Explicit

Implements Scripting.Dictionary

Private dic As Scripting.Dictionary

Private Sub Class_Initialize()
    Set dic = New Scripting.Dictionary
End Sub

Public Sub Add(Key As Variant, Item As Variant)
    dictionary_Add Key, Item
End Sub
Private Sub dictionary_Add(Key As Variant, Item As Variant)
    dic.Add Key, Item
End Sub
Public Sub Remove(Key As Variant)
    dictionary_Remove (Key)
End Sub
Private Sub dictionary_Remove(Key As Variant)
    dic.Remove (Key)
End Sub

Public Function TEST_LAMBDA(strLAMBDA As String) As Scripting.Dictionary

    Dim strSplit() As String
    Dim strCriteria As String

    Set TEST_LAMBDA = New Scripting.Dictionary

    strSplit = Split(strLAMBDA, "=>")
    strCriteria = strSplit(1)

    Dim intCounter As Integer
    strSplit = Split(strCriteria, "=")
    strCriteria = strSplit(1)

    For intCounter = 0 To dic.Count - 1
        If dic.Keys()(intCounter) = strCriteria Then
            TEST_LAMBDA.Add dic.Keys()(intCounter), dic.Items()(intCounter)
        End If
    Next intCounter

End Function
Private Property Get dictionary_CompareMode() As Scripting.CompareMethod
End Property
Private Property Let dictionary_CompareMode(ByVal RHS As Scripting.CompareMethod)
End Property
Private Property Get dictionary_Count() As Long
End Property
Private Function dictionary_Exists(Key As Variant) As Boolean
End Function
Private Property Get dictionary_HashVal(Key As Variant) As Variant
End Property
Private Property Get dictionary_Item(Key As Variant) As Variant
End Property
Private Property Let dictionary_Item(Key As Variant, RHS As Variant)
End Property
Private Property Set dictionary_Item(Key As Variant, RHS As Variant)
End Property
Private Function dictionary_Items() As Variant
End Function
Private Property Let dictionary_Key(Key As Variant, RHS As Variant)
End Property
Private Function dictionary_Keys() As Variant
End Function
Private Sub dictionary_RemoveAll()
End Sub

我喜欢这样使用

Sub t()

Dim a As New clsDictionary

a.Add "9", "this out"
a.Add "10", "test"

Dim d As Scripting.Dictionary

Set d = a.TEST_LAMBDA("x=>x=9")

End Sub