【VBA】アーリーバインドとレイトバインド

VBAのアーリーバインドとレイトバインドの違いについては、あちこちのWebで諸氏が説明していますので、今さら私が説明する必要もないと思うのですが、配布の問題から説明した記事が見つけられなかったので、私なりに配布の問題の観点から説明してみようと思います。

アーリーバインドとレイトバインドとは

アーリーバインドa.k.a参照設定

アーリーバインドというのは事前バインドと言うこともあるのですが、ここでは「参照設定をすること」と言っておきたいと思います。

例えば、Excelを使っていてVBE(Visual Basic Editor)で次のようなコードを書いたとき、参照設定をしていないとコンパイルでエラーになります。

Dim WdApp As Word.Application
コンパイルエラー:ユーザ定義型は定義されていません。

参照設定というのは、VBEではメニューバーのツールのところにあります。

VBE ツール→参照設定

この参照設定で、適切なライブラリを選んでおかないとエラーになるのがアーリーバインドです。

参照設定。私はほとんどのライブラリを参照設定していません。

どのライブラリを選ぶかは、使うオブジェクトによって決まっています。

Word.Applicationを使いたいなら、Microsoft Word XX,X Object Libraryを選ぶ必要があります。XX.Xの部分には数字が入ります。どの数字が入るかは、お使いのPCのWordのバージョンによって異なります。

Microsft Word 16.0 Object Libraryを選んである参照設定。

レイトバインド

レイトバインドというのは、次のような宣言の仕方です。

Dim WdApp As Object

先ほどのアーリーバインドと何が違うかというと、Asの後ろです。

Word.Applicationという具体的なオブジェクトの種類が、Object型という曖昧な型に変わっています。

この宣言の仕方では、たとえ参照設定でWordのライブラリを選択していなくてもエラーになりません。

しかし、インテリジェンスがきかなくなります。

インテリジェンスというのは、コードを記述中にリストや候補を示してくれる親切機能のことです。

インテリジェンスの例。図ではWordのライブラリを参照設定してあるアーリーバインドの例です。WdAppと打った後、.(ドット)を打つと、図のように入力候補を示してくれます。
レイトバインドではドットを打っても入力候補は示されません(インテリジェンスがきかなくなります)

だったらアーリーバインドばかりでいいじゃないかと思われるかもしれませんが、問題は参照設定が各端末ごとに必要ということです。

アーリーバインドの問題点

参照設定というのは、各自にやってもらわないといけません。

あるVBAを作って配布したときに、アーリーバインドにしてあると、参照設定をユーザにやってもらわないといけません。

これがなかなか難しいのです。

かつてアプリ会社でパートをやっていたとき、VBAを作って配布した際の経験です。C言語とかバリバリに使いこなすSEさんたちですら、Excelの参照設定については「は?参照設定?何それ?」状態でした(という人もいました)。ですので、参照設定をしてもらうよう、手順書を作っていっしょに配布する必要がありました。

なお、C言語を知っているSEさんには、「参照設定というのはC言語で言うところの#include文です」と言うと分かってもらえました。javaならimport文でしょうか。閑話休題。

SEさんですらこうなのに、一般のユーザをや。

よく知恵袋で回答していますが、質問者たちに「このコードは参照設定が必要ですから、○○のライブラリを選択しておいてから使ってくださいね」と書いたところで、「参照設定って何ですか?」とさらに質問が来てしまうので、私は今はもうアーリーバインドは使いません。レイトバインドオンリーです。

最近回答した例。これもレイトバインドです。

レイトバインドの問題点

レイトバインドにも問題があります。

プログラムを実行したときに、動作が遅くなる点です。

しかし、この遅いというのは、体感ではあまり感じません。

原因は、実行時にメソッド(今回の例だとCalculate)が存在するかどうかチェックされるからです。事前バインドだとコンパイル時にチェック済みですので、その分早くなります・・・と言われていますが、実際にはそんなに差はないです。例えば次のようなコードを書いて実験しましたが、どちらもだいたい似たような時間でした(私のPCだと5秒程度)。

Option Explicit

Sub lateBindTest()
    Dim Ex As Object
    Dim ii As Long
    Const clStart As Long = 1
    Const clEnd As Long = 10
    Dim dStart As Double
    Dim dEnd As Double
    Dim dProc As Double
    
    dStart = Timer
    
    For ii = clStart To clEnd
    
        Set Ex = CreateObject("Excel.Application")
        Ex.Calculate
        
    Next ii
    Set Ex = Nothing
    
    dEnd = Timer
    
    dProc = dEnd - dStart
    
    Debug.Print "lateBindTest:かかった時間は" & dProc & "秒"
End Sub

↑レイトバインドの実験。私のPCで5.7734375秒でした。

Sub earlyBindTest()
    Dim Ex As Excel.Application
    Dim ii As Long
    Const clStart As Long = 1
    Const clEnd As Long = 10
    Dim dStart As Double
    Dim dEnd As Double
    Dim dProc As Double
    
    dStart = Timer
    
    For ii = clStart To clEnd
        
        Set Ex = New Excel.Application
        Ex.Calculate
        
    Next ii
    Set Ex = Nothing
    
    dEnd = Timer
    
    dProc = dEnd - dStart
    
    Debug.Print "earlyBindTest:かかった時間は" & dProc & "秒"
End Sub

↑アーリーバインドの実験。私のPCで5.90625秒でした。むしろアーリーバインドの方が遅いという結果になってしまいました。

これは何回もやって統計をとらないとだめなんでしょうけど、私はプログラマではないのでそこまでやる気力はないです。

まとめ

以上、VBAのアーリーバインドとレイトバインドの違いについて、配布の観点から説明しました。

よくある使い方が、最初に自分でコーディングするときにはアーリーバインドにしておいて、配布のときにはレイトバインドにしてしまうというものです。

そうするとコーディングの際インテリジェンスが効いて作業が早くなりますし、配布のときにはObject型に戻すので、参照設定の問題はなくなります。

何かのお役に立てば幸いです。

ここまでお読みいただきありがとうございました。