Excel VBA - How to Redim a 2D array?

前端 未结 9 2062
闹比i
闹比i 2020-11-30 06:57

In Excel via Visual Basic, I am iterating through a CSV file of invoices that is loaded into Excel. The invoices are in a determinable pattern by client.

I am readin

相关标签:
9条回答
  • 2020-11-30 07:13

    A small update to what @control freak and @skatun wrote previously (sorry I don't have enough reputation to just make a comment). I used skatun's code and it worked well for me except that it was creating a larger array than what I needed. Therefore, I changed:

    ReDim aPreservedArray(nNewFirstUBound, nNewLastUBound)
    

    to:

    ReDim aPreservedArray(LBound(aArrayToPreserve, 1) To nNewFirstUBound, LBound(aArrayToPreserve, 2) To nNewLastUBound)
    

    This will maintain whatever the original array's lower bounds were (either 0, 1, or whatever; the original code assumes 0) for both dimensions.

    0 讨论(0)
  • 2020-11-30 07:15

    i solved this in a shorter fashion.

    Dim marray() as variant, array2() as variant, YY ,ZZ as integer
    YY=1
    ZZ=1
    
    Redim marray(1 to 1000, 1 to 10)
    Do while ZZ<100 ' this is populating the first array
    marray(ZZ,YY)= "something"
    ZZ=ZZ+1
    YY=YY+1 
    Loop
    'this part is where you store your array in another then resize and restore to original
    array2= marray
    Redim marray(1 to ZZ-1, 1 to YY)
    marray = array2
    
    0 讨论(0)
  • 2020-11-30 07:20

    Here ya go.

    Public Function ReDimPreserve(ByRef Arr, ByVal idx1 As Integer, ByVal idx2 As Integer)
    
        Dim newArr()
        Dim x As Integer
        Dim y As Integer
    
        ReDim newArr(idx1, idx2)
    
        For x = 0 To UBound(Arr, 1)
            For y = 0 To UBound(Arr, 2)
                newArr(x, y) = Arr(x, y)
            Next
        Next
    
        Arr = newArr
    
    End Function
    
    0 讨论(0)
  • 2020-11-30 07:23

    This isn't exactly intuitive, but you cannot Redim(VB6 Ref) an array if you dimmed it with dimensions. Exact quote from linked page is:

    The ReDim statement is used to size or resize a dynamic array that has already been formally declared using a Private, Public, or Dim statement with empty parentheses (without dimension subscripts).

    In other words, instead of dim invoices(10,0)

    You should use

    Dim invoices()
    Redim invoices(10,0)
    

    Then when you ReDim, you'll need to use Redim Preserve (10,row)

    Warning: When Redimensioning multi-dimensional arrays, if you want to preserve your values, you can only increase the last dimension. I.E. Redim Preserve (11,row) or even (11,0) would fail.

    0 讨论(0)
  • 2020-11-30 07:24

    I stumbled across this question while hitting this road block myself. I ended up writing a piece of code real quick to handle this ReDim Preserve on a new sized array (first or last dimension). Maybe it will help others who face the same issue.

    So for the usage, lets say you have your array originally set as MyArray(3,5), and you want to make the dimensions (first too!) larger, lets just say to MyArray(10,20). You would be used to doing something like this right?

     ReDim Preserve MyArray(10,20) '<-- Returns Error
    

    But unfortunately that returns an error because you tried to change the size of the first dimension. So with my function, you would just do something like this instead:

     MyArray = ReDimPreserve(MyArray,10,20)
    

    Now the array is larger, and the data is preserved. Your ReDim Preserve for a Multi-Dimension array is complete. :)

    And last but not least, the miraculous function: ReDimPreserve()

    'redim preserve both dimensions for a multidimension array *ONLY
    Public Function ReDimPreserve(aArrayToPreserve,nNewFirstUBound,nNewLastUBound)
        ReDimPreserve = False
        'check if its in array first
        If IsArray(aArrayToPreserve) Then       
            'create new array
            ReDim aPreservedArray(nNewFirstUBound,nNewLastUBound)
            'get old lBound/uBound
            nOldFirstUBound = uBound(aArrayToPreserve,1)
            nOldLastUBound = uBound(aArrayToPreserve,2)         
            'loop through first
            For nFirst = lBound(aArrayToPreserve,1) to nNewFirstUBound
                For nLast = lBound(aArrayToPreserve,2) to nNewLastUBound
                    'if its in range, then append to new array the same way
                    If nOldFirstUBound >= nFirst And nOldLastUBound >= nLast Then
                        aPreservedArray(nFirst,nLast) = aArrayToPreserve(nFirst,nLast)
                    End If
                Next
            Next            
            'return the array redimmed
            If IsArray(aPreservedArray) Then ReDimPreserve = aPreservedArray
        End If
    End Function
    

    I wrote this in like 20 minutes, so there's no guarantees. But if you would like to use or extend it, feel free. I would've thought that someone would've had some code like this up here already, well apparently not. So here ya go fellow gearheads.

    0 讨论(0)
  • 2020-11-30 07:24

    Here is how I do this.

    Dim TAV() As Variant
    Dim ArrayToPreserve() as Variant
    
    TAV = ArrayToPreserve
    ReDim ArrayToPreserve(nDim1, nDim2)
    For i = 0 To UBound(TAV, 1)
        For j = 0 To UBound(TAV, 2)
            ArrayToPreserve(i, j) = TAV(i, j)
        Next j
    Next i
    
    0 讨论(0)
提交回复
热议问题