4

Microsoft Excel で動作する vb.net COM 相互運用に取り組んでおり、vb から vb.net に配列を渡す際に問題が発生しています。PointPairsvb から設定する必要がある vb.net コードにプロパティがあり、2 次元配列を渡すのに問題があります。2D 配列でプロパティを明示的に設定することと、2 つの 1D 配列を Sub に渡して vb.net でプロパティを設定しようとしましたが、何もうまくいかないようです。

vb.net コード:

Public Property PointPairs() As Double(,)
   Get
     ...
     Return array
   End Get
   Set(ByVal Value(,) As Double)
     ...
   End Set
End Property

Public Sub SetPointPairs(ByRef spline As Spline, ByRef xValues() As Double, _
                              ByRef yValues() As Double)
   Dim Value(,) As Double
   ReDim Value(1, UBound(xValues, 1))

   For i As Integer = 0 To UBound(xValues, 1)
       Value(0, i) = xValues(i)
       Value(1, i) = yValues(i)
   Next

   spline.PointPairs = Value
End Sub

vb コード:

Dim spline1 As New Spline
Dim points(), xValues(), yValues() As Double
'read input from excel cells into points() array/add x and y values to respective arrays

spline1.PointPairs = points 'first method (doesn't work)
Call SetPointPairs(spline1, xValues, yValues)  'second method (doesn't work)

すべてがvb.netによって正しくエクスポートされており、プロパティ/サブ/関数がvbaのオブジェクトブラウザに表示されていますが、これら2つのアプローチで配列を渡そうとすると、エラーメッセージFunction or interfaces markes as restricted, or the function uses an automation type not supported in Visual BasicまたはSub or Function not defined. 私も使用してみ<MarshalAs()>ましたが、これまで使用したことがなく、vb と vb.net の間で配列を渡すために使用する方法に関するドキュメントがあまり見つかりません。

提案や解決策を事前に感謝します

4

1 に答える 1

2

このソリューションに興味がある人は、まさに私が必要としていたこの記事を見つけました。

http://www.codeproject.com/Articles/12386/Sending-an-array-of-doubles-from-Excel-VBA-to-C-us?fid=247508&select=2478365&tid=2478365

VBA で 2D 配列を Double の 2 つの 1D 配列に分割し、それらをオブジェクトとして vb.net に渡し、記事で説明されているように変更する必要がありました。SetPointPairs Sub を次のように変更し、.net コードでオブジェクトから配列に変換するこのプライベート関数を追加しました

Sub SetPointPairs(ByRef spline As CubicSpline, ByRef xValues As Object, ByRef yValues As Object) Implements iCubicSpline.SetPointPairs

        Dim xDbls(), yDbls(), pointDbls(,) As Double

        xDbls = ComObjectToDoubleArray(xValues)
        yDbls = ComObjectToDoubleArray(yValues)
        ReDim pointDbls(1, UBound(xDbls, 1))
        For i As Integer = 0 To UBound(pointDbls, 2)
            pointDbls(0, i) = xDbls(i)
            pointDbls(1, i) = yDbls(i)
        Next

        spline.PointPairs = pointDbls

End Sub

Private Function ComObjectToDoubleArray(ByVal comObject As Object) As Double()

        Dim thisType As Type = comObject.GetType
        Dim dblType As Type = Type.GetType("System.Double[]")
        Dim dblArray(0) As Double

        If thisType Is dblType Then
            Dim args(0) As Object
            Dim numEntries As Integer = CInt(thisType.InvokeMember("Length", BindingFlags.GetProperty, _
                                            Nothing, comObject, Nothing))
            ReDim dblArray(numEntries - 1)
            For j As Integer = 0 To numEntries - 1
                args(0) = j
                dblArray(j) = CDbl(thisType.InvokeMember("GetValue", BindingFlags.InvokeMethod, _
                                        Nothing, comObject, args))
            Next
        End If

        Return dblArray

    End Function
于 2013-07-09T21:19:32.427 に答える