C# COM 可視クラスの作成は非常に簡単で、(コメントで述べたように) 楽しいものです。ここに小さなサンプルがあります。
新しい C# ライブラリ プロジェクトで、以下を追加します。
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace CSharpCom
{
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
//The 3 GUIDs in this file need to be unique for your COM object.
//Generate new ones using Tools->Create GUID in VS2010
[Guid("18C66A75-5CA4-4555-991D-7115DB857F7A")]
public interface ICSharpCom
{
string Format(string FormatString, [Optional]object arg0, [Optional]object arg1, [Optional]object arg2, [Optional]object arg3);
void ShowMessageBox(string SomeText);
}
//TODO: Change me!
[Guid("5D338F6F-A028-41CA-9054-18752D14B1BB")] //Change this
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
interface ICSharpComEvents
{
//Add event definitions here. Add [DispId(1..n)] attributes
//before each event declaration.
}
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[ComSourceInterfaces(typeof(ICSharpComEvents))]
//TODO: Change me!
[Guid("C17C5EAD-AA14-464E-AD32-E9521AC17134")]
public sealed class CSharpCom : ICSharpCom
{
public string Format(string FormatString, [Optional]object arg0, [Optional]object arg1, [Optional]object arg2, [Optional]object arg3)
{
return string.Format(FormatString, arg0, arg1, arg2, arg3);
}
public void ShowMessageBox(string SomeText)
{
MessageBox.Show(SomeText);
}
}
}
プロジェクトのプロパティの [署名] タブに移動し、ボックスをオンにしてアセンブリに署名し、新しい「厳密な名前のキー ファイル」を作成します。これにより、登録済み DLL のバージョン管理の問題を防ぐことができます。
regasm
それをコンパイルし、Visual Studio コマンド プロンプトで使用して DLL を登録します。使用している Office のバージョンに応じて、32 ビットまたは 64 ビットの regasm を使用します...C:\windows\Microsoft.NET\Framework
またはC:\windows\Microsoft.NET\Framework64
(それぞれ 32 ビットと 64 ビット) にRegAsm があります。
C:\windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe /codebase /tlb CSharpCom.dll
これにより、DLL が Windows に登録されるため、VBA エディターで [ツール] > [参照] に移動し、COM の名前空間 "CSharpCom" を見つけることができるはずです。そのボックスをオンにすると、VBA で COM オブジェクトを作成できるようになります。
Sub TestCom()
Dim c As CSharpCom.CSharpCom
Set c = New CSharpCom.CSharpCom
c.ShowMessageBox c.Format("{0} {1}!", "Hello", "World")
End Sub
フォームを COM オブジェクトに追加し、VBA が特定のメソッドを呼び出したときにフォームを開くことができます。これを使用して、進行状況バーのあるフォームを作成できるはずです。ただし、VBA はシングル スレッドであることを考慮する必要があります。これは、コードの実行中に他のすべてがフリーズすることを意味するため、少し複雑になる可能性があります。
私の頭の上から、COM 可視クラスに 3 つのメソッドを作成できます。1 つはフォームを開き、もう 1 つは進行状況を更新します (VBA が COM オブジェクトの update() メソッドを呼び出した直後に VBA の DoEvents() メソッドを呼び出します)。 、Office が画面の更新を処理できるようにするため)、および 1 つを閉じます。フォームで Dispose() を呼び出す必要があります。これは「close」メソッドで実行できますが、VBA がクラッシュし、close メソッドが呼び出されない場合、メモリ リークや問題が発生する可能性があると思います。