Reputation: 702
I have a an Excel addin written in C# I am trying to call from VBA in Excel. In VBA I generate several arrays to pass:
Dim Identifiers() As Variant
Dim Variables() As Variant
Dim Times() As Variant
...
Dim QaddIn As COMAddIn
Dim QTool As Object
Dim results As Variant
Set QaddIn = Application.COMAddIns("QTool")
QaddIn.Connect = True
Set QTool = QaddIn.Object
results = QTool.GetQData(datasetName, Identifiers, Variables, Times, timeString)
GetQData
is defined in C# as:
string[] GetQData(string DatasetName, object[] Identifiers, object[] Variables, object[] TimeCodes,
string TimeString);
But when I run the code, VBA throws the error object of type 'system.object[*]' cannot be converted to object of type 'system.object[]'
. This same code worked fine passing variant arrays defined with a static length, as in Dim Identifiers(3) As Variant
. What is the difference between what I am trying to pass now?
Upvotes: 0
Views: 556
Reputation: 702
The problem was that the array I was attempting to pass to C# was indexed from 1, that is, it was an Array(1 to 5)
rather than an Array(0 to 4)
. It's unfortunate that passing an array indexed from 1 fails, because Range.Value
and all of the WorksheetFunction
methods return arrays indexed from 1.
I wrote the following code in VBA to reindex my arrays from zero before passing them:
Function ShiftArray(ThisArray() As Variant) As Variant
Dim lb As Long, ub As Long
Dim NewArray() As Variant
Dim i As Long
lb = LBound(ThisArray)
ub = UBound(ThisArray)
ReDim NewArray(0 To (ub - lb))
For i = 0 To (ub - lb)
NewArray(i) = ThisArray(i + lb)
Next i
ShiftArray = NewArray
End Function
Upvotes: 1
Reputation: 10712
The problem is that variable length arrays and fixed length arrays are not the same. vba in general will be pretty forgiving so you generally get away with it, but C# isn't. It can't be sure that you mean to convert the array to a fixed length array. You should look for a method on the Identifiers object to convert it to a fixed length array. This will probably then look something like:
results = CIQTool.GetCIQData(datasetName, Identifiers.ToArray(), Variables.ToArray(), Times.ToArray(), timeString)
I'm not sure the exact naming of that method though so use the code completion to look for it.
Upvotes: 0