问题
I started working in Excel with VBA and would like to save some kind of List.
My approach is the following, but I fear that I am looking into the totally wrong direction.
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
When trying to execute, I get a compile error: "Only user-defined types defined in public object modules can be coerced to or from a variant or passed to late-bound functions."
The goal would be to have a C# like List to which I can add MyType-objects and find them in a way you can do it in C#: ListVar.find(p => p.ID == 3). Also if doable, the list should be persistent in the file. This is not needed because I could simply write it into a worksheet when closing and vice versa when opening.
Is there maybe a different object class I can use that fits my needs better?
回答1:
You could use an array list? Within your Sub:
Dim arrayList As Object
Set arrayList = CreateObject("System.Collections.ArrayList")
You can then use all the usual methods of the .NET type ArrayList such as .Contains()
or .Sort()
etc...
Edit: (as OP is using Mac OS)
You can create a class yourself, and use this in the collection. Start by creating a new class module (Alt+I, then C)
Use the following in this module:
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
Important - name the module "MyType", this is the name you want to use in your code.
Back to your original sub in a normal code module:
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
Will work fine.
回答2:
Not sure if you can do this on a mac, but I used a class similar to this,
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
I used like so
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
来源:https://stackoverflow.com/questions/36151362/generic-list-of-structs-in-vba