如何在VBA中创建复合对象?

时间:2015-05-05 12:53:40

标签: vba

我无法通过微软的帮助,只要你知道答案已经解决了,这很好,所以我被困了。

我是否可以创建自己的复合对象(我假设这是术语),例如,对象可以是并且具有以下子类:

  • 名字 - 字符串
  • 姓氏 - 字符串
  • 出生日期 - 日期时间
  • 性别 - 字符串(接受M / F)
  • 高度 - 实数

很抱歉,如果它看起来像一个非常基本的问题(没有双关语),但我已经很长时间没有使用Visual Basic了,而且Microsoft Visual Basic从来都不是我的唯一。

2 个答案:

答案 0 :(得分:4)

我认为您需要使用TYPE语法,如下所示:

TYPE person

    Firstname As String
    Surname As String
    Date_of_birth As Date ' instead of Datetime
    Gender As String '(M/F accepted)
    Height As Single 'instead of Real number

END TYPE

Sub Test()
    Dim aTest As person
End Sub

答案 1 :(得分:4)

您应该考虑使用类模块而不是类型。类型很好,但他们可以做的事情受到限制。一旦我需要比类型更多的功能,我通常最终会将我的类型转换为类。

您可以使用所需的属性创建CPerson类。现在,如果你想返回一个FullName属性,你可以编写一个Property Get来返回它 - 你可以用一种类型来做。

Private mlPersonID As Long
Private msFirstName As String
Private msSurname As String
Private mdtDOB As Date
Private msGender As String
Private mdHeight As Double
Private mlParentPtr As Long

Public Property Let PersonID(ByVal lPersonID As Long): mlPersonID = lPersonID: End Property
Public Property Get PersonID() As Long: PersonID = mlPersonID: End Property
Public Property Let FirstName(ByVal sFirstName As String): msFirstName = sFirstName: End Property
Public Property Get FirstName() As String: FirstName = msFirstName: End Property
Public Property Let Surname(ByVal sSurname As String): msSurname = sSurname: End Property
Public Property Get Surname() As String: Surname = msSurname: End Property
Public Property Let DOB(ByVal dtDOB As Date): mdtDOB = dtDOB: End Property
Public Property Get DOB() As Date: DOB = mdtDOB: End Property
Public Property Let Gender(ByVal sGender As String): msGender = sGender: End Property
Public Property Get Gender() As String: Gender = msGender: End Property
Public Property Let Height(ByVal dHeight As Double): mdHeight = dHeight: End Property
Public Property Get Height() As Double: Height = mdHeight: End Property


Public Property Get FullName() As String

    FullName = Me.FirstName & Space(1) & Me.Surname

End Property

然后,您可以创建一个CPeople类来保存所有CPerson实例。

Private mcolPeople As Collection

Private Sub Class_Initialize()
    Set mcolPeople = New Collection
End Sub

Private Sub Class_Terminate()
    Set mcolPeople = Nothing
End Sub

Public Property Get NewEnum() As IUnknown
    Set NewEnum = mcolPeople.[_NewEnum]
End Property

Public Sub Add(clsPerson As CPerson)
    If clsPerson.PersonID = 0 Then
        clsPerson.PersonID = Me.Count + 1
    End If

    mcolPeople.Add clsPerson, CStr(clsPerson.PersonID)
End Sub

Public Property Get Person(vItem As Variant) As CPerson
    Set Person = mcolPeople.Item(vItem)
End Property

Public Property Get Count() As Long
    Count = mcolPeople.Count
End Property


Public Property Get FilterByGender(ByVal sGender As String) As CPeople

    Dim clsReturn As CPeople
    Dim clsPerson As CPerson

    Set clsReturn = New CPeople

    For Each clsPerson In Me
        If clsPerson.Gender = sGender Then
            clsReturn.Add clsPerson
        End If
    Next clsPerson

    Set FilterByGender = clsReturn

End Property

通过这个课程,您可以通过所有实例进行For Each(谷歌自定义类和NewEnum,看看如何做到这一点)。您还可以使用属性Get来返回CPerson实例的子集(在这种情况下是女性)。

现在,在标准模块中,您可以创建几个CPerson实例,将它们添加到CPeople实例,过滤它们并循环遍历它们。

Public Sub FillPeople()

    Dim clsPerson As CPerson
    Dim clsPeople As CPeople
    Dim clsFemales As CPeople

    Set clsPeople = New CPeople

    Set clsPerson = New CPerson
    With clsPerson
        .FirstName = "Joe"
        .Surname = "Blow"
        .Gender = "M"
        .Height = 72
        .DOB = #1/1/1980#
    End With
    clsPeople.Add clsPerson

    Set clsPerson = New CPerson
    With clsPerson
        .FirstName = "Jane"
        .Surname = "Doe"
        .Gender = "F"
        .Height = 62
        .DOB = #1/1/1979#
    End With
    clsPeople.Add clsPerson

    Set clsFemales = clsPeople.FilterByGender("F")

    For Each clsPerson In clsFemales
        Debug.Print clsPerson.FullName
    Next clsPerson

End Sub

创建课程的学习曲线越来越多,但在我看来这是值得的。