VBA 中的元组样式对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2196284/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Tuple style object in VBA
提问by ChrisDiRulli
I'm using VBA in an Access application and I would like to have a n-tuple object that contains values of different data types. Then I would like a collection of those objects.
我在 Access 应用程序中使用 VBA,并且我想要一个包含不同数据类型值的 n 元组对象。然后我想要这些对象的集合。
If I was doing this in javascript it would look like:
如果我在 javascript 中这样做,它看起来像:
var myStructure = {
name: "blah"
age: 33
moreStuff : "test"
};
And then I would need a collection of myStructure. How can I best accomplish this in VBA?
然后我需要一个 myStructure 的集合。我怎样才能最好地在 VBA 中做到这一点?
回答by Philippe Grondier
You can define your own variable type with code such as:
您可以使用以下代码定义自己的变量类型:
Public T_Person as Type
name as string
dateOfBirth as date
....
email() as string (*)
....
End type
You can then declare a T_person type in your code with:
然后你可以在你的代码中声明一个 T_person 类型:
Dim currentPerson as T_Person
currentPerson.name = myName
currentPerson.dateOfBirth = myDate
currentPerson.email(1) = myFirstEmail
....
(*) I do not remember the details for declaring arrays in such circumstances. You might have to determine array's length when defining the variable. Please check help.
(*) 我不记得在这种情况下声明数组的细节。在定义变量时,您可能必须确定数组的长度。请检查帮助。
The same result can also be reached by declaring a class module named, for example, "Person". In this class module, you'll be not only able to follow the objet properties (such as name, dateOfBirth, etc), but also object events (initialisation and deletion). You'll be also able to create methods on this object. You code would then look like:
通过声明一个名为“Person”的类模块也可以达到相同的结果。在这个类模块中,您不仅可以跟踪对象属性(例如名称、出生日期等),还可以跟踪对象事件(初始化和删除)。您还可以在此对象上创建方法。您的代码将如下所示:
Dim myPerson as Person
set myPerson = New Person
myPerson.name = myName
myPerson.dateOfBirth = myDate
if myPerson.age > 18 then (*)
'the guy is an adult'
myPerson.createAccount
Else
'the guy is not ...'
Endif
(*) Here, age is a calculated proerty of your object, available when dateOfBirth is not null. Please google "VBA class module" to find different examples for the implementation of a class module in VBA.
(*) 此处,年龄是对象的计算属性,当 dateOfBirth 不为 null 时可用。请谷歌“VBA 类模块”以查找在 VBA 中实现类模块的不同示例。
Now, if you want to manage a collection of similar "objects" (here, Persons), you will have to go through the creation of a class module for your objects collection (a "Persons" class module for example) and make use of the "Collection" objet available in VBA. You will then end with 2 different class modules: Person (will hold each person's detail), and Persons (will hold the collection of Persons). You'll then be able to have code like this:
现在,如果您想管理一组类似的“对象”(此处为 Persons),则必须为对象集合创建一个类模块(例如“Persons”类模块)并利用VBA 中可用的“集合”对象。然后,您将以 2 个不同的类模块结束:Person(将保存每个人的详细信息)和 Persons(将保存 Persons 的集合)。然后你就可以有这样的代码:
Public myPersons as Persons 'at the app level, 1 main collection'
myPersons.add .... 'adding a new person to your collection'
myPersons.count ... 'counting number of persons in myPersons'
Please google on "VBA collection object" for examples on Collection management in VBA. Check my code proposal, as this was written on the fly, and without VBA help file.
请在“VBA 集合对象”上搜索有关 VBA 中集合管理的示例。检查我的代码提案,因为这是即时编写的,并且没有 VBA 帮助文件。
The "Class" solution is clearly more powerfull, but more complex than the "Type". Go for it if you need it. It is definitely worth the pain!
“Class”解决方案显然比“Type”更强大,但更复杂。如果你需要,就去吧。这绝对值得痛苦!
PS: I am not very happy with my namings here, as this can lead to very confusing code when dealing with the myPersons collection and myPerson instance of o Person object. I'd advise you to find a more obvious one, like "PersonCollection" and "Person", or even "Individual"
PS:我对这里的命名不太满意,因为在处理 myPersons 集合和 o Person 对象的 myPerson 实例时,这会导致代码非常混乱。我建议你找一个更明显的,比如“PersonCollection”和“Person”,甚至“Individual”
回答by BrianZ
You can use Variant multidimensional arrays to store your collections. Variants can store any data type making it very versatile.
您可以使用 Variant 多维数组来存储您的集合。变体可以存储任何数据类型,使其非常通用。
Const Name as Integer = 0
Const Age as Integer = 1
Const moreStuff as Integer = 2
Dim myStructure as Variant
Redim myStructure(0 to 2, 0 to n)
myStructure(Name, 0) = "Blah"
myStructure(Age, 0) = 33
myStructure(moreStuff, 0) = "test"
Note: You can only expand the last dimension of a multidimensional array in VBA and preserve the values, so make sure that it is for the dimension you want to scale.
注意:您只能在 VBA 中扩展多维数组的最后一个维度并保留这些值,因此请确保它适用于您要缩放的维度。
That is the basic data structure and you can develop a class or functions to wrap everything up to suit your needs.
这是基本的数据结构,您可以开发一个类或函数来包装所有内容以满足您的需求。
回答by Foole
The Collection class is an option.
Collection 类是一个选项。
Dim col As New Collection
col.Add("blah", "name")
col.Add(33, "age")
col.Add("test", "moreStuff")
This gives you the most flexibility. However it isn't very efficient and the Collection class has no way to get a list of keys.
这为您提供了最大的灵活性。但是它不是很有效,并且 Collection 类无法获取键列表。
回答by Bobort
You may also want to look into the Scripting.Dictionary object, though I have read that it is considered unsafe. It is more dynamic than using Type definitions, and unlike Collection, it gives you access to the keys.
您可能还想查看 Scripting.Dictionary 对象,尽管我已经读到它被认为是不安全的。它比使用类型定义更具动态性,并且与 Collection 不同,它允许您访问键。
Here's a sample:
这是一个示例:
Public Function TestDictionary()
Dim d As New Scripting.Dictionary 'need reference to Microsoft Scripting Runtime
'Dim d As Object
'Set d = CreateObject("Scripting.Dictionary")
Dim k As Variant
d.Add "Banana", "Yellow"
d.Add "Apple", "Red"
d.Add "Grape", "Green"
For Each k In d.Keys
Debug.Print k; ": "; d.Item(k)
Next k
End Function