我在 Excel/VBA 中使用 .NET/ComVisible 程序集时遇到问题。我在 .NET 中将几个参数定义为“对象”,因此它们将在 VBA 中转换为 Variant,因为 VBA 中的可选参数需要使用 Variant 类型。
问题是当我尝试在 Excel/VBA 中使用该对象时,我收到“运行时错误'424':需要对象”。我认为我在 C# 界面中缺少属性,该属性将添加一个“ propput ”方法而不是“ propputref ”方法,该方法将允许变量中的值,但我在互联网上没有找到任何答案,只是类似的问题。我看到了 System.Reflection.BindingFlags,但这似乎只适用于编译时和运行时代码,不适用于接口定义。
底层数据类型是双精度的,我需要它为空或通过 COM/VBA 的双精度。我对字符串参数没有问题,只是变体/双精度。
这是C#接口:
[ComVisible(true)]
[Guid("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface ISampleParameters
{
object GrossObservedValue { get; set; }
string TableName { get; set; }
// Rest of parameters removed for simplicity
}
这是 C# 对象:
[ComVisible(true)]
[Guid("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")]
[ClassInterface(ClassInterfaceType.None)]
public class SampleParameters : ISampleParameters
{
private double? grossObservedValue;
private string tableName;
public object GrossObservedValue
{
get
{
return grossObservedValue;
}
set
{
try
{
if (value == null)
grossObservedValue = null;
else
grossObservedValue = Convert.ToDouble(value);
}
catch
{
throw;
}
}
}
}
这是VBA的用法:
Dim Parameters As New SampleParameters
Parameters.GrossObservedValue = 1.23
' Causes: Run-time error '424': Object required
这是来自 OleView 的类型库 IDL:
[
odl,
uuid(XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX),
version(1.0),
dual,
oleautomation,
custom(XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX, TempNamespace.ISampleParameters)
]
interface ISampleParameters : IDispatch {
[id(0x60020000), propget]
HRESULT GrossObservedValue([out, retval] VARIANT* pRetVal);
[id(0x60020000), propputref]
HRESULT GrossObservedValue([in] VARIANT pRetVal);
[id(0x60020001), propget]
HRESULT TableName([out, retval] BSTR* pRetVal);
[id(0x60020001), propput]
HRESULT TableName([in] BSTR pRetVal);
};
似乎唯一的解决方案是手动生成 IDL,然后将其导入 .NET,就像在这个线程中使用 VB.NET 和 VB6一样。那是唯一的解决方案吗?这篇关于The Essentials for Using COM in Managed Code的文章也非常好,但没有涵盖在 .NET/C# 中定义接口。