Search code examples
excelobjectcollectionsuser-defined-typesvba

Collection of Objects Passing a new UDT to each Object while Looping thru an Array


My aMRecon array is 2500 rows x 65 columns. I need to evaluate up to 10+ columns within each single row and thus I believe I need to create an object representing each row. I have created a UDT and in a basic procedure below I am trying to create an object for each row with each object having an .EntityID property (which is the cell value in each row within Column B or Column 2).

Public Type BreakInfo
    EntityID As String
    IssueName As String  
    ValDate As Date
    LedgerAMT As Long
    NetAMTL As Long
    PriceDiff As Long                    
End Type

Sub Fill_Objects()

Dim aMrow As Integer, aMcol As Integer
Dim BI As BreakInfo

For aMcol = LBound(aMRecon, 2) To UBound(aMRecon, 2)
        For aMrow = LBound(aMRecon, 1) To UBound(aMRecon, 1)
                If aMcol = 2 Then
                    Debug.Print aMRecon(aMrow, aMcol)
                    Set ObjLSL = New Collection
                    BI.EntityID = aMRecon(aMrow, aMcol)
                End If
        Next aMrow
    Next aMcol
End If

End Sub

Do I need to somehow create a collection of objects? Could someone please show me an example to help. As of right now I think I only have one object and the .EntityID property keeps getting overwritten. Thank you

In Fact each row at will only have 1 property, basically each property is a Column Header. Am I going about this the most efficient way? Eventually I will need to evaluate each property within an object and categorize it.

Inserted a ClassModule entitle BreakInfo

'Public EntityID As String
Public EntityID As Variant
Public IssueName As String  
Public ValDate As Date
Public LedgerAMT As Long
Public NetAMTL As Long
Public PriceDiff As Long 

That's all that's in the class.


Solution

  • You need to first create (insert) a Class Module, name it BreakInfo, and give it Public members like this:

    Option Explicit
    
    Public EntityID As String
    Public IssueName As String
    Public ValDate As Date
    Public LedgerAMT As Long
    Public NetAMTL As Long
    Public PriceDiff As Long
    

    Then you can use something like this:

    Sub Fill_Objects()
        Dim aMrow As Integer, aMcol As Integer
        Dim BI As BreakInfo
        Dim ObjLSL As Collection
        Dim key As Long
    
        'Create the Collection instance.
        Set ObjLSL = New Collection
    
        For aMcol = LBound(aMRecon, 2) To UBound(aMRecon, 2)
            For aMrow = LBound(aMRecon, 1) To UBound(aMRecon, 1)
                If aMcol = 2 Then
                    'Instantiate a BreakInfo.
                    Set BI = New BreakInfo
                    BI.EntityID = aMRecon(aMrow, aMcol)
                    '...
    
                    key = key + 1
                    ObjLSL.Add BI, CStr(key)
                End If
            Next aMrow
        Next aMcol
    End Sub
    

    Notice that the collection is instantiated once, before the loops. A collection can't ingest variables of user-defined types, but it will gladly gobble up object instances.

    Edit

    The question has changed. If you worry about efficiency, you could hardcode aMcol = 2 and do without the outer For and the If aMcol = 2. Other than that, I don't understand what you're trying to do with your values.