VBA 最奥義（たぶん）クロスプラットフォームスクリプト（仮）

#VBA高難度技法
- Win32APIを使用（Sleepを除く）
- 正規表現
- VBS,Jscript,Powershellのスクリプトと連携使用する
- クロスプラットフォーム（仮）

クロスプラットフォームとはオフィスのVBAを別のオフィスで使用することOutLookのVBAをExcelで使うなど

#準備
必ず参照設定すること
ただし参照設定（アーリーバインディング、事前バインディング）だと、バージョンが上がったとき動かない可能性はある。なので完成したらレイトバインディングにしてもよい。

#使用のポイント
##変数の宣言
 1. 変数の宣言は強制Option Explicit
 2. 変数は必ず親の識別子をつけること
 3. 事前バインディングに加えてアプリケーションの変数を宣言すること
 
たとえばExcelは
Dim wb as workbook
を
Dim xlApp As Excel.Application
Dim olApp as Outlook.Application
Dim wdApp as Word.Application
Dim ppApp as PowerPoint.Application
Dim pbApp as Publisher.Application
Dim acApp as Access.Aplication
Dim wb As Excel.Workbook
Dim wDoc as Word.Document
Dim pbDoc as Publisehr.Document
とする。(上記の例のうち、実際は参照設定したものだけ宣言してください）
例外はアクセスで、ADODB,DAOで接続することが多く、らアプリケーション自体の宣言をすることが少ない。
オブジェクトの変数の宣言は必ず親をつけないとVBAが判別できない。

##定数は数字か定数にした方がよい
たとえばwdXXX=1という定数がある場合
word.wdXXXもしくはwdApp.wdXXXのいずれかの識別子をくわえないとバグが出ます。
この使い分けがどういう基準なのか全く資料がありません。
なのでこの方法で修正するより、定数Const で設定した方法がいいと思われます。
それかイミディエイトで ？wdXXXとすると数字が返るのでその数字を直接代入します。変換してもよいです。

##クロスで作るときは最初別々に組み立ててから合成するが、上記に注意する。
エクセルからワードを起動させて処理する場合、まずワードのVBAを組んでから、Excelに取り込みます。
このため、ワードの段階でオブジェクトの変数に識別子を施します。また、定数もこの時点で数字い変換しておくと安全です。

#参考
これらの参考を見てもオブジェクトのことだけで、定数に識別子を使う必要があることについて全く記載がない。
たぶんそれについて記載したのはこの記事だけかもしれない。それくらいクロスプラットフォームスクリプト（仮）はマイナーな技らしい。しかし、連携して使うためにはこの技を避けて通ることはできない。

[OLE プログラム識別子、遅延バインディング、および事前バインディング (Project)](https://msdn.microsoft.com/ja-jp/library/office/ff866799.aspx)
##レイトバインディング
Sub CreateWordDoc_Late() 
    Dim wdDoc As Object 
    Set wdDoc = CreateObject("Word.Document") 
    wdDoc.Save 
End Sub

##Microsoft Word 15.0 Object Library への参照を追加
Sub CreateWordDoc_Early() 
    Dim wdDoc As Word.Document 
    Set wdDoc = New Word.Document 
    wdDoc.Save 
End Sub
ここでのポイントは wdDoc As New Word.Documentとしないこと
##事前バインディングを使用しExcel ワークシートを作成する
####Microsoft Excel 15.0 Object Library への参照を設定
```vbnet:CreateExcelWorkbook_Early()

Sub CreateExcelWorkbook_Early()
    Dim xlApp As Excel.Application
    Dim xlWorkbook As Excel.Workbook
    Dim xlWorksheet As Excel.Worksheet
    
    Set xlApp = Excel.Application
    xlApp.Visible = True
        
    Set xlWorkbook = xlApp.Workbooks.Add
    Set xlWorksheet = xlWorkbook.Worksheets(1)
    
    xlWorksheet.Cells(1, 1).Value = "Data from Project"
    xlWorksheet.SaveAs ("C:\Project\VBA\ProjectWorksheet.xlsx")
    xlWorkbook.Close
    xlApp.Visible = False
End Sub
```
ActiveX コントロール


####FM2.0
次の表に示す ActiveX コントロールを作成するには、対応する OLE プログラム ID を使用します。ユーザー フォームを挿入すると、Project により、事前バインディング用に Microsoft Forms 2.0 Object Library への参照が設定されます。Access,Excelも同様。

|作成するコントロール|使用する識別子|
|:----:|:----:|
|CheckBox|Forms.CheckBox.1|
|ComboBox|Forms.ComboBox.1|
|CommandButton|Forms.CommandButton.1|
|Frame|Forms.Frame.1|
|イメージ|Forms.Image.1|
|Label|Forms.Label.1|
|ListBox|Forms.ListBox.1|
|MultiPage|Forms.MultiPage.1|
|OptionButton|Forms.OptionButton.1|
|ScrollBar|Forms.ScrollBar.1|
|SpinButton|Forms.SpinButton.1|
|TabStrip|Forms.TabStrip.1|
|TextBox|Forms.TextBox.1|
|ToggleButton|Forms.ToggleButton.1|

Microsoft Access
次の表に示す Access オブジェクトを作成するには、対応する OLE プログラム ID の 1 つを使用します。バージョン番号を示すサフィックスを付けずに ID を使用すると、マクロを実行するコンピューターにある最新バージョンの Access でオブジェクトが作成されます。事前バインディング用に、Microsoft Access 15.0 Object Library への参照を設定します。バージョン番号アリはアップデートで使えなくなるため使用禁止。

|作成するオブジェクト|使用する識別子|
|:----:|:----:|
|Application|Access.Application、~~Access.Application.15~~|
|CurrentData|Access.CodeData, Access.CurrentData|
|CurrentProject|Access.CodeProject、Access.CurrentProject|
|DefaultWebOptions|Access.DefaultWebOptions|

Microsoft Excel

|作成するオブジェクト|使用する ID|コメント|
|:----:|:----:|:----|
|Application|Excel.Application、~~Excel.Application.15~~||
|Workbook|~~Excel.AddIn~~|たぶんProjectの解説で普通はExcel.Workbook|
|Workbook|Excel.Chart、~~Excel.Chart.8~~|グラフ用とそのデータ用の 2 枚のワークシートを含むブックを取得します。グラフのワークシートがアクティブなワークシートになります。|
|~~Workbook~~|~~Excel.Sheet、Excel.Sheet.12~~|~~1 枚のワークシートを含むブックを取得します。~~|

[シート上のコントロールの値クリア](http://www.moug.net/tech/exvba/0040034.html)
じっさいにFM2.0の識別子を使用した例。

[Microsoft Office Visio オートメーション リファレンス プロパティ P ProgID プロパティ ](https://msdn.microsoft.com/ja-jp/library/cc345182.aspx)

[VBAシステム開発‎ > ‎1. VBAの世界‎ > ‎第４章‎ > ‎4.1 COMとは‎ > ‎ ](https://sites.google.com/site/compositiosystemae/home/vbaworld/upper/whatiscom/guid)

 - CLSIDに一対一で対応する、人間に理解できるID。「ライブラリ名.クラス名」で表現される。
 - CreateObject関数で使用する文字列が該当する。また、事前バインディング時は変数型として宣言できる(稀にできないこともある)
 -  ライブラリのバージョンに依存するProgIDをIndependentProgIDというが、これは通常使用されることはない。
 -    同じライブラリに複数バージョンが存在する場合には、レジストリにCurIDが指定され、ここに格納されているIndependentProgIDがカレントとして使用される。

複数のバージョンが存在する場合、カレントとして指定されているバージョンが存在し、実行時バインディングで使用するCreateObject関数を使用したオブジェクト生成では、カレントバージョンのオブジェクトが生成されます。
これに対し、参照設定によりコンポーネントを参照した事前バインディングでは、参照設定したバージョンが使用されます。
上記のような状況は非常に稀ですが、プログラムにミスがないのに、オブジェクトの生成に失敗する場合には、この問題を検討してみると良いと思います。（なお、検証環境のWindowsVista+ADO(カレントVer6.0)では再現できませんでした。）

以上からバージョン名のあるものは使ってはいけない。

[OLE プログラム ID](https://msdn.microsoft.com/ja-jp/library/Cc329655.aspx)
Projctと同様の解説だが。
Microsoft Office Web コンポーネント
Microsoft Office Web コンポーネント (OWC) は廃止されたため、Project と共にインストールされません
という点が記載されていない。
[ProgIDの調べ方について](https://qa.atmarkit.co.jp/q/4784)
プログラム（というか単に.exe）が全部COMオブジェクトというわけではない。