.NET 8 DLLをVBAから型付きで使う方法 - COM公開とdscom TLB

· 更新日: · · C#, .NET 8, VBA, COM, Office, dscom

更新履歴(3件・最終更新 2026年08月02日)

この記事に加えた変更の記録です。アーカイブした更新前のバージョンは、DOI付きの固定URLから読めます。

記事の冒頭に「この記事の知識マップ」節を追加しました。本文で扱っている概念とその関係を、要約・図・詳細ページへのリンクにまとめたものです。本文の主張は変えていません。
外部レビュー(1283件)への対応として本文を更新しました。個々の変更内容は、この下の履歴を参照してください。
dscomが何かと、32bit用の`dscom32.exe`の入手方法を新設しました(`dotnet tool`版では64bitのTLBしか作れません)。VBAでの実行結果の期待値と`Err.Number`の読み方、.NET例外とHRESULTの対応表、参照設定の具体的な操作手順、登録解除の手順、.NETランタイムの入手案内を追加し、冒頭に必要な環境の表を置きました。
初版公開
この記事を引用する(DOI: 10.5281/zenodo.21589668)

この記事はZenodoにアーカイブされています。常に最新版へ解決されるDOIと、いま表示している版に固定されたDOIの両方を下に示します。

小村 豪(2026)「.NET 8 DLLをVBAから型付きで使う方法 - COM公開とdscom TLB」合同会社小村ソフト. https://doi.org/10.5281/zenodo.21589668 https://staging.comcomponent.com/blog/2026/03/16/007-dotnet8-dll-typed-vba-com-dscom-tlb/

DOI(最新版)
10.5281/zenodo.21589668
DOI(この版)
10.5281/zenodo.21732695

VBA から .NET 8 の処理を呼びたい場面はまだ普通にあります。特に、Excel や Access の既存資産はそのまま残しつつ、重い処理、文字列処理、HTTP、暗号、業務ロジックのような部分だけを C# に逃がしたいときです。

ただ、CreateObject で遅延バインディングに寄せると、VBA 側では Object だらけになります。IntelliSense は弱くなり、メソッド名の打ち間違いは実行時まで見つからず、だんだん文字列頼みのぬかるみに沈みます。

そこで今回は、.NET 8 の DLL を COM 公開し、dscom でタイプライブラリ(TLB)を生成し、VBA から早期バインディングで型付き利用するところに絞って整理します。

.NET Framework + RegAsm の昔話、IDL を手書きして MIDL で固める話、Reg-Free COM の話は今回は横に置きます。ここでは、.NET 8 / COM host / dscom / VBA early binding の一本道だけを扱います。

なお、この記事に登場するコードは、ビルド・検証できるサンプル一式(COM 公開ライブラリ、TLB 生成・登録スクリプト、VBA モジュール、ユニットテスト)として GitHub で公開しています。

dotnet8-dll-typed-vba-com-dscom-tlb - komurasoft-blog-samples (GitHub)

必要な環境

項目 必要なもの
OS Windows。COM 登録を行うので、regsvr32 を管理者権限で実行できること
.NET SDK .NET 8 SDK。EnableComHosting は .NET 5 以降の機能です
Office Excel または Access。32bit 版か 64bit 版かを先に確認します(3 章)
TLB 生成ツール dscom。64bit 用と 32bit 用で入手方法が違います(6 章)
クライアント PC Office と同じ bitness の .NET 8 ランタイム(9 章)

手順に入る前に、自分の環境の版を控えておくことを強く勧めます。あとで「同じ手順なのに動かない」となったとき、比較できる情報がここにしかないからです。

# .NET SDK とランタイムの一覧(x64 / x86 のどちらが入っているかも分かります)
dotnet --info

# Windows のビルド番号
winver

Office の版とビットは、Excel の ファイル > アカウント > Excel のバージョン情報 で確認できます。ダイアログのタイトル行の末尾に 32 ビット または 64 ビット と出ます。

1. まず結論

先に結論だけ並べると、流れはこうです。

  • .NET 8 のクラスライブラリを EnableComHosting=true でビルドする
  • COM に見せる 明示的なインターフェイスクラス を作る
  • クラスは ClassInterfaceType.None にして、AutoDual に逃げない
  • VBA から使うインターフェイスは InterfaceIsDual にする
  • ビルド後にできた *.dll から、dscom tlbexport*.tlb を作る
  • regsvr32*.comhost.dll を登録する
  • dscom tlbregister*.tlb を登録する
  • VBA で参照設定を追加し、Dim x As ライブラリ名.IYourInterface のように型付きで使う

要するに、COM の入口は .NET SDK が作る *.comhost.dll、型情報は dscom が作る *.tlb、VBA はその TLB を見て早期バインディングする、という構成です。

この記事の知識マップ

.NET 8のクラスライブラリをVBAから型付きで利用するには、COMの型情報であるタイプライブラリが不可欠で、これはdscomというツールが.NET Frameworkで廃止されたtlbexp.exeやRegAsm.exeの後継として生成・登録します。.NET側はEnableComHostingでビルドしたCOM hostをCOMの起動入口とし、regsvr32での登録とOfficeとのbitness一致が前提になります。VBA側はタイプライブラリを参照設定で読み込むことで早期バインディングが使え、CreateObjectによる遅延バインディングより型安全に使えます。公開後の互換性はIIDやCLSIDの扱いとClassInterfaceTypeの選び方に左右され、ClassInterfaceType.NoneとInterfaceIsDual、DispIdの組み合わせがVBA参照の破損を避ける定石です。

「.NET 8のDLLをVBAから型付きで使う方法の知識マップ」VBAが早期バインディングでCOMを型付きに使うにはタイプライブラリが必要で、dscomがそのTLB生成と登録を担い、.NET 8側はCOM hostとして公開されること、ClassInterfaceTypeやIID・CLSIDの扱いがVBA参照の互換性にどう影響するかを示す図前提とする前提とする利用する利用する用いるのは非推奨実装を担うの後継で構成できるで構成できる前提とする実装を担う利用する前提とする前提とする原因になり得る原因になり得る原因になり得る用いるのは非推奨推奨される対応軽減する推奨される対応利用するで確認できるで構成できる前提とする前提とする前提とするVBA(Visual Basic for Applications)dscom型ライブラリ(TLB)早期バインディング(VBA)遅延バインディング(CreateObject)tlbexp.exe / RegAsm.exeCOM host(*.comhost.dll)regsvr32.NET(Core以降)COM(コンポーネントオブジェクトモデル)IID(インターフェース識別子)CLSID(Class ID)VBA参照・登録の破損ClassInterfaceType.AutoDualClassInterfaceType.NoneDispIdAttributeInterfaceIsDual(デュアルインターフェイス)HRESULT.NET例外ComVisibleAttributebitness一致要件

図の実線は常に成り立つ関係、破線は条件付きの関係です(成立条件は詳細ページの各関係の説明に記載)。関係すべての一覧(全27件、根拠・確度つき)と主要概念の定義は知識マップ詳細ページにまとめています。データ: JSON-LD / Turtle

2. この構成の全体像

まず、何が何の役目なのかを 1 枚で見ます。

参照設定した TLB で型情報取得COM 呼び出しVBA / Excel / AccessVbaTypedComSample.tlbVbaTypedComSample.comhost.dllVbaTypedComSample.dll (.NET 8).NET 8 Runtime

それぞれの役割はこうです。

ファイル 役割
VbaTypedComSample.dll .NET 8 の実装本体
VbaTypedComSample.comhost.dll COM から呼ばれる入口
VbaTypedComSample.tlb VBA が見る型情報
VbaTypedComSample.deps.json 依存関係の解決情報
VbaTypedComSample.runtimeconfig.json .NET ランタイム起動情報

ここで大事なのは、VBA が型を知るために必要なのは TLB で、COM の起動入口として必要なのは comhost だという点です。

.dll 単体を渡して終わり、とはいかないあたりが、COM の世界の素直でないところです。

3. 最初に決めること - 32bit / 64bit を揃える

ここを外すと、かなりの確率で ActiveX コンポーネントはオブジェクトを作成できません。 方面へ転がります。

Office / VBA と COM サーバーの bitness は揃えてください。

利用側 .NET 側の目安 TLB 生成 登録コマンド
64bit Office x64 / win-x64 dscom C:\Windows\System32\regsvr32.exe
32bit Office(64bit Windows 上) x86 / win-x86 dscom32.exe C:\Windows\SysWOW64\regsvr32.exe

.NET 5+ 以降の COM host では、AnyCPU のままにすると *.comhost.dll が 64bit 側に寄りやすく、32bit Office と噛み合わないことがあります。なので、Office に合わせて x86 / x64 を明示したほうが安全です。

この記事のコードは 64bit Office 向けを例にします。32bit Office なら、後で出てくる x64x86win-x64win-x86 に読み替えてください。

4. .NET 8 側を作る

ここでは、VBA から AddDivideHello を呼べる最小サンプルにします。

4.1 .csproj

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net8.0-windows</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <EnableComHosting>true</EnableComHosting>
    <PlatformTarget>x64</PlatformTarget>
    <NETCoreSdkRuntimeIdentifier>win-x64</NETCoreSdkRuntimeIdentifier>
  </PropertyGroup>
</Project>

ポイントは EnableComHosting です。これを付けると、ビルド時に VbaTypedComSample.comhost.dll が生成されます。

4.2 アセンブリ全体はデフォルトで COM 非公開にしておく

COM に見せる型だけ ComVisible(true) にしたいので、アセンブリ全体は false にしておくのが楽です。

using System.Runtime.InteropServices;

[assembly: ComVisible(false)]

4.3 公開するインターフェイスとクラスを書く

using System.Runtime.InteropServices;

namespace VbaTypedComSample;

[ComVisible(true)]
[Guid("2A1BBEDE-DE6E-4C34-AD60-2E9E0E33E999")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface ICalculator
{
    [DispId(1)]
    int Add(int x, int y);

    [DispId(2)]
    double Divide(double x, double y);

    [DispId(3)]
    string Hello(string name);
}

[ComVisible(true)]
[Guid("FAD1C752-0BB6-4DDD-889F-FE446350847A")]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(ICalculator))]
public class Calculator : ICalculator
{
    public Calculator()
    {
    }

    public int Add(int x, int y) => checked(x + y);

    public double Divide(double x, double y)
    {
        if (y == 0)
        {
            throw new ArgumentOutOfRangeException(nameof(y), "0 では割れません。");
        }

        return x / y;
    }

    public string Hello(string name)
    {
        if (string.IsNullOrWhiteSpace(name))
        {
            return "Hello";
        }

        return $"Hello, {name}";
    }
}

このコードで押さえておきたいのは、以下の点です。

  • Guidインターフェイスクラスに別々に振る
  • ClassInterfaceType.None にして、自動生成クラスインターフェイスに依存しない
  • VBA で扱いやすいように InterfaceIsDual にする
  • DispId を振っておくと、公開後にメソッド順をいじったときの事故を減らしやすい
  • COM から New されるので、public な引数なしコンストラクターを用意する

5. ビルドする

Release ビルドします。

dotnet build -c Release

ビルド後、出力フォルダには少なくとも次のようなファイルが並びます。

bin/
  Release/
    net8.0-windows/
      VbaTypedComSample.dll
      VbaTypedComSample.comhost.dll
      VbaTypedComSample.deps.json
      VbaTypedComSample.runtimeconfig.json

配布や登録で使うのはこのフォルダです。あとで配置場所を変えるなら、登録もやり直しになります。

6. dscom で TLB を生成する

6.1 dscom とは何か

dscom は、.NET アセンブリから COM のタイプライブラリ(TLB)を生成・登録するためのオープンソースのコマンドラインツールです。dSPACE 社が公開しており、ライセンスは Apache-2.0 です。

なぜ必要かというと、.NET 5 以降では tlbexp.exeRegAsm.exe が廃止されたからです。.NET Framework の時代はこの 2 つで TLB 生成とアセンブリ登録ができましたが、.NET 5+ にはその後継が標準で入っていません。dscom は、その穴を埋めるために作られたツールです。

主なサブコマンドはこれだけ覚えておけば足ります。

サブコマンド 役割
tlbexport アセンブリから TLB を書き出す
tlbregister TLB をシステムへ登録する
tlbunregister TLB の登録を解除する
tlbdump TLB の中身を出力して確認する
tlbembed TLB をファイルへ埋め込む

tlbdump は、生成した TLB に意図した型が入っているかを、VBA を開く前に確認するのに便利です。

6.2 64bit の場合

64bit の TLB を作るだけなら、dotnet tool で入ります。

dotnet tool install --global dscom

次に、ビルドしたアセンブリから TLB を生成します。

dscom tlbexport .\bin\Release\net8.0-windows\VbaTypedComSample.dll --out .\bin\Release\net8.0-windows\VbaTypedComSample.tlb

6.3 32bit Office 向けの場合 - dscom32.exe をどこから入手するか

ここが 32bit Office 対応で一番詰まるところです。

dotnet tool install で入る dscom は、AnyCPU または 64bit のアセンブリしか扱えず、生成できるのは 64bit の TLB だけです。 32bit の TLB を作るには、別の実行ファイルである dscom32.exe が必要で、これは NuGet ではなく GitHub のリリースページからダウンロードします。

ダウンロードした dscom32.exe は、この記事の例ではプロジェクト直下の tools フォルダーへ置いています。置き場所は自由ですが、ビルド出力と一緒に配布しないようにしてください。開発時のツールであって、実行時には不要です。

もう 1 つ、見落としやすい前提があります。dscom32.exe を動かすには、x86 版の .NET ランタイムが入っている必要があります。 dscom が hostfxr.dll を読み込む都合によるもので、x64 版しか入っていない環境では動きません。dotnet --info の出力にある一覧で、x86 のランタイムがあるか確認してください。

.\tools\dscom32.exe tlbexport .\bin\Release\net8.0-windows\VbaTypedComSample.dll --out .\bin\Release\net8.0-windows\VbaTypedComSample.tlb

なお、dscom 側のドキュメントでも、AnyCPU のままにすると *.comhost.dll が 64bit として生成されるため、32bit で使うならアセンブリ自体を 32bit でコンパイルすることが推奨されています。3 章の話と同じ結論です。

ビルドのたびに手で叩くのが面倒なら、dSPACE.Runtime.InteropServices.BuildTasks パッケージを入れると、コンパイル時に TLB を自動生成できます。

7. COM host と TLB を登録する

ここは 管理者権限のコマンドプロンプト / PowerShellで実行してください。

7.1 64bit Office / 64bit COM の場合

$out = Resolve-Path .\bin\Release\net8.0-windows

C:\Windows\System32\regsvr32.exe "$out\VbaTypedComSample.comhost.dll"
dscom tlbregister "$out\VbaTypedComSample.tlb"

7.2 32bit Office(64bit Windows 上)の場合

$out = Resolve-Path .\bin\Release\net8.0-windows

C:\Windows\SysWOW64\regsvr32.exe "$out\VbaTypedComSample.comhost.dll"
.\tools\dscom32.exe tlbregister "$out\VbaTypedComSample.tlb"

ここでやっていることは 2 つです。

  • regsvr32*.comhost.dll を COM サーバーとして登録する
  • tlbregister*.tlb をタイプライブラリとして登録する

8. VBA で参照設定して、型付きで使う

  1. Excel または Access を開く
  2. Alt + F11 で VBA エディタ(VBE)を開く。リボンから開くなら 開発 タブ > Visual Basic です。開発 タブが出ていない場合は、ファイル > オプション > リボンのユーザー設定開発 にチェックを入れます
  3. VBE のメニューで ツール > 参照設定
  4. 参照可能なライブラリ ファイル の一覧はアルファベット順に並びます。登録が成功していれば、その中にライブラリ名(既定ではアセンブリ名と同じ VbaTypedComSample)が出るので、左のチェックボックスを入れて OK
  5. 一覧に見えなければ 参照... ボタンから VbaTypedComSample.tlb を直接選ぶ

一覧に出てこない場合、原因はたいてい 3 章の bitness 不一致か、7 章の tlbregister が通っていないかのどちらかです。32bit Office からは 64bit で登録した TLB は見えません。

参照設定が入ったかどうかは、表示 > オブジェクト ブラウザーF2)を開き、左上のライブラリ選択で VbaTypedComSample を選べるかで確認できます。ここで ICalculatorCalculator、そして Add / Divide / Hello が見えていれば、TLB は正しく作れています。

Option Explicit

Public Sub UseCalculator()
    Dim calc As VbaTypedComSample.ICalculator
    Set calc = New VbaTypedComSample.Calculator

    Debug.Print calc.Add(10, 20)
    Debug.Print calc.Divide(10, 4)
    Debug.Print calc.Hello("VBA")
End Sub

このプロシージャにカーソルを置いて F5 で実行し、Ctrl + G でイミディエイト ウィンドウを開くと、4 章の実装どおりに 3 行が出ます。

30
2.5
Hello, VBA

ここが期待どおりなら、参照設定・COM 登録・ランタイム起動・引数と戻り値のマーシャリングまで全部通っています。逆に、ここで値が合わないなら .NET 側の実装を、そもそも実行できないなら 3 章と 7 章を疑ってください。

これで、VBA 側にはこんな恩恵があります。

  • IntelliSense が効く
  • メソッド名の typo が実行前に見つけやすい
  • Object Browser で公開 API を確認できる
  • Object ベタ書きより読みやすい

8.1 例外は VBA 側では COM エラーになる

たとえば Divide(10, 0) のように .NET 側で例外が投げられると、VBA 側では COM エラーとして見えます。

Option Explicit

Public Sub UseCalculatorWithErrorHandling()
    On Error GoTo EH

    Dim calc As VbaTypedComSample.ICalculator
    Set calc = New VbaTypedComSample.Calculator

    Debug.Print calc.Divide(10, 0)
    Exit Sub

EH:
    Debug.Print Err.Number
    Debug.Print Hex$(Err.Number)
    Debug.Print Err.Description
End Sub

ここで出る値の読み方を押さえておくと、切り分けが速くなります。

項目 何が入るか
Err.Number .NET の例外に対応する HRESULT が、符号付き Long として入ります。10 進のままでは読みにくいので Hex$(Err.Number) で 16 進に直します
Err.Description COM の IErrorInfo 経由で、.NET の例外メッセージがそのまま入ります。上のコードなら 0 では割れません。 を含む文字列です

HRESULT の値は例外の型ごとに決まっています。ArgumentOutOfRangeException に対応するのは COR_E_ARGUMENTOUTOFRANGE、値は 0x80131502 です。つまり Hex$(Err.Number)80131502 になっていれば、想定どおり .NET 側の ArgumentOutOfRangeException が届いていることになります。

主なものを並べると、こうです。

.NET の例外 HRESULT 定数
ArgumentException COR_E_ARGUMENT 0x80070057
ArgumentOutOfRangeException COR_E_ARGUMENTOUTOFRANGE 0x80131502
InvalidOperationException COR_E_INVALIDOPERATION 0x80131509
NotSupportedException COR_E_NOTSUPPORTED 0x80131515
上記以外の一般的な例外 COR_E_EXCEPTION 0x80131500

VBA 側で例外の種類ごとに処理を分けたいなら、この HRESULT で分岐することになります。ただし、HRESULT で分岐する設計は .NET 側の例外型の変更に弱いので、業務的な失敗は例外ではなく戻り値やエラーコードで返すほうが、境界としては安定します。

9. 配布するときの考え方

配布時に大事なのは、DLL 単体を配るのではなく、出力一式を置くことです。

VbaTypedComSample.dll
VbaTypedComSample.comhost.dll
VbaTypedComSample.deps.json
VbaTypedComSample.runtimeconfig.json
VbaTypedComSample.tlb
(必要なら依存 DLL 一式)

さらに、クライアント PC には 対応する .NET 8 ランタイムが必要です。COM host は self-contained 配布ではなく、基本的に framework-dependent な運用になります。

入れるものは具体的にはこうです。

  • 配布ページは .NET 8 のダウンロードです
  • 必要なのは SDK ではなく ランタイムです。この記事のサンプルは画面を持たないクラスライブラリなので、.NET Runtime で足ります。WPF や Windows フォームの型を使う場合は .NET Desktop Runtime が必要です
  • bitness は Office に合わせます。 64bit Office なら x64、32bit Office なら x86 のランタイムです。3 章で x64 / x86 を明示したのと同じ理由で、ここも合っていないと起動しません
  • 導入済みかどうかは、クライアント PC で dotnet --list-runtimes を実行して Microsoft.NETCore.App 8.x の行があるか見ると分かります

配布資料には、この「必要なランタイムの種類・バージョン・bitness」を必ず書いておいてください。導入手順に書き忘れると、現地で ActiveX コンポーネントはオブジェクトを作成できません。 を見て bitness を疑い、時間を溶かします。

10. はまりどころ

10.1 AnyCPU のまま放置しない

VBA / Office の bitness と COM host の bitness がズレると、かなり気持ち悪い失敗のしかたをします。

  • 64bit Office なら x64 / win-x64
  • 32bit Office なら x86 / win-x86

10.2 ClassInterfaceType.AutoDual を使わない

一見ラクですが、公開後にメンバー順や構成を触ると壊しやすいです。

VBA から型付きで安定して使いたいなら、明示インターフェイスを定義し、クラスは ClassInterfaceType.Noneにしておくのが定石です。

10.3 GUID を軽率に再生成しない

COM では GUID が契約そのものです。IID や CLSID を公開後に軽率に入れ替えると、既存の VBA 参照や登録が壊れます。

10.4 公開済みインターフェイスを壊さない

COM は「後から 1 個メソッド足しただけ」でも平和に済まないことがあります。

  • ICalculator は残す
  • 変更が大きいなら ICalculator2 を新設する
  • クラスは両方実装してもよい

10.5 型は地味に寄せる

VBA に見せる境界では、あまり格好をつけないほうが安全です。

相性が良いのは、まずはこのへんです。

  • int
  • double
  • bool
  • string
  • DateTime
  • decimal
  • enum

10.6 Office を開いたまま更新しない

Excel や Access が DLL を掴んだままになり、ビルドや再登録で面倒が起きることがあります。

  • Office を閉じる
  • 必要なら登録解除する
  • ビルドし直す
  • もう一度登録する

登録解除は、登録したときと逆の順序で、登録に使ったのと同じ bitness のコマンドで行います。管理者権限が必要なのも登録時と同じです。

# 64bit Office / 64bit COM の場合
$out = Resolve-Path .\bin\Release\net8.0-windows

dscom tlbunregister "$out\VbaTypedComSample.tlb"
C:\Windows\System32\regsvr32.exe /u "$out\VbaTypedComSample.comhost.dll"
# 32bit Office(64bit Windows 上)の場合
$out = Resolve-Path .\bin\Release\net8.0-windows

.\tools\dscom32.exe tlbunregister "$out\VbaTypedComSample.tlb"
C:\Windows\SysWOW64\regsvr32.exe /u "$out\VbaTypedComSample.comhost.dll"

regsvr32/u が登録解除のオプションです。登録時と違う regsvr32 を使うと解除できません(64bit で登録したものを SysWOW64regsvr32 では外せません)。フォルダーごと移動・削除する前に解除しておかないと、レジストリに存在しないパスの登録が残ります。

11. まとめ

.NET 8 の DLL を型付きで VBA から使うという話は、COM 公開 + dscom で TLB 生成に絞ってしまえば、それほど怖い手順ではありません。.NET 8 側は EnableComHosting=true にして明示インターフェイス(クラスは ClassInterfaceType.None、VBA 向けは InterfaceIsDual)を用意し、dscom tlbexport で TLB を作り、regsvr32*.comhost.dll を、dscom tlbregister*.tlb を登録する。あとは VBA で参照設定を入れて早期バインディングするだけです。

迷ったときは、COM host と TLB を分けて考えるのがコツです。

  • 起動入口は *.comhost.dll
  • 型情報は *.tlb
  • 実装本体は *.dll

12. 参考資料

同じタグを共有する最新の記事です。さらに近い話題で知識を深められます。

このテーマと近いトピックページです。記事を起点に、関連するサービスや他の記事へ進めます。

この記事は次のサービスページにつながります。近い入口からご覧ください。

よくある質問

この記事のテーマについて、相談時によくある質問をまとめています。

.NET 8のDLLをVBAから型付き(早期バインディング)で使うには何が必要ですか?
.NET 8のクラスライブラリをEnableComHosting=trueでビルドして*.comhost.dllを生成し、dscom tlbexportで*.tlbを作ります。次にregsvr32で*.comhost.dllを、dscom tlbregisterで*.tlbを登録し、VBAの参照設定でそのTLBを追加すれば、Dim x As ライブラリ名.IYourInterfaceの形で型付きに使えます。役割分担としては、COMの起動入口が*.comhost.dll、VBAが見る型情報が*.tlb、実装本体が*.dllです。
「ActiveX コンポーネントはオブジェクトを作成できません」と出る原因は何ですか?
典型的な原因はOffice/VBAとCOMサーバーのbitness不一致です。64bit Officeならx64/win-x64でビルドしてSystem32のregsvr32で登録し、32bit Office(64bit Windows上)ならx86/win-x86でビルドしてSysWOW64のregsvr32で登録、TLB生成もdscom32.exeを使います。.NET 5+のCOM hostではAnyCPUのままにすると*.comhost.dllが64bit側に寄りやすく、32bit Officeと噛み合わないことがあるため、Officeに合わせてx86/x64を明示するのが安全です。
ClassInterfaceType.AutoDualを使ってはいけないのですか?
一見ラクですが、公開後にメンバー順や構成を触ると壊しやすいため避けるべきです。VBAから型付きで安定して使いたいなら、明示的なインターフェイスを定義してクラスはClassInterfaceType.Noneにし、VBAから使うインターフェイスはInterfaceIsDualにするのが定石です。DispIdを振っておくとメソッド順変更時の事故を減らせます。またCOMではGUIDが契約そのものなので、IIDやCLSIDを公開後に軽率に再生成すると既存のVBA参照や登録が壊れます。
配布するときはDLL単体を渡せばよいですか?
DLL単体では動きません。実装本体の*.dll、*.comhost.dll、*.deps.json、*.runtimeconfig.json、*.tlb、必要なら依存DLL一式をまとめて配置します。さらにクライアントPCには対応する.NET 8ランタイムが必要で、COM hostはself-contained配布ではなく基本的にframework-dependentな運用になります。配置場所をあとで変えるなら登録もやり直しになる点にも注意が必要です。

著者プロフィール

記事の著者プロフィールページです。

小村 豪

合同会社小村ソフト 代表

Windows ソフト開発、技術相談、不具合調査を中心に、既存資産が残る案件や原因が見えにくい障害調査に強みがあります。

ブログ一覧に戻る