CreateObject関数は何をやっているのかが分かりにくい

VBAで少し特殊なことをやろうとすると出てくるのがCreateObject関数です。

ところがこのCreateObject関数について調べようと思ってMicrosoftのヘルプを見てみると「オートメーション オブジェクトへの参照」という分かりにくい説明になっています。ネットでも「ActiveXへの参照」という説明が多いようですが、ActiveXは普段使うアプリケーションの内部で知らないうちに使っていても自分でコーディングすることが多い技術ではありませんので、なかなか理解しにくいと思います。

そのため、よくわからないけど動くからいいや、という感じで使っている方は結構いると思います。

特にわかりにくいのがCreateObject関数の引数に渡す”Scripting.FileSystemObject”とか”Excel.Application”などの文字列です。この文字列は一体どこからきているのかは熟練のプログラマーでないとなかなか分からないでしょう。

そこでこのページではこれらの疑問について説明します。

CreateObject関数の引数の文字列はレジストリのキー名

CreateObject関数の引数に指定する文字列ですが、これはレジストリの「HKEY_LOCAL_MACHINE\Software\Classes\」のキー名を指しています。

FileSystemObjectの場合であれば「HKEY_LOCAL_MACHINE\Software\Classes\Scripting.FileSystemObject」のキー名である「Scripting.FileSystemObject」です。キー名とは下の画像ではフォルダのように見える部分のことを言います。

CreateObject関数の場合はこのキー名を使って以下のように書きます。

 

CreateObject関数の引数の文字列と参照するDLLの関係

CreateObject関数の引数文字列からは以下の順で辿っていきます。

Scripting.FileSystemObjectキーの下の階層にあるCLSIDキーの既定値がCreateObject関数の引数文字列が指し示すクラスのIDになります。

このCLSIDをレジストリから検索すると「HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{ID省略}」が見つかります。レジストリの検索はレジストリエディタの編集メニューから行うことが出来ます。

この配下のInprocServer32の既定値にはDLLの実体がフルパスで設定されています。FileSystemObjectの実体はscrrun.dllということが分かります。

ProgIDには先ほどと同じですが、FileSystemObjectのキー名が設定されています。

このように、CreateObject関数の引数文字列にProgIDを指定 → CLSID → InprocServer32 → DLLパス、とつながっています。以上から、CreateObject関数は外部DLLを使うための初期化処理、ということが分かります。

外部DLLと書きましたが、実際はCOM(Component Object Model)で、ここではscrrun.dllでしたが拡張子がocxのものもあります。COMとはおおざっぱに言えば単独では動作できない汎用クラスをライブラリ化して*.dllや*.ocxにしたものです。関数だけが提供されているDLLとは異なります。

上のscrrn.dllをdumpbinで見てみると以下のようにFileSystemObjectの関数とは全然違う関数が出てきます。

これらはCOMで必要な公開関数です。一応載せましたけど、おそらくほとんどの方には関係ない話で、CreateObject関数で使いたい関数の初期化処理をして必要に応じて使えればOKだと思います。

細かい話はここでは省略します。

あとは使いたいクラスのメソッドやプロパティの話になります。それらはヘルプ等で確認してください。

逆に、ヘルプなどから使いたいDLLが分かっている場合は、上の順とは逆にDLL名を検索して、CLSID→ProgID(キー名)という形で検索していくと、VBAでそのDLLの機能を使うことが出来る場合があります。

ProgIDとCLSIDの一覧取得

レジストリエディターからProgIDやCLSIDを一つずつ検索するのが手間なのであれば、コマンドプロンプトでテキストファイルに出力して確認してください。

ProgIDは以下のコマンドを実行するとProgID.txtに出力されます。

CLSIDは以下のコマンドを実行するとCLSID.txtに出力されます。