【问题标题】:Use of Custom Data Types in VBA在 VBA 中使用自定义数据类型
【发布时间】:2012-09-07 00:11:05
【问题描述】:

我正在尝试在 VBA for Excel 中创建自定义数据类型。我们称这种数据类型为“卡车”。每辆卡车都有以下属性:

NumberOfAxles (this is an integer)
AxleWeights (this is an array of doubles)
AxleSpacings (this is an array of doubles)

我可以创建多个数据类型“卡车”(卡车(1)、卡车(2)...等)的实例,然后将上面列出的属性读/写到该实例吗?

例子:

Truck(1).NumberOfAxles = 2
Truck(1).AxleWeights(1) = 15.0
Truck(1).AxleWeights(2) = 30.0
Truck(1).AxleSpacings(1) = 8.0

Truck(2).NumberOfAxles = 3
Truck(2).AxleWeights(1) = 8.0
Truck(2).AxleWeights(2) = 10.0
Truck(2).AxleWeights(3) = 12.0
Truck(2).AxleSpacings(1) = 20.0
Truck(2).AxleSpacings(2) = 4.0

等等。上面的语法很可能是错误的,我只是想展示我需要提出的结构。

我正在尝试将数据写入数据结构并根据需要调用它,例如

Truck(i).NumberOfAxles
Truck(i).AxleWeights(j)
Truck(i).AxleSpacings(j)

非常感谢!

【问题讨论】:

    标签: class vba types excel


    【解决方案1】:

    当然可以:

    Option Explicit
    
    '***** User defined type
    Public Type MyType
         MyInt As Integer
         MyString As String
         MyDoubleArr(2) As Double
    End Type
    
    '***** Testing MyType as single variable
    Public Sub MyFirstSub()
        Dim MyVar As MyType
    
        MyVar.MyInt = 2
        MyVar.MyString = "cool"
        MyVar.MyDoubleArr(0) = 1
        MyVar.MyDoubleArr(1) = 2
        MyVar.MyDoubleArr(2) = 3
    
        Debug.Print "MyVar: " & MyVar.MyInt & " " & MyVar.MyString & " " & MyVar.MyDoubleArr(0) & " " & MyVar.MyDoubleArr(1) & " " & MyVar.MyDoubleArr(2)
    End Sub
    
    '***** Testing MyType as an array
    Public Sub MySecondSub()
        Dim MyArr(2) As MyType
        Dim i As Integer
    
        MyArr(0).MyInt = 31
        MyArr(0).MyString = "VBA"
        MyArr(0).MyDoubleArr(0) = 1
        MyArr(0).MyDoubleArr(1) = 2
        MyArr(0).MyDoubleArr(2) = 3
        MyArr(1).MyInt = 32
        MyArr(1).MyString = "is"
        MyArr(1).MyDoubleArr(0) = 11
        MyArr(1).MyDoubleArr(1) = 22
        MyArr(1).MyDoubleArr(2) = 33
        MyArr(2).MyInt = 33
        MyArr(2).MyString = "cool"
        MyArr(2).MyDoubleArr(0) = 111
        MyArr(2).MyDoubleArr(1) = 222
        MyArr(2).MyDoubleArr(2) = 333
    
        For i = LBound(MyArr) To UBound(MyArr)
            Debug.Print "MyArr: " & MyArr(i).MyString & " " & MyArr(i).MyInt & " " & MyArr(i).MyDoubleArr(0) & " " & MyArr(i).MyDoubleArr(1) & " " & MyArr(i).MyDoubleArr(2)
        Next
    End Sub
    

    【讨论】:

    • 不客气! @ooo 关于课程的答案也对你有用。
    • 我检查了 ooo 的答案,我看到了使用类而不是类型的优势。我同意使用类将使代码更具前瞻性,但您的回复快速解决了我的具体问题(数据结构非常简单且有限)。
    • 您需要确保,该类型是在任何子或函数之前定义的,稍后定义它会导致问题(或根本不起作用)。
    • MyType 定义在同一个代码模块中吗?代码在什么类型的代码模块中?
    • 使用 excel 2016 仅在定义为 private 时有效
    【解决方案2】:

    您似乎想将 Truck 定义为具有 NumberOfAxles、AxleWeights 和 AxleSpacings 属性的 Class

    这可以在CLASS MODULE(这里命名为clsTrucks)中定义

    Option Explicit
    
    Private tID As String
    Private tNumberOfAxles As Double
    Private tAxleSpacings As Double
    
    
    Public Property Get truckID() As String
        truckID = tID
    End Property
    
    Public Property Let truckID(value As String)
        tID = value
    End Property
    
    Public Property Get truckNumberOfAxles() As Double
        truckNumberOfAxles = tNumberOfAxles
    End Property
    
    Public Property Let truckNumberOfAxles(value As Double)
        tNumberOfAxles = value
    End Property
    
    Public Property Get truckAxleSpacings() As Double
        truckAxleSpacings = tAxleSpacings
    End Property
    
    Public Property Let truckAxleSpacings(value As Double)
        tAxleSpacings = value
    End Property
    

    然后在 MODULE 中定义新卡车及其属性并将其添加到卡车集合中,然后检索该集合。

    Option Explicit
    
    Public TruckCollection As New Collection
    
    Sub DefineNewTruck()
    Dim tempTruck As clsTrucks
    Dim i As Long
    
        'Add 5 trucks
        For i = 1 To 5
            Set tempTruck = New clsTrucks
            'Random data
            tempTruck.truckID = "Truck" & i
            tempTruck.truckAxleSpacings = 13.5 + i
            tempTruck.truckNumberOfAxles = 20.5 + i
    
            'tempTruck.truckID is the collection key
            TruckCollection.Add tempTruck, tempTruck.truckID
        Next i
    
        'retrieve 5 trucks
        For i = 1 To 5
            'retrieve by collection index
            Debug.Print TruckCollection(i).truckAxleSpacings
            'retrieve by key
            Debug.Print TruckCollection("Truck" & i).truckAxleSpacings
    
        Next i
    
    End Sub
    

    有几种方法可以做到这一点,因此这实际上取决于您打算如何使用数据来确定类/集合是最佳设置还是数组/字典等。

    【讨论】:

    • 感谢您解释使用类的方法。我今天实现这个只是为了熟悉它,它就像一个魅力。出于我的目的,“自定义类型”方法有效,因为将来不会对这个项目进行扩展。但是,我将尝试在接下来的项目中更频繁地使用类。谢谢!
    • 对于非常简单的数据类型,类可能是矫枉过正。 Olle 的回答中定义的类型相当于其他语言中的 struct ,在某些情况下可能更轻更容易使用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多