VBA 中的通用结构列表
Generic List of Structs in VBA
我开始在 Excel 和 VBA 一起工作,想保存一些列表。
我的方法如下,但我担心我正在寻找完全错误的方向。
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
尝试执行时,出现编译错误:"Only user-defined types defined in public object modules can be coerced to or from a variant or passed to late-bound functions."
目标是拥有一个类似于 C# 的列表,我可以向其中添加 MyType 对象并以您可以在 C# 中执行的方式找到它们:ListVar.find(p => p.ID == 3).
此外,如果可行,该列表应该在文件中持久存在。这不是必需的,因为我可以在关闭时将其简单地写入工作表,反之亦然。
是否有其他对象class我可以使用更适合我的需要?
您可以使用数组列表吗?在您的子目录中:
Dim arrayList As Object
Set arrayList = CreateObject("System.Collections.ArrayList")
然后您可以使用 .NET 类型 ArrayList 的所有常用方法,例如 .Contains()
或 .Sort()
等...
编辑: (因为 OP 使用 Mac OS)
您可以自己创建一个 class,并在 collection 中使用它。首先创建一个新的 class 模块(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
会很好用。
不确定是否可以在 mac 上执行此操作,但我使用了与此类似的 class,
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
我开始在 Excel 和 VBA 一起工作,想保存一些列表。
我的方法如下,但我担心我正在寻找完全错误的方向。
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
尝试执行时,出现编译错误:"Only user-defined types defined in public object modules can be coerced to or from a variant or passed to late-bound functions."
目标是拥有一个类似于 C# 的列表,我可以向其中添加 MyType 对象并以您可以在 C# 中执行的方式找到它们:ListVar.find(p => p.ID == 3). 此外,如果可行,该列表应该在文件中持久存在。这不是必需的,因为我可以在关闭时将其简单地写入工作表,反之亦然。
是否有其他对象class我可以使用更适合我的需要?
您可以使用数组列表吗?在您的子目录中:
Dim arrayList As Object
Set arrayList = CreateObject("System.Collections.ArrayList")
然后您可以使用 .NET 类型 ArrayList 的所有常用方法,例如 .Contains()
或 .Sort()
等...
编辑: (因为 OP 使用 Mac OS)
您可以自己创建一个 class,并在 collection 中使用它。首先创建一个新的 class 模块(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
会很好用。
不确定是否可以在 mac 上执行此操作,但我使用了与此类似的 class,
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