我目前处于不幸的位置,不得不通过COM Interop从C#调用VBA宏。宏返回一个字符串数组,看起来像:
Public Function Foo() As String()
然后我试图在C#中转换为一个字符串数组,如下所示:
var result = (string[])xlApp.Run("Foo", ... missing args ...)
然后导致运行时错误:
无法将'System.String [*]'类型的对象强制转换为'System.String []'。
有谁知道String [*]是什么,你知道如何将它转换为C#string []吗?这个演员在我创建的一个简单测试用例中工作。我能看到的唯一区别是,在简单的情况下,我在VBA中的数组是字符串类型(0到5),而在更复杂的情况下,它是字符串类型(1到6)。这可能是原因,如果是这样,我的VBA相当生疏 - 我该如何解决?
非常感谢,
乔恩
答案 0 :(得分:5)
.NET支持这样的数组(下限不同于0),您可以使用这样的代码段创建一个:
Array arr = Array.CreateInstance(typeof(string), new int[] { 5 }, new int[] {1});
将这样的数组转换为string []的最简单方法是(虽然,它复制数据,另一方面,这些只是引用,所以如果你的数组不是太长,你将不会获得巨大的性能):
string[] x = new string[5];
Array.Copy(arr, 1, x, 0, 5);
编辑:或使用更一般的方法:
string[] x = new string[arr.GetLength(0)];
Array.Copy(arr, arr.GetLowerBound(0), x, 0, arr.GetLength(0));
Edit2:它看起来像是使用lowerbounds的数组!= 0适用于罚款,如果有超过1个维度,你可以阅读更多here,其中Jon Skeet似乎回答了为什么会发生这种情况。
编辑3:根据djna的评论,使回复不那么模糊。这是你如何从方法返回的对象中获取string [],不能直接转换为string [],因为它有lowerBound!= 0:
Array arr = (Array)xlApp.Run("Foo", ... missing args ...); //Here I assume that .Run() method is returning object, or something that has to be casted to Array.
string[] result = new string[arr.GetLength(0)];
Array.Copy(arr, arr.GetLowerBound(0), result, 0, arr.GetLength(0)); // Here data is copied, but only references in this scenario
答案 1 :(得分:1)
您的代码是
var result = (string[])xlApp.Run("Foo", ... missing args ...);
正如您所指出的,基于1的数组有不同的行为,在VB中使用从零开始的数组,您的代码可以正常工作。
你可以获得这样的数据
var result = (Array)xlApp.Run("Foo", ... missing args ...);
var stringsResult = result.Cast<string>[];
这为您提供了IEnumerable of string