HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

CopyOf2DArray (Values Only)

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
valuesonlycopyof2darray

Problem

Purpose:

Given a 2-Dimensional Array, return a copy of the Array. In VBA, if I just

Set newArray = oldArray


then newArray is simply a pointer to oldArray rather than an independent copy, hence this function.

Method:

Assign Array bounds. Create identically-sized Array. Iterate over Array and copy each element value.

Specific Areas of Interest:

The function feels very generic. The naming even more so. But then again it's supposed to be very generic. Is the naming alright or could it be better?

Function:

Private Function CopyOf2DArray(ByRef targetArray As Variant) As Variant
    '/ Will error if the array contains objects

    Dim LB1 As Long, UB1 As Long
    Dim LB2 As Long, UB2 As Long
    AssignArrayBounds targetArray, LB1, UB1, LB2, UB2

    Dim newArray As Variant
    ReDim newArray(LB1 To UB1, LB2 To UB2)

    Dim i As Long, j As Long
    For i = LB1 To UB1
        For j = LB2 To UB2
            newArray(i, j) = targetArray(i, j)
        Next j
    Next i

    CopyOf2DArray = newArray

End Function

Solution

I am going to challenge your premise


...then newArray is simply a pointer to oldArray rather than an
independent copy.

The following code works fine ...

Sub myTest1()
Dim oldArray() As Double, newArray() As Double
Dim i As Long, j As Long

ReDim oldArray(0 To 1, 0 To 2)
For i = 0 To 1
    For j = 0 To 2
        oldArray(i, j) = (i * 10#) + (j * 1#)
    Next j
Next i

newArray = oldArray

For i = 0 To 1
    For j = 0 To 2
        Debug.Print i, j, newArray(i, j)
    Next j
Next i

End Sub


To verify that newArray is not just a pointer to oldArray, the following code ...

Public Declare PtrSafe Function VarPtrArray Lib "VBE7" Alias "VarPtr" (Var() As Any) As LongPtr

Sub myTest2()
Dim oldArray() As Double, newArray() As Double
Dim i As Long, j As Long

ReDim oldArray(0 To 1, 0 To 2)
For i = 0 To 1
    For j = 0 To 2
        oldArray(i, j) = (i * 10#) + (j * 1#)
    Next j
Next i

newArray = oldArray

Debug.Print "oldArray", VarPtrArray(oldArray), VarPtr(oldArray(0, 0))
Debug.Print "newArray", VarPtrArray(newArray), VarPtr(newArray(0, 0))

End Sub


... generates this result ...

oldArray       1633360       350127888 
newArray       1633356       350126600


All of which means that, for arrays that do not contain objects, a simple assignment (e.g. newArray = oldArray) is fine to copy an array.

Code Snippets

Sub myTest1()
Dim oldArray() As Double, newArray() As Double
Dim i As Long, j As Long

ReDim oldArray(0 To 1, 0 To 2)
For i = 0 To 1
    For j = 0 To 2
        oldArray(i, j) = (i * 10#) + (j * 1#)
    Next j
Next i

newArray = oldArray

For i = 0 To 1
    For j = 0 To 2
        Debug.Print i, j, newArray(i, j)
    Next j
Next i

End Sub
Public Declare PtrSafe Function VarPtrArray Lib "VBE7" Alias "VarPtr" (Var() As Any) As LongPtr

Sub myTest2()
Dim oldArray() As Double, newArray() As Double
Dim i As Long, j As Long

ReDim oldArray(0 To 1, 0 To 2)
For i = 0 To 1
    For j = 0 To 2
        oldArray(i, j) = (i * 10#) + (j * 1#)
    Next j
Next i

newArray = oldArray

Debug.Print "oldArray", VarPtrArray(oldArray), VarPtr(oldArray(0, 0))
Debug.Print "newArray", VarPtrArray(newArray), VarPtr(newArray(0, 0))

End Sub
oldArray       1633360       350127888 
newArray       1633356       350126600

Context

StackExchange Code Review Q#134274, answer score: 6

Revisions (0)

No revisions yet.