ExcelのVBAで使えるDLLを、C++(Visual Studio 2017)で作る。・・・その4.3(非配列Variant型変数による配列受け渡し編)
初めに
前回の予告通り、今回は非配列のVariant型変数に配列を格納して、DLLとの受け渡しをしてみます。
処理
処理方法は、これまでにやってきた事の組み合わせで出来ます。
DLL側でVariant型を受け取る処理は、文字列の受け渡しを行った時と同じ。
受け取ってから、VARIANT型変数のvtを見て、配列かどうかの判断を行います。
配列であることの確認できれば、VARIANT型変数のparrayに目的のSAFEARRAYがあります。
SAFEARRAYがわかれば、あとは、前回の処理を使えます。
コード
DLL
AccessibleFromVBA.h
追加分ACCESSIBLEFROMVBA_API void WINAPI GetArrayV(LPVARIANT pv); ACCESSIBLEFROMVBA_API void WINAPI SetArrayV(const LPVARIANT pv);
AccessibleFromVBA.cpp
AccessibleFromVBA.def
LIBRARY AccessibleFromVba EXPORTS DoNothing GetNumberI GetNumberI2 SetString SetStringS GetStringByParam GetStringByParamS GetStringByRetVal GetStringByRetValS GetArrayPE GetArrayAD GetArray2 SetArrayGE SetArrayAD GetArrayV SetArrayV
VBA
Private Declare Sub SetArrayV Lib "C:\Datas\MyDatas\Developer\VisualStudioComunity2017\DllForVBA\ForTest\AccessibleFromVBA.dll" (ByRef v As Variant) Private Declare Sub GetArrayV Lib "C:\Datas\MyDatas\Developer\VisualStudioComunity2017\DllForVBA\ForTest\AccessibleFromVBA.dll" (ByRef v As Variant) Public Sub DllTestSetArrayV() Dim v As Variant Dim lArray(3, 1) As Long Dim sArray() As String Dim dArray(2) As Double Dim i As Long Dim j As Long ReDim sArray(2) sArray(0) = "Z1000" sArray(1) = "ZX-10R" sArray(2) = "Kawasaki" v = sArray Call SetArrayV(v) ReDim sArray(2, 2) v = sArray Call SetArrayV(v) For i = LBound(lArray, 1) To UBound(lArray, 1) For j = LBound(lArray, 2) To UBound(lArray, 2) lArray(i, j) = (i + 1) * 10 + j Next j Next i 'Arrayを使った場合、DLL側では、vt が VT_VARIANT | VT_ARRAY になるので注意が必要 '以下のコメントしたコードでは、VT_I4 | VT_ARRAY にはならない。 ' v = Array(1&, 2&, 3&, 4&) v = lArray Call SetArrayV(v) v = dArray Call SetArrayV(v) End Sub Public Sub DllTestGetArrayV() Dim vL As Variant Dim vS As Variant Dim i As Long ReDim vL(3) As Long vL(0) = 100 vL(1) = 200 vL(2) = 300 vL(3) = 400 Debug.Print "Before" For i = LBound(vL) To UBound(vL) Debug.Print i, vL(i) Next i Call GetArrayV(vL) Debug.Print vbCrLf & "After" For i = LBound(vL) To UBound(vL) Debug.Print i, vL(i) Next i Debug.Print "" ReDim vS(2) As String vS(0) = "Z1000" vS(1) = "ZX-10R" vS(2) = "Ninja 900R" Debug.Print "Before" For i = LBound(vS) To UBound(vS) Debug.Print i, vS(i) Next i Call GetArrayV(vS) Debug.Print vbCrLf & "After" For i = LBound(vS) To UBound(vS) Debug.Print i, vS(i) Next i End Sub
実行結果
DllTestSetArrayV
DllTestGetArrayV
Before 0 100 1 200 2 300 3 400 After 0 200 1 400 2 600 3 800 Before 0 Z1000 1 ZX-10R 2 Ninja 900R After 0 Z1000 GetArrayV 0 1 ZX-10R GetArrayV 1 2 Ninja 900R GetArrayV 2