Excel/VBAで.NET/ComVisibleアセンブリを使用すると問題が発生します。.NETでいくつかのパラメーターを「オブジェクト」として定義したので、VBAのオプションのパラメーターはVariantタイプを使用する必要があるため、それらはVBAのVariantに変換されます。
問題は、Excel / VBAでオブジェクトを使用しようとすると、「実行時エラー '424':オブジェクトが必要です」というメッセージが表示されることです。バリアントの値を許可する「 propputref」メソッドの代わりに「propput 」メソッドを追加するC#インターフェイスの属性が欠落していると思いますが、インターネット上で同様の質問に対する回答は見つかりませんでした。System.Reflection.BindingFlagsが表示されますが、これはコンパイル時とランタイムコードでのみ機能し、インターフェイス定義では機能しないようです。
基になるデータ型はdoubleであり、COM/VBAを介してnullまたはdoubleにする必要があります。文字列パラメータに問題はなく、variant/doubleだけです。
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を手動で生成し、VB6でVB.NETを使用して、このスレッドのように.NETにインポートして戻すことです。それが唯一の解決策ですか?マネージコードでCOMを使用するための基本事項に関するこの記事も非常に優れていましたが、.NET / C#でのインターフェイスの定義については説明していませんでした。