[Excel]VBA 参照設定とCreateObject

エクセルVBAでは、外部ライブラリ(エクセル外のオブジェクト)を参照する事によりエクセルには無い機能を利用する事ができます。方法は2つあって「参照設定」と「CreateObject関数」です。

参照設定

参照設定はVBEの「ツール」→「参照設定」のダイアログで設定できます。

私の環境だと、デフォルトでエクセルが参照しているライブラリは以下の4つです(Excel2019)。

  • Visual Basic For Applications
  • Microsoft Excel 16.0 Object Library
  • OLE Automation
  • Microsoft Office 16.0 Object Library

あと、ユーザーフォームを作成すると自動でMicrosoft Forms 2.0 Object Libraryが追加されます。

普段はこのライブラリにあるクラスやモジュール、関数を利用してマクロを作成していますが、参照設定を行う事でここにはない機能を利用できます。

設定方法

VBEの「ツール」→「参照設定」でダイアログを開き、参照したいライブラリにチェックを入れる。

設定の保存

参照設定はBookごとに保存されます。一度設定してしまえばそのBookでは再設定不要です。

ライブラリが一覧に無い場合

参照設定ダイアログに表示されるライブラリ一覧はPC環境によって変わります。参照設定ダイアログに使いたいライブラリが無い場合、ライブラリ本体(ファイル)がインストールされていれば、直接参照することで一覧に表示させる事ができます。

参照設定ダイアログの[参照]ボタンを押し、ライブラリのファイル名で検索、見つかったファイルをクリックする。

一覧にライブラリが表示されます。

参考までに、デフォルトの4つと当サイトで扱った事のある外部ライブラリのファイル名は以下の通りです。

  • Visual Basic For Applications…VBE7.DLL
  • Microsoft Excel 16.0 Object Library…EXCEL.EXE
  • OLE Automation…stdole2.tlb
  • Microsoft Office 16.0 Object Library…MSO.DLL
  • Microsoft Forms 2.0 Object Library…FM20.DLL
  • Microsoft Outlook 16.0 Object Library…MSOUTL.OLB
  • Microsoft Scripting Runtime…scrrun.dll

コード

参照設定を行うだけではそのライブラリに含まれるクラスを扱う事はできません。インスタンス化が必要です。DimまたはSetステートメントにNewキーワードでオブジェクト名を指定します。

サンプルはMicrosoft Outlook 16.0 Object LibraryライブラリのApplicationオブジェクト、Microsoft Scripting RuntimeライブラリのDictionaryオブジェクトをそれぞれ使用するケースです。

Setありサンプル

'OutlookApplicationオブジェクト
Dim olApp as Outlook.Application
Set olApp = New Outlook.Application
    'Outlook.Applicationオブジェクトを使用した処理を記述
Set olApp = Nothing

'Dictionaryオブジェクト
Dim myDic As Dictionary
Set myDic = New Dictionary
    'Dictionaryオブジェクトを使用した処理を記述
Set myDic = Nothing
Setなしサンプル

'OutlookApplicationオブジェクト
Dim olApp As New Outlook.Application

'Dictionaryオブジェクト
Dim myDic As New Dictionary

Setあり/なしの違い

違いはSetありはその行でインスタンス化(実体化)されるのに対し、Setなしは宣言だけで、まだインスタンス化されていません。Setなしがインスタンス化されるのは「そのオブジェクトが初めて参照された時」です。

Setなしサンプルでは、コードの書き方によってはひょっとしたらバグが発生するかも、位の認識です(私見)。どうしても気になる方はSetありサンプルを使って下さい。

Set obj = Nothing

この記述、時と場合によっては不要です。興味のある方、理解を深めたい方は他サイトをググって下さい。そうでない方は取り合えず記述しておいて間違いはありません。

Newで指定するオブジェクト名

Newキーワードで指定するオブジェクト名ですが、大体の場合はVBEのオブジェクトブラウザーで確認できるオブジェクト名(クラス)で大丈夫ですが、そうでないケースもあります。

オブジェクト名が他のライブラリと被っているとアプリケーション名も必要になります。サンプルのApplicationオブジェクトがそうですが、省略するとExcel.Applicationを参照してエラーが出ます。

このサイトで使用したオブジェクト名はサンプルコードを残していきますが、そうでないものは…「参照設定 ライブラリ名 オブジェクト名」でググるか、このサイトでお目当てのオブジェクト名が見つかるかも知れません。

エクセルの神髄

VBAでエクセル外のオブジェクトを使うときには、事前バインディングと遅延バインディング(実行時バインディング)の2通りが…

インスタンス化について

インスタンス化の詳細については私の知識ではとても説明できないので他サイトで確認して下さい。私の簡単な理解では、クラスはそもそもオブジェクトの設計図であり、実体を持ちません。

インスタンス化とは「実体化」であり、クラスをインスタンス化して初めて「オブジェクト」になります。

では普段使用しているオブジェクトはNewしてないのになぜ使えるのか?ですが、調べてもよくわかりませんでした(調べ方が悪かったかも)。エクセルがアプリケーションとして機能するために既にインスタンス化されているんだと勝手に解釈しています。

ただ、デフォルトで参照されているライブラリ全てがインスタンス(インスタンス化されたクラス)ではないようです。

VBAライブラリのCollectionオブジェクトがその例です。Collectionオブジェクトを使用するとき、参照設定は不要ですが、Newは必要です。

CreateObject関数

CreateObject関数を使うことでも外部ライブラリのオブジェクトを扱う事ができます。

コード

参照設定と違い、コード上で全てを完結できます。

CreateObject関数サンプル

'(Outlook)Applicationオブジェクト
Dim olApp as Object
Set olApp = CreateObject("Outlook.Application")
    'Outlook.Applicationオブジェクトを使用した処理を記述
Set olApp = Nothing

'Dictionaryオブジェクト
Dim mydic As Object
Set mydic = CreateObject("Scripting.Dictionary")
    'Dictionaryオブジェクトを使用した処理を記述
Set myDic = Nothing

CreateObject関数の引数

参照設定とCreateObject関数では指定するオブジェクト名の書き方が違います。但し、同じ場合もあります(ややここしい)。とても覚えきれないし、ヘルプ内をオブジェクト名で検索しても簡単には見つからない事が多いです。

参照設定同様、ネットで検索するか調査してくれているサイトをブックマークするのが手っ取り早いです。

参照設定とCreateObject関数の違い

当サイトでは外部ライブラリを使用するコードを紹介する場合、参照設定を推奨しています。紹介しているコードはCreateObject関数で記述していますが、理由は後述します。

参照設定

インテリセンスが有効になる

正確には、「参照設定すると変数宣言で特定のオブジェクト型を指定する(As Objectではない)」のでインテリセンス(入力支援機能)が有効になります。参照設定自体はインテリセンスの有無に直接関わっていません。

事前バインディングになるので処理が高速化される

インテリセンス同様、変数宣言による理由で事前バインディングになります。詳しくはこのサイトで。

エクセルの神髄

マクロVBAでActiveXオブジェクトを操作する場合のVBA記述方法が2通りあります。オブジェクトがオブジェクト変数に…

CreateObject関数

コードのみで完結するので環境に左右されにくい

ファイルではなくコードを共有する場合、参照設定ありだとその設定方法も共有する必要があります。CreateObject関数ではその必要がありません。ライブラリさえインストールされていれば、コードのみでマクロが機能します。

当サイトの他ページで紹介しているサンプルコードがCreateObject関数を使用しているのもこれが理由です。せっかちな人がコピペだけしてページ離脱、参照設定しない、といったケースが想定されるので。

実行時バインディングになるのでエラー処理ができる

参照設定は事前バインディングになるので、エラー(参照設定されていない等)があるとマクロが起動しません。

CreateObject関数は実行時バインディングになるのでエラーハンドリング(エラー発生時に処理を停止しないで別の処理を行う)が可能です。マクロの内容によっては有効なケースもあると思います。

特段の理由がない限り、インテリセンスが有効になる参照設定推奨です。CreateObject関数を使うことによって得られるメリットが大きい場合はもちろん、それを妨げるものではありません。

それぞれの機能を理解して使い分けられるようになりたいものです。

最後までご高覧いただきありがとうございました。