2012-09-13 15 views
31

Sto tentando di creare un tipo di dati personalizzato in VBA per Excel. Chiamiamo questo tipo di dati "camion". Ogni camion ha i seguenti attributi:Uso di tipi di dati personalizzati in VBA

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

posso creare molte istanze del tipo di dati "truck" (camion (1), camion (2) ... ecc), e leggere/scrivere gli attributi che ho elencato sopra a quell'istanza?

Esempio:

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 

e così via. La sintassi sopra riportata è molto probabilmente sbagliata, volevo solo dimostrare la struttura che ho bisogno di inventare.

Tutto quello che sto cercando di scrivere dati a una struttura di dati e lo chiamano, se necessario, come ad esempio

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

Grazie mille!

risposta

51

Certo che puoi:

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 
+0

grande spiegazione! Molte grazie! – marillion

+0

Prego! La risposta di @ooo sulle classi funzionerà anche per te. –

+1

Ho controllato la risposta di ooo, e vedo i vantaggi dell'uso di classi anziché di tipi. Sono d'accordo che l'uso delle classi renderà il codice più a prova di futuro, ma la tua risposta risolve il mio problema specifico (la struttura dei dati è molto semplice e limitata) in modo rapido. – marillion

27

Sembra che si desidera definire come un camion Class con proprietà NumberOfAxles, AxleWeights & AxleSpacings.

Questa può essere definita in un modulo CLASSE (qui chiamato 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 

poi in un modulo il seguente definisce un nuovo camion e le sue proprietà e lo aggiunge ad una collezione di camion e poi recupera la collezione.

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 

Ci sono diversi modi di fare questo in modo che in realtà dipende da come si intende utilizzare i dati sul fatto che una classe/collezione è il miglior set up o array/dizionari ecc

+6

grazie per aver spiegato l'approccio usando le classi. L'ho implementato oggi solo per familiarizzare e funziona come un fascino. Per il mio scopo, l'approccio "tipo personalizzato" funziona, dal momento che non ci sarà alcuna espansione su questo progetto in futuro. Tuttavia, cercherò di usare le lezioni più spesso nei prossimi progetti. Grazie! – marillion

Problemi correlati