PR

■VBScript(Visual Basic Scripting Edition)を活用すれば,システム管理をはじめとする様々な作業を自動化できるが,原因不明のエラーに悩まされることも多い。
■VBScriptのコードを記述する場合に生じるエラーの多くは,比較的少数の原因によるものである。これらの原因,つまり変数,エラー処理構文,引用符,特殊文字または予約文字——の扱いを取り上げ,それらが引き起こす問題と解決法を紹介する。

(2006年1月号「Windowsテクノロジ徹底解説」より)



 仮にあなたが,Active Directory(AD)にある古いユーザー・アカウントを自動的に削除するスクリプトを何時間もかけて作成したところだとする。あなたはVBScriptについては初心者だが,毎月古いADのユーザー・アカウントを削除する作業はあまりに面倒なので,スクリプトを書く苦労は十分報われると確信していた。期待を胸に,完成したスクリプトをテスト用のネットワークで実行。ところが,どうしたことかスクリプトは途中で突然止まってしまった——。

 何がうまくいかなかったのだろうか? 考えられる原因は無数にある。しかし,パレートの法則(別名「80−20の法則」)を当てはめると,スクリプトのエラーのほとんど(およそ80%)は,比較的少数(およそ20%)の原因によるものであると言える。

 最近,何人かのスクリプトのエキスパートに,VBScript(Visual Basic Scripting Edition)のコードでよく見かけるエラーについて聞いた。彼らが仕事で,あるいはWindows IT ProやWindows Scripting Solutionsなどの雑誌掲載用コードをレビューする際に,最も多く見かけるエラー(構文エラーおよび実行時エラー)は,以下の4カ所で発生するという。(1)変数,(2)エラー処理構文,(3)引用符,(4)特殊文字または予約文字——である。以下では,これら4カ所で発生する問題と対策について具体的に説明していきたい。

変数宣言を強制する
 あなたは複数のサイトで構成されたネットワーク上にある各プリンタの情報を取得するために,何時間もかけてスクリプトを作成したところである。WMI(Windows Management Instrumentation)モニカとVBScript定数,およびstrComputer,colPrinters,printerなどの変数で頭が一杯なのに加え,画面を長時間にわたって凝視するうちに目も疲れてきた。最後のFor Each~Next構文で変数colPrinterを扱い始めたところで,ようやく終わりが見えてきた。あなたは急いでスクリプトを仕上げ,テストを開始した。だが,スクリプトが突然終了してしまい,早く帰宅できる望みは消えてしまった——。

 何が起きたのだろうか? 答えは今の文章の中にある。スクリプトを作成していて頻繁に発生するのがスペル・ミスである。この例では,プリンタのコレクションを扱う変数の名前を最初はcolPrintersと記述していたのが,次ではcolPrinterと記述している。「s」が抜けているのである。


△ 図をクリックすると拡大されます
図1●変数宣言を強制することによって引用符で囲んでいない文字列定数を発見できる例

△ 図をクリックすると拡大されます
図2●図1のコードを実行したときに表示されるエラー・メッセージ

△ 図をクリックすると拡大されます
図3●図1のコードでOption Explicitステートメントを省略した場合の実行結果
 Windows IT Proのテクニカル・ディレクタであり,ソフトウエア開発とコンサルティングを行う米TECAの社長でもあるMichael Otey氏は,「私が最もよく見かける問題は,Option Explicitステートメントを使っていないことだ。その結果,本来使用すべき変数と非常によく似た名前の変数をスクリプトで使用してエラーになる」という。この問題については,企業システムの自動化ソフトを開発する米SCRIPTMATIONの最高経営責任者兼チーフ・ソフトウエア・アーキテクトSteve Seguis氏など多くのスクリプトのエキスパートも同意している。Steve氏は,「例えば,oUser という変数をある場所で使ったかと思えば,別の場所ではoUsrと入力している。このような問題はOption Explicitステートメントを使って変数の宣言を強制すれば簡単に解決できる」と語る。

 VBScriptは,スペル・ミスの防止を支援する構文を備えている。確かにVBScriptでは,変数を使う際に明示的に宣言する必要はない。単に値を割り当てるだけでよい。しかし,野菜を食べ,毎日運動するのがすべての人にとって有益であるのと同様に,たとえ必要でないにせよ変数を明示的に宣言するのが一番である。

 変数を使用するに当たっては,スクリプトの先頭にOption Explicitステートメントを記述し,スクリプト・エンジンにDim,Private,Public,ReDimステートメントで明示的に宣言した変数だけを許可するように指示する。スクリプト・エンジンは宣言していない変数に遭遇すると,「この変数は宣言されていません」(エラー番号500)というエラー・メッセージを発生し,宣言していない変数の名前を教えてくれる。スクリプトの先頭にたった1行記述しておくだけで,デバッグにかかる時間を大幅に短縮できるのである。ただし,宣言していない変数が2つ以上ある場合,エラー・メッセージは最初に見つけたミスだけを表示する点に注意していただきたい。

 また,VBScriptコードでは,すべての文字列定数を2重引用符「"」で囲む必要がある。Option Explicitステートメントを使えば,宣言していない変数を見つけられるだけでなく,2重引用符で囲んでいない文字列定数も発見できる。例えば図1のコードでは,「PC1」を2重引用符で囲んでいないため,スクリプト・エンジンはこれを文字列定数ではなく,変数であると見なして「この変数は宣言されていません」というエラー・メッセージを表示する(図2)。

 一方,図1でOption Explicitステートメントを記述しなかったときは,コードを実行してもエラー・メッセージが表示されることはない。この場合,スクリプト・エンジンは,strComputerとPC1という2つの変数があると解釈する。従ってスクリプト・エンジンは,strComputer変数に「PC1」という値(文字列)を割り当てる代わりに,strComputer変数にPC1変数の値を代入してしまう。実行結果は図3のようになり,本来はEchoメソッドによって「PC1」と表示されるはずなのに何も表示されない。変数PC1の初期値が空であるためだ。

 変数によって発生する問題はほかにもある。「型が一致しません」「名前が二重に定義されています」といったエラー・メッセージに出会ったことがあるだろうか? これらのエラー,および変数に関連するそのほかのエラーの原因を以下に紹介する。