Option Explicit
#If Win64 Then
Const VARIANT_SIZE = 24&
Const PTR_LEN = 8&
#Else
Const VARIANT_SIZE = 16&
Const PTR_LEN = 4&
#End If
#If VBA7 Then
Private Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As LongPtr)
Private Declare PtrSafe Sub ZeroMemory Lib "kernel32" Alias "RtlZeroMemory" (dest As Any, ByVal numBytes As LongPtr)
Private Declare PtrSafe Function SafeArrayAccessData Lib "oleaut32" Alias "#23" (ByVal psa As LongPtr, pData As LongPtr) As Long
Private Declare PtrSafe Function SafeArrayUnaccessData Lib "oleaut32" Alias "#24" (ByVal psa As LongPtr) As Long
#Else
Private Enum LongPtr
[_]
End Enum
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As LongPtr)
Private Declare Sub ZeroMemory Lib "kernel32" Alias "RtlZeroMemory" (dest As Any, ByVal numBytes As LongPtr)
Private Declare Function SafeArrayAccessData Lib "oleaut32" Alias "#23" (ByVal psa As LongPtr, pData As LongPtr) As Long
Private Declare Function SafeArrayUnaccessData Lib "oleaut32" Alias "#24" (ByVal psa As LongPtr) As Long
#End If
Function Join_2D_Arrays(ByVal Ar1 As Variant, ByVal Ar2 As Variant) As Variant()
Const S_OK = 0&
Dim psa1 As LongPtr, pData1 As LongPtr
Dim psa2 As LongPtr, pData2 As LongPtr
Dim vJoinedArray As Variant
Dim lRowsCount1 As Long, lRowsCount2 As Long
Dim lColCount1 As Long, lColCount2 As Long
Dim n As Long
ReDim vJoinedArray(1& To UBound(Ar1, 1&) + UBound(Ar2, 1&) + 1&, 1& To UBound(Ar1, 2&))
Call CopyMemory(psa1, ByVal VarPtr(Ar1) + 8&, PTR_LEN)
If SafeArrayAccessData(psa1, pData1) <> S_OK Then
GoTo errHandler
End If
lRowsCount1 = UBound(Ar1, 1&): lColCount1 = UBound(Ar1, 2&)
For n = 0& To UBound(Ar1, 2&) - 1&
If n < lColCount1 Then
Call CopyMemory(vJoinedArray(1&, n + 1&), ByVal pData1 + (n * VARIANT_SIZE * lRowsCount1), lRowsCount1 * VARIANT_SIZE)
End If
Next n
Call SafeArrayUnaccessData(psa1)
Call CopyMemory(psa2, ByVal VarPtr(Ar2) + 8&, PTR_LEN)
If SafeArrayAccessData(psa2, pData2) <> S_OK Then
GoTo errHandler
End If
lRowsCount2 = UBound(Ar2, 1&): lColCount2 = UBound(Ar2, 2&)
For n = 0& To UBound(Ar2, 2&) - 1&
If n < lColCount1 Then
Call CopyMemory(vJoinedArray(lRowsCount1 + 1&, n + 1&), ByVal pData2 + (n * VARIANT_SIZE * lRowsCount2), lRowsCount2 * VARIANT_SIZE)
End If
Next n
Call SafeArrayUnaccessData(psa2)
Join_2D_Arrays = vJoinedArray
For n = 0& To UBound(Ar1, 2&) - 1&
If n < lColCount1 Then
Call ZeroMemory(vJoinedArray(1&, n + 1&), ByVal UBound(vJoinedArray, 1&) * VARIANT_SIZE)
End If
Next n
Exit Function
errHandler:
MsgBox "Unable to get the array data."
End Function