Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Excel VBA Collections and Custom Data Types

I'm trying to learn how to create a custom data type, then use that with a collection. I solved the problem another way, but this started with a timesheet report I was automating. I originally wanted a 2 dimensional array with varying data types. When I couldn't do that, some research led to the idea of a collection of custom data types. However the examples I have found keep pushing me to create a class. I am not yet comfortable with that and it seems like this should be doable. Here is kind of what I am a looking for (I started with an example I found on this site):

Option Explicit

'***** User defined type
Public Type MyType
  MyInt As Integer
  MyString As String
  MyDoubleArr(2) As Double
End Type

Public ColThings As Collection

Sub CollectionTest()
  Dim x As Integer
  Dim vrecord As MyType

  For x = 1 To 4
      vrecord.MyInt = x
      vrecord.MyString = "Matt"
      vrecord.MyDoubleArr(0) = x + 5
      vrecord.MyDoubleArr(1) = x + 6
      vrecord.MyDoubleArr(2) = x + 7
      ColThings.Add vrecord
  Next x

  For x = 1 To 4
     Debug.Assert vrecord.MyInt & " - " & vrecord.MyString & " - " &   vrecord.MyDoubleArr(0) & ", " & vrecord.MyDoubleArr(1) & ", " & vrecord.MyDoubleArr(0)
  Next x
End Sub

The error I get is: Compile Error: "Only user-defined types defined in public object modules can be coerced to or from a variant or passed to late-bound functions"

I am not a novice with VBA, but I am trying to make the next step.

Thanks in advance.

like image 792
Matthew Stockton Avatar asked Jan 21 '26 16:01

Matthew Stockton


1 Answers

I took a stab at it, ultimately I am not sure if this is what you want, but if you don't want to make a class then the only other option I can see is to store your types in an array instead of a collection. To my knowledge (please correct me if I am wrong) you cannot add a user-defined type to a collection, you must create it as a class, instantiate an object of that class, then add that to the collection.

Instead I declared the array Records() of MyType and added each MyType to that array.

Option Explicit

'***** User defined type
Public Type MyType
  MyInt As Integer
  MyString As String
  MyDoubleArr(2) As Double
End Type

Public ColThings As Collection

Sub CollectionTest()
  Dim x As Integer
  Dim Records() As MyType
  Dim vrecord As MyType

  For x = 1 To 4
      vrecord.MyInt = x
      vrecord.MyString = "Matt"
      vrecord.MyDoubleArr(0) = x + 5
      vrecord.MyDoubleArr(1) = x + 6
      vrecord.MyDoubleArr(2) = x + 7
      ReDim Preserve Records(x)
      Records(x) = vrecord
  Next x

  For x = 1 To 4
     Debug.Print Records(x).MyInt & " - " & Records(x).MyString & " - " & Records(x).MyDoubleArr(0) & ", " & Records(x).MyDoubleArr(1) & ", " & Records(x).MyDoubleArr(0)
  Next x

End Sub

I believe that is similar to what you want to accomplish. I haven't attempted the class method yet as you said you were not quite ready for that, but that would be a very good exercise in my humble opinion.

like image 135
Soulfire Avatar answered Jan 23 '26 09:01

Soulfire



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!