可以使用com互操作将变量数组传递给C#吗?
我尝试在Excel和C#之间传输一些数据。为此,我编写了一个简单的C#类,其中包含一个属性来设置和获取数据可以使用com互操作将变量数组传递给C#吗?,c#,vba,com-interop,C#,Vba,Com Interop,我尝试在Excel和C#之间传输一些数据。为此,我编写了一个简单的C#类,其中包含一个属性来设置和获取数据 [Guid("xxx")] [ClassInterface(ClassInterfaceType.AutoDual)] [ComVisible(true)] public class Vector { private object[,] _values; public object[,] ExcelValues { get { ... }
[Guid("xxx")]
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComVisible(true)]
public class Vector
{
private object[,] _values;
public object[,] ExcelValues
{
get { ... }
set { ... }
}
}
在VBA中获取ExcelValues属性效果很好,但无法在VBA中设置它。如果尝试设置属性,则VBA代码不会编译:
Dim values As Variant
With myRange
' typo: Set values = Range(.Offset(0, 0), .Offset(100, 0))
values = Range(.Offset(0, 0), .Offset(100, 0))
End With
Dim data As New Vector
' this doesn't compile
data.ExcelValues = values
' this works
values = data.ExcelValues
有没有什么建议可以让我完成这项工作,而不必每次从变量数组中设置一个值 通过使用Set,您告诉VBA“值”是一个对象(在本例中是一个范围),但在将其指定给值时,您没有使用Set。读取值时,请尝试删除集合
With myRange
values = Range(.Offset(0, 0), .Offset(100, 0)).Value
End With
我根据发布的代码找到了一个解决方案。变量数组必须作为对象(而不是对象[,])从VBA传递到C。然后可以使用反射将其转换为更方便的内容:
[Guid("xxx")]
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDual)]
public class Vector
{
[ComVisible(false)]
public IList<double> Values { get; set; }
public object[,] GetExcelValues()
{
// own extension method
return Values.ConvertToExcelColumn();
}
public void SetExcelValues(object comArray)
{
IEnumerable<object> values = ConvertExcelCloumnToEnumerable(comArray);
Values = new List<double>(values.Select(Convert.ToDouble));
}
private static IEnumerable<object> ConvertExcelCloumnToEnumerable(object comObject)
{
Type comObjectType = comObject.GetType();
if (comObjectType != typeof(object[,]))
return new object[0];
int count = (int)comObjectType.InvokeMember("Length", BindingFlags.GetProperty, null, comObject, null);
var result = new List<object>(count);
var indexArgs = new object[2];
for (int i = 1; i <= count; i++)
{
indexArgs[0] = i;
indexArgs[1] = 1;
object valueAtIndex = comObjectType.InvokeMember("GetValue", BindingFlags.InvokeMethod, null, comObject, indexArgs);
result.Add(valueAtIndex);
}
return result;
}
}
[Guid(“xxx”)]
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDual)]
公共类向量
{
[ComVisible(false)]
公共IList值{get;set;}
公共对象[,]GetExcelValues()
{
//自身扩展方法
返回值。ConvertToExcelColumn();
}
public void SetExcelValues(对象comArray)
{
IEnumerable values=ConvertExcelCloumnToEnumerable(comArray);
Values=新列表(Values.Select(Convert.ToDouble));
}
私有静态IEnumerable ConvertExcelCloumnToEnumerable(对象comObject)
{
类型comObjectType=comObject.GetType();
if(comObjectType!=typeof(对象[,]))
返回新对象[0];
int count=(int)comObjectType.InvokeMember(“长度”,BindingFlags.GetProperty,null,comObject,null);
var结果=新列表(计数);
var indexArgs=新对象[2];
对于(inti=1;i),你是对的。这是一个打字错误,但不是问题的解决方案。