t-hom’s diary

主にVBAネタを扱っているブログ…とも言えなくなってきたこの頃。

VBAからVBScriptへマクロを移植する方法

今回はVBScriptをやってみたいVBA使いの方へ、VBAで書いたコードをVBSに移植する方法を説明しようと思う。
特にあまり知られていないであろう最初から移植性を意識したコードを書く方法について紹介する。

執筆のきっかけになったのはこちらの記事。
chemiphys.hateblo.jp

VBScriptの作り方

テキストエディタでコードを書いて、拡張子をvbsとして保存するだけ。
実行するにはダブルクリックする。
ドラッグ&ドロップしたファイルを処理するようなスクリプトも作れる。

VBAとの違い

エントリーポイント(プログラムの開始点)がファイルの先頭

VBAの場合、Subプロシージャを複数作ってそれぞれがエントリーポイントになるけれど、VBSの場合はファイルの先頭がエントリーポイントになる。
つまりSubプロシージャなどを書かずに、いきなりMsgBox "Hello"と書けば動くのだ。

意外に知られていないのは、普通にSubプロシージャも書けるということ。
エントリーポイントからCallしてやれば動作する。

Call Main
Sub Main()
    MsgBox "Hello"
End Sub

VBAと同じようにプロシージャの集まりとして作っておいてCallするという方法をとれば、VBAプログラムとの高い互換性を保ちつつスクリプト化できるのでおすすめ。

変数宣言に型を持たせられない

VBAならDim a As Integerなどと書けるところ、VBSではDim aとしか書けない。
私はよく、Dim a 'As Integerという風にAs以降をコメント化している。

イミディエイトウインドウが使えない

つまりVBAから移植するためにはDebug.Printは別の方法で書き直さないといけない。
Debug.Printはそもそもデバッグ機能なので本番マクロで使うのもどうなのって思うけど、個人用マクロで重宝するのは確か。

無いなら作ってしまおう。

'下で定義するDebugPrintクラスをもとに変数Debugを準備
Dim Debug: Set Debug = New DebugPrint

Call Main
 
Sub Main()
    Debug.Print "こんにちは"
    Debug.Print "さようなら"
    Debug.Flush 'FlushしてはじめてPrintした内容がMsgBoxで表示される。
End Sub

'以下にDebugPrintクラスを定義
Class DebugPrint
    Private message

    Public Sub Print(msg)
        message = message & msg & vbNewLine
    End Sub

    Public Sub Flush()
        MsgBox message
        Call Clear
    End Sub

    Public Sub Clear()
        message = ""
    End Sub
End Class

こうするとVBAからの移植性はアップする。
メインコードをわざわざ書き直さなくても、Flushを呼ぶという変更だけで済む。

参照設定できないので遅延バインディングになる

参照設定が使えないため、外部オブジェクトの作成はCreateObjectで行うことになる。
VBAで参照設定をやっている場合、以下を参考にCreateObject方式に書き換える。

参照設定とCreateObjectの対応リスト - You.Activate

その他の特徴

  • Rnd関数を使用する場合、その前の任意の行に「Call Randomize()」を挿入しないとランダムにならない。
  • 配列の宣言にDim a(1 to 3)といった指定ができず、3つの要素がほしい場合はDim a(2)と書いて0,1,2の3つを作るしかない。
  • Select文がVBAより低機能で基本的な書き方しかできない。
  • 日本語変数が利用できない。

追記

Twitterで、有益なリンクが流れてきたので追記(id:imihitoさんありがとう)
VBA の機能で VBScript に含まれていない機能

VBSではCollectionが使えないようなので、代替手段として以下の記事もどうぞ。
imihito.hatenablog.jp

VBAからVBScriptへマクロを移植する方法

  1. マクロをそのまま貼り付ける。
  2. 変数宣言から型の宣言を取り除く(あるいはコメントアウト)。
  3. エントリーポイントから実行したいマクロをCallする。
  4. 参照設定からCreateObject形式に切り替える。

上記で大体動くが、Debug.Printを使っていたり、Select文の高度な機能(Is比較、n To n表記など)を利用している場合は修正が必要になる。

VBScriptからVBAへマクロを移植する方法

上位互換とは言わないが、基本的に、Sub~End Subでくくってやれば大体のスクリプトはそのまま動く。
VBAも型宣言なしで動作するし、CreateObjectにも対応しているのでVBSからVBAへは極めて移植性が高い。
ただしWScript.Echoを使っている場合はMsgBoxかDebug.Printへ変更が必要である。

長いスクリプトをそのまま貼り付けると、長いプロシージャが出来上がるのであまり良くない。
VBScriptにおいても最初からプロシージャにコードを書くようにし、適切にプロシージャを分割しておくとVBAに移植してもスッキリと見通しの良いコードになる。

VBScriptにオススメのエディタ

やはりVBAで使用するVBエディタが一番楽である。

VBAで最初からVBSへの移植性を意識したプログラムを書く場合、外部オブジェクトの利用は以下のように参照設定とCreateObjectのハイブリッドにしておくと良い。

Dim fso As FileSystemObject
Set fso = CreateObject("Scripting.FileSystemObject")

そうすると、VBエディタで書くときはオブジェクトメンバーの入力候補が出るし、VBSに直すときはこのようにAs以降をコメントアウトするだけで済む

Dim fso 'As FileSystemObject
Set fso = CreateObject("Scripting.FileSystemObject")

VBScript関連書籍

まずVBAができる人にお勧めするのは以下の1冊。

WSHクイックリファレンス 第2版

WSHクイックリファレンス 第2版

これはFileSystemObjectやDictionaryなどのWSHのオブジェクトについて使い方がわからないときにリファレンスとして重宝する。
また、VBAでもこれらのオブジェクトは多用するが、VBAの書籍よりも詳しく書かれている。
VBScriptJScriptに両対応しているのでJavaScript派の方にもおススメ。

以下はあまり良く知らないけど、実質VBScriptの関連書籍って現行品はこれくらいしか無いので一応ひととおり掲載だけしておく。

Windows自動処理のための WSHプログラミングガイド 増補改訂版

Windows自動処理のための WSHプログラミングガイド 増補改訂版

[改訂版] VBScriptポケットリファレンス (POCKET REFERENCE)

[改訂版] VBScriptポケットリファレンス (POCKET REFERENCE)

最速攻略 VBScriptサンプル大全集 Windows7/Vista/XP/2000対応

最速攻略 VBScriptサンプル大全集 Windows7/Vista/XP/2000対応

VBScript逆引き大全500の極意

VBScript逆引き大全500の極意

ただ私の場合はほぼVBAって感じのVBScriptを書くのであまり書籍を参考にした覚えはないな。
ただドラッグ&ドロップ操作などのVBSに特有の機能もあるので一冊くらい専門の本を持っておいても良いかなとは思う。

VBSでクラスを使う方法

以下の記事がおススメだけれど、まずクラスって何って方にはちょっとザックリしすぎてるかなとは思う。
http://tuka.s12.xrea.com/index.xcg?p=VBS%A4%CE%A5%AF%A5%E9%A5%B9%A5%AA%A5%D6%A5%B8%A5%A7%A5%AF%A5%C8

クラスについてよく分からない方はまずVBAでクラスを使うこちらの記事と
ateitexe.com

手前味噌だけど、以下の記事がオススメ。
thom.hateblo.jp

当ブログは、amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイト宣伝プログラムである、 Amazonアソシエイト・プログラムの参加者です。