你能推荐我一个很好的替代 VBA 中引用或指针类型的方法吗?我一直在为这样的表达而苦苦挣扎:
dblMyArray( i * lngDimension0 + j * lngDimension1 + k * lngDimension2, l * lngDimension3 + m * lngDimension4 ) = dblMyArray( i * lngDimension0 + j * lngDimension1 + k * lngDimension2, l * lngDimension3 + m * lngDimension4 ) + 1
如果我想在多维数组中累积值,例如C++,我可以这样写:
double& rElement = dblMyArray[ i * lngDimension0 + j * lngDimension1 + k * lngDimension2 ][ l * lngDimension3 + m * lngDimension4 ];
rElement += 1;
或者
double* pElement = &dblMyArray[ i * lngDimension0 + j * lngDimension1 + k * lngDimension2 ][ l * lngDimension3 + m * lngDimension4 ];
*pElement += 1;
我正在寻找这样的东西。
我不想重复赋值右侧的元素,也不想调用带有 ByRef 参数的函数,因为这会使代码的维护变得更加困难。
有任何想法吗?
最佳答案
VBA 支持指针,但仅限于非常有限的范围,并且主要用于需要它们的 API 函数(通过 VarPtr、StrPtr 和 ObjPtr)。你可以做一些hackery来获取数组内存区域的基地址。 VBA 将数组实现为 SAFEARRAY结构,所以第一个棘手的部分是获取数据区域的内存地址。我发现这样做的唯一方法是让运行时将数组放入 VARIANT 中,然后将其分开:
Public Declare Sub CopyMemory Lib "kernel32" Alias _
"RtlMoveMemory" (Destination As Any, Source As Any, _
ByVal length As Long)
Private Const VT_BY_REF = &H4000&
Public Function GetBaseAddress(vb_array As Variant) As Long
Dim vtype As Integer
'First 2 bytes are the VARENUM.
CopyMemory vtype, vb_array, 2
Dim lp As Long
'Get the data pointer.
CopyMemory lp, ByVal VarPtr(vb_array) + 8, 4
'Make sure the VARENUM is a pointer.
If (vtype And VT_BY_REF) <> 0 Then
'Dereference it for the variant data address.
CopyMemory lp, ByVal lp, 4
'Read the SAFEARRAY data pointer.
Dim address As Long
CopyMemory address, ByVal lp, 16
GetBaseAddress = address
End If
End Function
第二个棘手的部分是 VBA 没有取消引用指针的 native 方法,因此您需要另一个辅助函数来执行此操作:
Public Function DerefDouble(pData As Long) As Double
Dim retVal As Double
CopyMemory retVal, ByVal pData, LenB(retVal)
DerefDouble = retVal
End Function
然后你可以像在 C 中一样使用指针:
Private Sub Wheeeeee()
Dim foo(3) As Double
foo(0) = 1.1
foo(1) = 2.2
foo(2) = 3.3
foo(3) = 4.4
Dim pArray As Long
pArray = GetBaseAddress(foo)
Debug.Print DerefDouble(pArray) 'Element 0
Debug.Print DerefDouble(pArray + 16) 'Element 2
End Sub
这是否是 好主意或者比你现在做的更好,留给读者作为练习。
关于excel - VBA 中引用/指针的良好替代品?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39143998/