次の方法で共有


VBA とドキュメント レベルのカスタマイズを組み合わせる

Microsoft Office Word または Microsoft Office Excel のドキュメント レベルのカスタマイズの一部であるドキュメントでは、Visual Basic for Applications (VBA) コードを使用できます。 カスタマイズ アセンブリからドキュメント内の VBA コードを呼び出すか、ドキュメント内の VBA コードがカスタマイズ アセンブリ内のコードを呼び出せるようにプロジェクトを構成できます。

適用対象: このトピックの情報は、Excel および Word のドキュメント レベルのプロジェクトに適用されます。 詳細については、「 Office アプリケーションとプロジェクトの種類で使用できる機能」を参照してください。

ドキュメント レベルのカスタマイズでの VBA コードの動作

Visual Studio でプロジェクトを開くと、ドキュメントはデザイン モードで開かれます。 VBA コードは、ドキュメントがデザイン モードのときに実行されないため、VBA コードを実行せずにドキュメントとコードを操作できます。

ソリューションを実行すると、VBA とカスタマイズ アセンブリの両方のイベント ハンドラーによって、ドキュメントで発生したイベントが取得され、両方のコード セットが実行されます。 どのコードを他のコードより前に実行するかを事前に判断することはできません。これは、個々のケースでのテストを通じて決定する必要があります。 2 つのコード セットが慎重に調整およびテストされていない場合は、予期しない結果が得られます。

カスタマイズ アセンブリから VBA コードを呼び出す

Word 文書でマクロを呼び出したり、Excel ブックでマクロや関数を呼び出したりできます。 これを行うには、以下のいずれかの方法を使用します。

  • Word の場合は、Run クラスのApplication メソッドを呼び出します。

  • Excel の場合は、Run クラスのApplication メソッドを呼び出します。

    メソッドごとに、最初のパラメーターは呼び出すマクロまたは関数の名前を識別し、残りの省略可能なパラメーターはマクロまたは関数に渡すパラメーターを指定します。 最初のパラメーターには、Word と Excel に異なる形式を指定できます。

  • Word の場合、最初のパラメーターは、テンプレート、モジュール、マクロ名を任意に組み合わせることができる文字列です。 ドキュメント名を指定した場合、コードでは、任意のドキュメント内のマクロだけでなく、現在のコンテキストに関連するドキュメントでのみマクロを実行できます。

  • Excel の場合、最初のパラメーターには、マクロ名を指定する文字列、関数の場所を示す Range 、または登録済み DLL (XLL) 関数のレジスタ ID を指定できます。 文字列を渡すと、作業中のシートのコンテキストで文字列が評価されます。

    次のコード例は、Excel のドキュメント レベルのプロジェクトから MyMacro という名前のマクロを呼び出す方法を示しています。 この例では、 MyMacroSheet1 で定義されていることを前提としています。

Globals.Sheet1.Application.Run("MyMacro", missing, missing, missing,
    missing, missing, missing, missing, missing, missing, missing,
    missing, missing, missing, missing, missing, missing, missing,
    missing, missing, missing, missing, missing, missing, missing,
    missing, missing, missing, missing, missing, missing);

Visual C# で省略可能なパラメーターの代わりにグローバル missing 変数を使用する方法については、「 Office ソリューションでのコードの記述」を参照してください。

VBA からドキュメント レベルのカスタマイズでコードを呼び出す

Word または Excel のドキュメント レベルのプロジェクトを構成して、ドキュメント内の Visual Basic for Applications (VBA) コードがカスタマイズ アセンブリ内のコードを呼び出すことができるようにすることができます。 これは次のような場合に便利です:

  • 同じドキュメントに関連付けられているドキュメント レベルのカスタマイズで機能を使用して、ドキュメント内の既存の VBA コードを拡張する場合。

  • ドキュメント レベルのカスタマイズで開発したサービスを、ドキュメント内の VBA コードを記述してサービスにアクセスできるエンド ユーザーが利用できるようにする必要があります。

    Visual Studio の Office 開発ツールは、VSTO アドインにも同様の機能を提供します。VSTO アドインを開発している場合は、他の Microsoft Office ソリューションから VSTO アドインのコードを呼び出すことができます。 詳細については、「 他の Office ソリューションから VSTO アドインのコードを呼び出す」を参照してください。

この機能は、Word テンプレート プロジェクトでは使用できません。 Word 文書、Excel ブック、または Excel テンプレート プロジェクトでのみ使用できます。

Requirements

VBA コードでカスタマイズ アセンブリを呼び出せるようにするには、プロジェクトが次の要件を満たしている必要があります。

  • ドキュメントには、次のいずれかのファイル名拡張子が必要です。

    • Word の場合: .docm または .doc

    • Excel の場合: .xlsm.xltm.xls、または .xlt

  • ドキュメントには、VBA コードを含む VBA プロジェクトが既に含まれている必要があります。

  • ドキュメント内の VBA コードは、マクロの有効化をユーザーに求めずに実行できるようにする必要があります。 Word または Excel のセキュリティ センター設定の信頼できる場所の一覧に Office プロジェクトの場所を追加することで、VBA コードを信頼して実行できます。

  • Office プロジェクトには、VBA に公開している 1 つ以上のパブリック メンバーを含むパブリック クラスが少なくとも 1 つ含まれている必要があります。

    メソッド、プロパティ、およびイベントを VBA に公開できます。 公開するクラスには、ホスト項目クラス (Word の ThisDocument 、Excel の ThisWorkbookSheet1 など) や、プロジェクトで定義する別のクラスを指定できます。 ホスト項目の詳細については、「 ホスト項目とホスト コントロールの概要」を参照してください。

VBA コードでカスタマイズ アセンブリを呼び出せるようにする

カスタマイズ アセンブリのメンバーをドキュメント内の VBA コードに公開するには、次の 2 つの方法があります。

  • Visual Basic プロジェクトのホスト項目クラスのメンバーを VBA に公開できます。 これを行うには、ホスト項目 (ドキュメント、ワークシート、またはブック) がデザイナーで開かれているときに、ホスト項目の EnableVbaCallersプロパティを [プロパティ] ウィンドウで True に設定します。 Visual Studio は、VBA コードがクラスのメンバーを呼び出せるようにするために必要なすべての作業を自動的に実行します。

  • Visual C# プロジェクトの任意のパブリック クラスのメンバー、または Visual Basic プロジェクトのホスト以外の項目クラスのメンバーを VBA に公開できます。 このオプションを使用すると、VBA に公開するクラスをより自由に選択できますが、より多くの手動手順も必要になります。

    これを行うには、次の主要な手順を実行する必要があります。

    1. クラスを COM に公開します。

    2. プロジェクト内のホスト項目クラスの GetAutomationObject メソッドをオーバーライドして、VBA に公開しているクラスのインスタンスを返します。

    3. プロジェクト内の任意のホスト項目クラスの ReferenceAssemblyFromVbaProject プロパティを True に設定します。 これにより、カスタマイズ アセンブリのタイプ ライブラリがアセンブリに埋め込まれており、ドキュメント内の VBA プロジェクトにタイプ ライブラリへの参照が追加されます。

    詳細な手順については、「方法: Visual Basic プロジェクトで VBA にコードを公開する」および「方法: Visual C# プロジェクトで VBA にコードを公開する」を参照してください。

    EnableVbaCallers プロパティと ReferenceAssemblyFromVbaProject プロパティは、デザイン時の [プロパティ] ウィンドウでのみ使用できます。実行時に使用することはできません。 プロパティを表示するには、Visual Studio でホスト項目のデザイナーを開きます。 これらのプロパティを設定するときに Visual Studio によって実行される特定のタスクの詳細については、「 ホスト項目のプロパティによって実行されるタスク」を参照してください。

ブックまたはドキュメントに VBA コードがまだ含まれていない場合、またはドキュメント内の VBA コードの実行が信頼されていない場合は、 EnableVbaCallers プロパティまたは ReferenceAssemblyFromVbaProject プロパティを True に設定するとエラー メッセージが表示されます。 これは、この状況では、Visual Studio でドキュメント内の VBA プロジェクトを変更できないためです。

VBA コードでメンバーを使用してカスタマイズ アセンブリを呼び出す

VBA コードがカスタマイズ アセンブリを呼び出せるようにプロジェクトを構成した後、Visual Studio はドキュメント内の VBA プロジェクトに次のメンバーを追加します。

  • すべてのプロジェクトに対して、Visual Studio によって GetManagedClass という名前のグローバル メソッドが追加されます。

  • EnableVbaCallers プロパティを使用してホスト項目クラスのメンバーを公開する Visual Basic プロジェクトの場合、Visual Studio は VBA プロジェクトのCallVSTOAssemblyThisDocumentThisWorkbookSheet1、またはSheet2 モジュールにSheet3という名前のプロパティも追加します。

    CallVSTOAssembly プロパティまたは GetManagedClass メソッドを使用して、プロジェクトの VBA コードに公開したクラスのパブリック メンバーにアクセスできます。

ソリューションの開発と展開中に、VBA コードを追加できるドキュメントのコピーがいくつかあります。 詳細については、「ドキュメントに VBA コードを追加するためのガイドライン」を参照してください

Visual Basic プロジェクトで CallVSTOAssembly プロパティを使用する

ホスト項目クラスに追加したパブリック メンバーにアクセスするには、 CallVSTOAssembly プロパティを使用します。 たとえば、次の VBA マクロは、Excel ブック プロジェクトのMyVSTOMethod クラスで定義されているSheet1という名前のメソッドを呼び出します。

Sub MyMacro()
    Sheet1.CallVSTOAssembly.MyVSTOMethod()
End Sub

このプロパティは、 GetManagedClass メソッドを直接使用するよりも、カスタマイズ アセンブリを呼び出す方が便利な方法です。 CallVSTOAssembly は、VBA に公開したホスト項目クラスを表すオブジェクトを返します。 返されたオブジェクトのメンバーとメソッド のパラメーターは、IntelliSense に表示されます。

CallVSTOAssembly プロパティには、次のコードのような宣言があります。 このコードは、Sheet1という名前の Excel ブック プロジェクトの ExcelWorkbook1 ホスト項目クラスを VBA に公開していることを前提としています。

Property Get CallVSTOAssembly() As ExcelWorkbook1.Sheet1
    Set CallVSTOAssembly = GetManagedClass(Me)
End Property

GetManagedClass メソッドを使用する

グローバル GetManagedClass メソッドを使用するには、 GetAutomationObject メソッドのオーバーライドを含むホスト項目クラスに対応する VBA オブジェクトを渡します。 次に、返されたオブジェクトを使用して、VBA に公開したクラスにアクセスします。

たとえば、次の VBA マクロは、MyVSTOMethodという名前のメソッドを呼び出します。このメソッドは、Sheet1という名前の Excel ブック プロジェクトの ExcelWorkbook1 ホスト項目クラスで定義されています。

Sub CallVSTOMethod
    Dim VSTOSheet1 As ExcelWorkbook1.Sheet1
    Set VSTOSheet1 = GetManagedClass(Sheet1)
    VSTOSheet1.MyVSTOMethod
End Sub

GetManagedClass メソッドには、次の宣言があります。

GetManagedClass(pdispInteropObject Object) As Object

このメソッドは、VBA に公開したクラスを表すオブジェクトを返します。 返されたオブジェクトのメンバーとメソッド のパラメーターは、IntelliSense に表示されます。

ドキュメントに VBA コードを追加するためのガイドライン

ドキュメントには複数の異なるコピーがあり、ドキュメント レベルのカスタマイズを呼び出す VBA コードを追加できます。

ソリューションの開発とテストを行う際に、Visual Studio でプロジェクトをデバッグまたは実行するときに開くドキュメント (ビルド出力フォルダー内のドキュメント) に VBA コードを記述できます。 ただし、このドキュメントに追加する VBA コードは、次回プロジェクトをビルドするときに上書きされます。これは、Visual Studio によってビルド出力フォルダー内のドキュメントがメイン プロジェクト フォルダーのドキュメントのコピーに置き換えられるためです。

ソリューションのデバッグ中または実行中にドキュメントに追加した VBA コードを保存する場合は、プロジェクト フォルダー内のドキュメントに VBA コードをコピーします。 ビルド プロセスの詳細については、「 Office ソリューションのビルド」を参照してください。

ソリューションをデプロイする準備ができたら、VBA コードを追加できる 3 つの主要なドキュメントの場所があります。

開発用コンピューターのプロジェクト フォルダー内

この場所は、ドキュメント内の VBA コードとカスタマイズ コードの両方を完全に制御できる場合に便利です。 ドキュメントは開発用コンピューター上にあるため、カスタマイズ コードを変更すると VBA コードを簡単に変更できます。 ドキュメントのこのコピーに追加した VBA コードは、ソリューションをビルド、デバッグ、発行するときにドキュメントに残ります。

デザイナーで開いている間は、VBA コードをドキュメントに追加できません。 最初にデザイナーでドキュメントを閉じ、Word または Excel で直接ドキュメントを開く必要があります。

注意事項

ドキュメントを開いたときに実行される VBA コードを追加すると、まれにこのコードによってドキュメントが破損したり、デザイナーで開けなくなる可能性があります。

発行フォルダーまたはインストール フォルダー内

場合によっては、VBA コードを発行フォルダーまたはインストール フォルダー内のドキュメントに追加することが適している場合があります。 たとえば、Visual Studio がインストールされていないコンピューターで VBA コードが別の開発者によって記述およびテストされる場合は、このオプションを選択できます。

ユーザーが発行フォルダーからソリューションを直接インストールする場合は、ソリューションを発行するたびに VBA コードをドキュメントに追加する必要があります。 ソリューションを発行すると、Visual Studio によって発行場所のドキュメントが上書きされます。

ユーザーが発行フォルダーとは異なるインストール フォルダーからソリューションをインストールする場合、ソリューションを発行するたびにドキュメントに VBA コードを追加しないようにすることができます。 発行の更新プログラムを発行フォルダーからインストール フォルダーに移動する準備ができたら、ドキュメントを除くすべてのファイルをインストール フォルダーにコピーします。

エンド ユーザー コンピューターで

エンド ユーザーが、ドキュメント レベルのカスタマイズで提供するサービスを呼び出す VBA 開発者である場合は、ドキュメントのコピーで CallVSTOAssembly プロパティまたは GetManagedClass メソッドを使用してコードを呼び出す方法をユーザーに伝えることができます。 ソリューションに更新プログラムを発行すると、エンド ユーザー コンピューター上のドキュメント内の VBA コードは上書きされません。これは、ドキュメントが更新の発行によって変更されないためです。

ホスト項目のプロパティによって実行されるタスク

EnableVbaCallers プロパティと ReferenceAssemblyFromVbaProject プロパティを使用すると、Visual Studio はさまざまなタスク セットを実行します。

EnableVbaCallers

Visual Basic プロジェクトでホスト項目の EnableVbaCallers プロパティを True に設定すると、Visual Studio は次のタスクを実行します。

  1. ComClassAttribute属性とComVisibleAttribute属性がホスト項目クラスに追加されます。

  2. ホスト項目クラスの GetAutomationObject メソッドをオーバーライドします。

  3. ホスト項目の ReferenceAssemblyFromVbaProject プロパティを True に設定します。

    EnableVbaCallers プロパティを False に戻すと、Visual Studio は次のタスクを実行します。

  4. ComClassAttribute クラスからComVisibleAttribute属性とThisDocument属性が削除されます。

  5. ホスト項目クラスから GetAutomationObject メソッドを削除します。

    Visual Studio では、 ReferenceAssemblyFromVbaProject プロパティが False に自動的に設定されることはありません。 [プロパティ] ウィンドウを使用して、このプロパティを False に手動で設定できます。

ReferenceAssemblyFromVbaProject

Visual Basic または Visual C# プロジェクトのホスト項目の ReferenceAssemblyFromVbaProject プロパティが True に設定されている場合、Visual Studio は次のタスクを実行します。

  1. カスタマイズ アセンブリのタイプ ライブラリが生成され、アセンブリにタイプ ライブラリが埋め込まれます。

  2. ドキュメント内の VBA プロジェクト内の次のタイプ ライブラリへの参照が追加されます。

    • カスタマイズ用アセンブリの型ライブラリ。

    • Microsoft Visual Studio Tools for Office 実行エンジン 9.0 タイプ ライブラリ。 このタイプ ライブラリは、Visual Studio Tools for Office ランタイムに含まれています。

    ReferenceAssemblyFromVbaProject プロパティを False に戻すと、Visual Studio は次のタスクを実行します。

  3. ドキュメント内の VBA プロジェクトからタイプ ライブラリ参照を削除します。

  4. アセンブリから埋め込みタイプ ライブラリを削除します。

Troubleshoot

次の表に、一般的なエラーと、エラーを修正するための推奨事項を示します。

エラー Suggestion
EnableVbaCallers プロパティまたは ReferenceAssemblyFromVbaProject プロパティを設定すると、ドキュメントに VBA プロジェクトが含まれていないか、ドキュメント内の VBA プロジェクトにアクセスする権限がないことを示すエラー メッセージが表示されます。 プロジェクト内のドキュメントに少なくとも 1 つの VBA マクロが含まれていること、VBA プロジェクトを実行するのに十分な信頼があることを確認し、VBA プロジェクトがパスワードで保護されていないことを確認します。
EnableVbaCallers または ReferenceAssemblyFromVbaProject プロパティを設定すると、GuidAttribute宣言が見つからないか破損していることが示されます。 GuidAttribute宣言がプロジェクトのAssemblyInfo.csまたはAssemblyInfo.vb ファイルに配置されていること、およびこの属性が有効な GUID に設定されていることを確認します。
EnableVbaCallers または ReferenceAssemblyFromVbaProject プロパティを設定すると、エラー メッセージは、AssemblyVersionAttributeで指定されたバージョン番号が無効であることを示します。 プロジェクト内のAssemblyInfo.csまたはAssemblyVersionAttribute ファイルの宣言が有効なアセンブリ バージョン番号に設定されていることを確認します。 有効なアセンブリ バージョン番号については、 AssemblyVersionAttribute クラスを参照してください。
カスタマイズ アセンブリの名前を変更すると、カスタマイズ アセンブリを呼び出す VBA コードは動作を停止します。 VBA コードに公開した後でカスタマイズ アセンブリの名前を変更すると、ドキュメント内の VBA プロジェクトとカスタマイズ アセンブリ間のリンクが壊れます。 この問題を解決するには、プロジェクトの ReferenceFromVbaAssembly プロパティを False に変更してから True に戻し、VBA コード内の古いアセンブリ名への参照を新しいアセンブリ名に置き換えます。