PR

Excel VBA の参照設定に表示される参照可能なライブラリとは?

Excel VBA Tips
この記事は約21分で読めます。

「Excel VBA Tips」ではExcel VBAを使用していて気付いたことを取り上げて行きます。

今回は、参照設定のダイアログボックスに表示される参照可能なライブラリの内容について掘り下げて行きたいと存じます。

以前「Excel VBA コーディング」のカテゴリで「Excel VBAで使えるCOMクラスのクラスIDとレジストリTypeLibとの対比表」を取り上げましたが、本テーマでは「Excel VBAで使えるTypeLib」と「参照設定に表示される参照可能なライブラリ」との違いを明確にしたいと思います。

なおパソコンにいろいろアプリケーションをインストールすると表示される参照可能なライブラリの内容は追加されて行くので、今回は弊社で2か月前(2022年11月)に購入したパソコンを使用して調べる事に致します。

※動作は64bit版Excel 2021の バージョン2212(ビルド 15928.20216)を使用して検証しています。

スポンサーリンク

参照設定について

Microsoft Officeアドインのドキュメントに参照設定ダイアログボックスのページがあります。

ここに書かれている内容をまとめると次のようなります。

  • 参照設定をする(ダイアログボックスで該当ライブラリのチェックボックスをオンにする)と「他のアプリケーションのオブジェクトをVBAコーディングの中で使用する」事ができるようになります。
  • コーディングで使用しないチェックボックスがオンになっているとVBAが解決するオブジェクト参照数が増えるのでコンパイルに時間がかかります。
  • 2 つの参照先ライブラリに同じ名前のオブジェクトが含まれている場合は、参照設定ダイアログボックスの上位の位置にあるライブラリで提供される定義が優先されます。
  • 参照設定ダイアログボックスにディレクトリ検索をして追加できるのは主に下記のファイルの種類になります。
    • Excel (.xlsm、.xlam)用のアプリケーション固有のファイル
    • タイプ ライブラリ (*.olb、 *.tlb、 *.dll)
    • 実行可能ファイル (*.exe、 *.dll)
    • ActiveX コントロール (*.ocx) その他

なお参照設定をしていなくてもコーディングでCreateObject関数を使う事でオブジェクト、具体的にはCOMクラスを使用する事はできますが、今回は「CreateObject関数を使わない(言い換えると参照設定を使う)」形を想定しています。

参照設定ダイアログボックスの設定は個々のXLSMファイルの中に保存される

XLSMファイルに保存されているのはあくまでも、「どのオブジェクトを参照しているか?」というフラッグだけで、XLSMファイルをオブジェクトが存在しないパソコンで使用した時はそのオブジェクトを動かす事はできません。

ちなみに、そのような場合に参照設定ダイアログボックスを見ると当該オブジェクトは「参照不可」と表示されています。

当然の事ですが「参照不可」のところのチェックボックスをオフにすると参照可能なライブラリの一覧から「参照不可」になっていたオブジェクトは一覧から見えなくなります。

つまりパソコンの中に設定されているオブジェクトが存在していなければ動かすことはできません。

参照可能なライブラリにデフォルトで表示されるオブジェクトとは?

「参照設定ダイアログボックスにデフォルトで表示されるオブジェクトは、どのような情報に基づいているのか?」という事は気にされた事は無いと思いますが、まさにそれが今回のメインテーマになります。

パソコンを長年使用していると気が付かれると思うのですが、参照可能なライブラリに表示されるオブジェクトは、パソコンにインストールされたアプリケーションシステムによって増加しています。

ただしインストールするアプリケーションによってはオブジェクトを持っていない場合もありますので、一概にそうとは決めつける事はできません。

また場合によっては一度インストールしたアプリケーションを削除するケースもある事と存じます。

今回検証に使用したパソコンにはバンドルでMicrosoft Office Home and Business 2021がインストールされているために参照可能なライブラリの一覧にはOffice関連のオブジェクトが含まれています。

以上を踏まえた上で 、「参照可能なライブラリに表示される全てのオブジェクトをオンにしてみて、どのくらいの数のオブジェクトが対象になっているのか?」を調べて見る事にします。

そこから「どのような情報に基づくものなのか?」を考察して見たいと思います。

検証に使用するパソコンの参照可能なライブラリの一覧を取得する

今回検証に使用するパソコンは2022年11月に購入したWindows11バージョン22H2にMicrosoft Office Home and Business 2021がインストールされた状態で、その後Google ChromeとLAN Diskのアプリケーションをインストールしています。

参照設定ダイアログボックスに表示されるオブジェクトを「どのようにして一覧表にするか?」なのですが、これを一つづつ書き写して行くとしたら、それだけで大変な作業量になってしまいますし間違えも起こり易くなります。

そこで、チェックボックスにチェックを入れるところは手作業になりますが、すべてのオブジェクトをオンした状態にして、VBAコーディングを使ってオンになっている参照設定のオブジェクトをすべて取得します。

そのためのコーデングの参考事例を下記に掲載いたします。

なお結果は開いているExcelブックの最後尾に「参照設定」シートを追加して書き出しています。

書き出す内容は、指定されたブックの Visual Basicプロジェクトを表すVBProjectオブジェクトに紐ずくreferencesコレクションから取り出したReferenceオブジェクトが持つ各種プロパティ/メソッドなのですが、残念ながらMicrosoft Officeドキュメントの中には、それらを説明する該当ページを見つけられませんでした。

ただし左図のようにオブジェクト ブラウザーで見ると幾つかプロパティが存在するので、値が返るものをピックアップして出力しています。

なおエラーが発生しても全てが処理できるように「On Error GoTo」ステートメントを設定していますのでお含み置きください。

  • GUID
    • TypeLibに同じ値が存在するので、タイプライブラリのID(128 ビットの数値 :16 進数)になる認識です。
  • Name
    • 「タイプライブラリの名称」に類似している。
  • Description
    • 参照設定の参照可能なライブラリに表示される内容になります。
  • BuiltIn
    • Boolean型の値で、Trueになるのは「Visual Basic For Applications」と「Microsoft Excel 16.0 Object Library」だけで、それ以外はすべてFalse
  • fullpath
    • 「TypeLibに登録されているパス」に類似している。
Sub referencesList()
Dim ws As Worksheet
Dim obj_ref As Object
Dim iRow As Integer
On Error GoTo ErrHandler
    iRow = 0
    Set ws = addNewSheet("参照設定")    '「参照設定」という名前で新しいシートを追加
    Application.ScreenUpdating = False   '画面固定
'チェックされた全ての参照設定に対し処理を実行
    For Each obj_ref In ActiveWorkbook.VBProject.references
        iRow = iRow + 1
        ws.Cells(iRow, 1).Value = obj_ref.GUID
        ws.Cells(iRow, 2).Value = obj_ref.Name
        ws.Cells(iRow, 3).Value = obj_ref.Description
        ws.Cells(iRow, 4).Value = obj_ref.BuiltIn
        ws.Cells(iRow, 5).Value = obj_ref.fullpath
    Next
    Cells.Select  '入力範囲を選択
    Cells.EntireColumn.AutoFit  '列の幅を自動調整
    ws.Cells(1, 1).Select  'A1セルを選択して範囲選択を解消
    Application.ScreenUpdating = True   '固定解除
    Set ws = Nothing
    Exit Sub  '<<<<<<<<
ErrHandler:
    ws.Cells(iRow, 4).Value = Err.Number & ":" & Err.Description
    Err.Clear
    Resume Next
End Sub
Public Function addNewSheet(stSheetName As String) As Object
    Set addNewSheet = Sheets.Add(after:=Sheets(Sheets.Count))  '新しいシートを追加
    addNewSheet.Name = stSheetName 'シート名を変更
End Function

実行結果のひとつひとつの内容は今回はあまり重要ではないが、エラーを確認する

今回検証に使用したパソコンでは288個のライブラリが出力されますが、そのひとつひとつの内容につきましては割愛を致します。
※割愛する理由は一言で言い表す事は難しいので、この後の章で順を追ってご説明いたします。

  • 検証パソコンのTypeLibのGUIDの個数は291個でした。
  • 同じくOfficeのTypeLibのGUIDの個数は68個でした。

合計すると359個になりますがどちらにも存在する20個を差し引くと339個になり、それに対して288個のライブラリという事は参照設定ダイアログボックスに表示されているライブラリの個数は絞られている事が分かります。
なお絞られている理由の一つには次の章でご説明する「バージョンが異なるケース」があります。

※OfficeのTypeLibにつきましては「Excel VBAでOfficeが使用するTypeLibをレジストリから取得?」をご参照いただければ幸いです。

【補足】
 64bit版Excel 2021をご使用の場合は、上記リンクに掲載しているコーディング事例「TypeLibPrint」で、下記変数の値を次のように書き換えればOfficeのTypeLibの内容を新しいシートに書き出す事ができます。

REG_KEY2=”SOFTWARE\Microsoft\Office\ClickToRun\REGISTRY\MACHINE\Software\Classes\TypeLib”
idx=2

なお「重要ではない」と言いながらも実行結果の中で1つ気になる点があります。

それは「-2147319779:’FullPath’ メソッドは失敗しました: ‘Reference’ オブジェクト」というエラーになるライブラリーが6個存在している点です。

皆様のパソコン環境で実行すると、恐らく異なる個数になる事と存じますが、細かな内容は置いておいて6個のオブジェクトを取敢えず列挙致します。

NoGUID
㊥Name/Description
㊦ファイルパス(参照設定ダイアログボックスの場所を手入力)
FileReg
istry
1㊤{09C6A793-92DC-4D27-A11D-3921C9314DED}
EditionUpgradeHelperLib/
C:\Windows\System32\EditionUpgradeHelper.dll
2㊤{0014D784-7012-4A79-8AB6-ADDB8193A06E}
ElevatorLib/Elevator 1.0 Type Library
C:\Program Files(x86)\Microsoft\edge\Application\109.0.1518.70\elevation_service.exe
×
3㊤{D6DA003A-AFF3-4850-A161-F3D883FF2447}
MeetingJoinAxLib/MeetingJoinHelper 2.0 Type Library
C:\Program Files(x86)\Microsoft Office16\MeetingJoinAxOC.dll
×
4㊤{444541A0-F621-4463-986A-52D1589E5B5D}
Microsoft_Office_PowerPivot_ExcelAddIn/Microsoft SQL Server PowerPivot for Microsoft Excel

㊦C:\Program Files\Microsoft Office\root\Office 16\ADDINS\PowerPoint Excel Add-in\
Microsoft_Office_PowerPoint_ExcelAddin.tlb
×
5㊤{77EC5343-1055-984F-88BC-E3949E1A4769}
NucleusNativeMessagingLib/
C:\Program Files\Microsoft OneDrive¥23.011.0115.0006\Microsoft_SharePoint.dll¥2
×
6㊤{B52A4496-7753-4F74-BE64-C2072E308122}
wscAPILib/wscAPI 2.0 Type Library
C:\Windows\System32\wscapi.dll
‘FullPath’ メソッドは失敗
  • ‘FullPath’ メソッドが失敗しているのに上記表にファイルパスが表記されているのは、参照設定ダイアログボックスの場所に表示されているファイルパスを手入力で書き写したからです。
  • File列はファイルパスがエクスプローラで見て存在しているか?を確認したものです。
    • 「〇」は存在している事を表しています。
  • Registry列はGUIDをレジストリエディタで検索してTypelib配下に存在する場合は「〇」にしています。

この結果から考察できるのは次の2点です。

  1. 参照設定ダイアログボックスの場所にはファイルパスは表示されているのにVBAの’FullPath’ メソッドが失敗する原因は不明です。
  2. エラーになる原因は「ファイルの存在性」でも「RegistryのTypelibの存在性」でもなさそうです。

ただ恐らくこの×がある4個のライブラリはVBAでは正しく機能しないのではないでしょうか?
なお6個をわざわざここで列挙したのは次の説明につなげるためなので、詳細は気にしなくても大丈夫です。

MEMOの補足

※下記で記載している数字につきましては検証パソコンでの値になり、皆さまのパソコン環境とは異なると思いますのでご注意ください。

コーディング事例のreferencesListを実行して書き出された288個のオブジェクトのGUIDを、MEMOに書いた①TypeLib291個、②Office TypeLib68個、とそれぞれマッチングさせると、①は249個、②は57個が一致します。

合計すると306個になり288個よりも増えてしまうのですが、実は①と②ともに存在するオブジェクトが20個あるので、それを差し引くと286個となり最終的には2個少なくなります。

このGUIDの2個の差は何か調べると、実は「’FullPath’ メソッドは失敗」の表でRegistryが「×」になっている2個のオブジェクトであり、これらはRegistryには存在していないので有効数としては286個になります。


話は変わりますが、例えば①のTypeLibに在りながら286個に含まれていないオブジェクトの1つ「Performance Data Service」のファイルパスを参照設定ダイアログボックスの参照で選択すると、そのオブジェクトは参照可能なライブラリとして設定が可能です。

このように、TypeLibに存在するオブジェクトであれば参照設定ダイアログボックスに存在していなくても、手動で参照可能なライブラリとして設定する事が可能なものがあります。

※なお「Performance Data Service」のチェックを外すと参照設定ダイアログボックスから消されてしまい、残りませんでした。

参照設定ダイアログボックスにはチェックボックスをオンにできないものがある

実は参照設定ダイアログボックスでチェックボックスをオンにして行くと、オンにできないオブジェクトに遭遇します。

ケースとしては次の2つになります。

①バージョンが異なるケース

実は表示されているオブジェクトの中に同じオブジェクトでバージョンが異なるものが存在します。

参照設定では異なるバージョンのオブジェクトのチェックボックスを同時にオンにする事はできません。

そのため一度に大量にチェックを付けたとしても、このエラーに遭遇するとその直前までしかチェックが有効にならないので、すべてのオブジェクトのチェックボックスをオンにするという作業は結構大変になります。

ご参考までになるのですが、検証パソコンでは本ケースに該当するオブジェクトは20個ほどありました。

もっともこのケースはチェックボックスをオンに出来なくても「致し方無い」と思うのですが、次のケースは理解に苦しむものになります。

②DLLを読み込めないケース

参照設定ダイアログボックスでチェックボックスをオンにして行くと、次のようなエラーになるケースがあります。

前章ではチェックボックスはオンにできるのにVBAの’FullPath’ メソッドが失敗するケースでしたが、今回はオンにしてOKボタンをクリックすると左図のエラーになるケースになります。

「エラーになるのなら参照設定ダイアログボックスのオブジェクト一覧に含めないで欲しい」と思うのてすが、そうはなっていないようです。

今回検証に使用したパソコンでは9個のライブラリーが該当しますが、前章と同様に細かな内容は置いておいて9個のオブジェクトを列挙します。

  • 参照設定ダイアログボックスに表示された内容を手入力していますので、前章にあったGUIDやNameの情報はありませんのでお含み置きいただければ幸いです。
  • Registryの確認はファイルパスに基づき実施しています。次章でご説明しますがDescriptionで検索した場合は違った結果になります。
No㊤Description
ファイルパス
FileReg
istry
1㊤Genesis TeIetext Server 1.0 Type Library
C:\Windows\System32\WSTPager.ax
2㊤Microsoft DAO 3.6 Object Library
C:\Program Files\Common Files\Microsoft Shared\DAO\dao360.dll
××
3㊤Microsoft SharePoint Plug-in for Firefox
C:\Program Files\Microsoft Office\root\Office16\NPSPWRAP.dll
4㊤MSOLAP 7.0 Type Library
C:\Program Files\Common Files\Microsoft Shared\OFFICE16\DataModel\msolap_xl.dll
×
5㊤MSOLAP 8 Type Library
C:¥Program Files\Microsoft Analysis Services\AS OLEDB¥140\msolap.dll
×
6㊤OCHelper 1 0 Type Library
C:\Program Files (x86)\Microsoft Offioe\Offioe 16¥OCHelper.dll\1
××
7㊤RAssistance 1.0 Type Library
C:\Windows\System32\RACPLDlg.dll
8㊤SHGINA_USERS 1.0 Type Library
C:\Windows\system32\usercpl.dll
×
9㊤Windows Geolocation Service, v1.0
C:\Windows\System32\LocationFramework.dll
DLL読み込み時のエラー

この結果から考察できるのは、前章と同じになりますが次の2点です。

  1. 参照設定ダイアログボックスの場所にはファイルパスは表示されているのにDLLが読み込めないという原因は不明です。
  2. エラーになる原因は「ファイルの存在性」でも「RegistryのTypelibの存在性」でもなさそうです。

チェックボックスをオンにできないオブジェクトが存在する仮説

先程の「DLL読み込み時のエラー 」の表は、「ファイルパス」でRegistryを検索したものですが、これを「Description」を使って検索すると違う結果になります。

ちなみにRegistry列が「×」のライブラリについて検証パソコンで調べると次のような情報が見つかります。

NoDescriptionRegistry Key
㊦ファイルパス
2Microsoft DAO 3.6
Object Library
㊤\HKEY_CLASSES_ROOT\TypeLib\{00025E01-0000-0000-C000-000000000046}\5.0\0\win32
%CommonProgramFiles%\Microsoft Shared\DAO\dao360.dll
6OCHelper 1 0
Type Library
㊤\HKEY_CLASSES_ROOT\TypeLib{EE9CFA8C-F997-4221-BE2F-85A5F603218F}\1.0\0\win32
C:\Program Files\Microsoft Office\root\VFS\ProgramFilesX86\Microsoft Office\Office16\OCHelper.dll\1
8SHGINA_USERS 1.0
Type Library
㊤\HKEY_CLASSES_ROOT\TypeLib{D808BD12-DD1E-4cbc-8A3A-0A35010F078A}\1.0\0\win32
%SystemRoot%\system32\usercpl.dll

No2とNo8はディレトリが環境変数になっているために単純な文字列検索では見つけられなかったのですが、No6は仮想ファイルシステム(VFS)を介した設定になっているために見つけられませんでした。

このような状況を鑑みると章題の仮説としてはつぎのようになります。

仮説
  • 参照設定ダイアログボックスを表示するのに使用されているライブラリ情報には、古い情報が混じっているのでは?
    • 検証パソコンに合わせた情報になっていれば「DLL読み込み時のエラー 」は発生しないのではないか?と想定されます。
  • 上記の状態を考えるとOffice VBAのためのライブラリ情報が別個に存在するのでは?
    • 例えば一般的なRegistryとは別なRegistryに保管されていると想定されますし、または別のRegistryではなく一般的なRegistryに権限付きで登録されている可能性も否定はできません。
  • 一般的なRegistryが更新されると、別個に存在するライブラリ情報を更新する仕組みが裏で動いているのでは?
    • Dllを使用しているソフトウェアをインストールやアンインストールをすると、経験上参照設定ダイアログボックスに表示されるライブラリ情報は追加や削除がなされています。

この仮説が今回のメインテーマである「参照設定ダイアログボックスにデフォルトで表示されるオブジェクトは、どのような情報に基づいているのか?」に対するザックリとした回答になります。

なお先述しました「MEMOの補足」のように、参照設定ダイアログボックスに表示されるオブジェクトでチェックボックスをオンにできるものはすべて、①TypeLib、②Office TypeLibのどちらかに存在しており、また参照設定ダイアログボックスに表示されていないオブジェクトを手動で登録する事ができるものもあり(すべてを確認していないので曖昧な表現にしています)、 最終的にこのような仮説になりました。

まとめ

「Office VBAのためのライブラリ情報が存在する」という仮説が今回のメインテーマの回答になるのですが、「なぜそのような2重更新のような形になっているのか?」を最後に少し考えて見たいと思います。


Windows 11でサポートされるOfficeのバージョンにつきましては、下記Microsoft コミュニティのページになるのですが、次のように書かれています。

この質問への回答によるとサポートされているのは下記になります。

  • Microsoft365
  • Office2021
  • Office2019
  • Office2016
  • Office Premium(日本のみ)

そうなると恐らくバージョンごとにライブラリ情報が存在していて、Dllを使用するソフトウェアがインストールされるたびに、それぞれのバージョンのライブラリ情報に(仕組みは分かりませんが)伝播されるのではないか?と思います。

その際にOffice2016であればこのような情報、Office2021であればこのような情報で更新する事になるとは思いますが、Officeが持つ下位互換性とかwin32/win64の互換性を考慮すると、それぞれのバージョンのライブラリ情報をクリーンな状態に保つのはかなり至難の業になるのではないか?と想定されます。


このような事を鑑みると、「参照設定にデフォルトで表示されるオブジェクト」は沢山ありますが、そこに表示されるオブジェクトをひとつひとつ気にしなくても、チェックが付けられているオブジェクトの事だけに集中すれば良いように感じます。

そうは言ってもどうしても気になる場合は「TypeLibからどのようなCOMクラスが呼ばれるのか?」の一覧を「Excel VBAで使えるCOMクラスのクラスIDとレジストリTypeLibとの対比表」でご紹介していますので、そちらをご参照いただければ幸いです。
※なお上記対比表は「参照設定にデフォルトで表示されるオブジェクト」を網羅していません(特にOffice TypeLibは含まれていません)し、絞り込んでもいませんのでご注意ください。
※ただ「TypeLibに存在していないオブジェクトは動作しない(はずである)」という事を考えると、Office TypeLib以外で気にしなければいけないオブジェクトは上記の一覧の中にあるはずです。
※Office TypeLibに存在するオブジェクトのCOMクラスにつきましては改めて別の記事でご紹介する予定です。

以上最後までご一読いただき誠にありがとうございました。