Open棟梁Project - マイクロソフト系技術情報 Wiki

目次

概要

vbsファイルの勘所、debugの方法、FunctionとSubの違い、エラー処理、などのトピック情報を纏めています。

vbscriptリファレンス

関数(mid, cint, len, split, など)、ステートメント(dim, if, for, call, function, など) など、言語のリファレンスは、以下を参照。

wscript, wshshell などの WSHのオブジェクトは、以下を参照。

Scripting.FileSystemObject? などの ファイル操作関連のオブジェクトは、以下を参照。

vbsのプログラミングは、下のユーザーズガイドから、必要なトピックを参照ください。

MS の Script Center では、豊富なサンプル例が検索できます。
左の選択肢から、用途や種類を絞り込んで、スクリプトの具体例が参照できます。

言語構文やプログラミングの解説は、ここでは割愛します。
上のガイドや、「vbs|vbscript やりたいこと」でググるなどしてください。豊富なサンプル、Q&Aが、ネット上に多数転がっています。
ネット上に転がっていたスクリプトを引用する際は、権利関係に注意ください。(特に、まるまる引用するような場合)

vbscript は、 Excelの VBA に似ています。Excel の モジュールシート に記述する感じで、vbsファイルに記述できます。
ただ、構文や機能に、できることの違いが少しあります。上の ユーザーズガイドから、「VBScript の機能で VBA に含まれていない機能」「VBA の機能で VBScript に含まれていない機能」を参照してください。

vbs と wsf

vbsファイルは、vbs と wsf の 2種類あり、どちらも Windows Scripting Host のスクリプトを記述します。
( そのほかにも、htmlの中、asp(active server pages)の中 にも vbscript を記述できますが、ここでは割愛。)

.vbs は vbscript のみを記述。

.wsf は xmlファイルで、 vbscript のほか jscript, 参照する TypeLib?, 参照する(取り込む)scriptファイル も記述することができます。wsfファイルは、ここでは解説しません、下を参照ください。
Windows スクリプト ファイル (.wsf) を使用する

Windows Scripting Host の実行ファイルは cscript.exe (コマンドライン用) または wscript.exe (Window用) です。
エクスプローラで vbsファイルをダブルクリックすると、既定で wscript.exe が使用されます。

実行は、コマンドプロンプトからで

 cscript.exe スクリプトファイル.vbs オプション

の様に実行。
cscript.exe 自身へのオプションは // で始まる形式で、スクリプトファイル.vbs への引数と並べて書きます。

vbsの勘所

以下、個別に。

「&」は文字列を連結する演算子です。数値や数字は文字列に変換して連結します。 文字列であることが自明な場合は 「+」でも文字列連結が出来ます。

wscript.stdout.writeline は 引数の文字列を、標準出力に出力します。cscript.exe でのみ動きます。 wscript.exe ではエラーになります。

  wscript.stdout.writeline "これはスクリプト。"
  for i = 0 to 9
    wscript.stdout.writeline "カウント " & i
  next
  wscript.quit 0

スクリプトで作り込む際には、下の様に、 print 関数を定義する、などするといいでしょう。

  sub print(v)
    wscript.stdout.writeline v
  end sub

sub と function

上の例の様に、sub ... end sub は、 値を返さない関数を定義します。
値を返す場合は、 function を使います。

   function amari(a, b)
     amari = ( a mod b )
   end function
   print amari( 20, 3 )

function の戻り値は 関数名 と同じ変数へ代入します。
関数の戻り値の型は指定できません。(vbやvbaにある function funcname(arg1, arg2) as type」 の as type は記述できません)

上の例にある「a mod b」 は、 a を b で割った剰余を求める演算子です。

functionの呼び出しは、値を必要とする場所(代入の右辺、別の関数の引数、式の途中) などに、「関数名(引数,..)」の様に記述して呼び出します。
また、値を必要としない場所では、「関数名 引数,..」の様に ( ) をつけずに記述します。
値を必要としない場所に ( ) をつけて記述する場合は、 「call 関数名(引数,..)」の様にして戻り値を無視するようにします。

subの呼び出しは、「call 関数名(引数,..)」「関数名(引数,..)」「関数名 引数,..」どの形式でも使用できます。

set と let

vbsで値を代入するときは、let 文を使います。 ただし、代入するものが object の場合は、 set 文を使います。

   let str1 = "abcde"
   str2 = "ABCDE"
   set fso = CreateObject("Scripting.FileSystemObject")

普通は、let は 省略して、上の str2 の代入の様に書きます。

上の関数の戻り値(function) の場合も、同じです。戻り値を返す関数の場合は、 関数名へ set を使って代入します。

   filename = "c:\temp\tempfile.txt"
   set fso = CreateObject("Scripting.FileSystemObject")
   set tmp1 = makeTempFile(filename)
   tmp1.writeline "てすと"
   tmp1.close
   set tmp1 = nothing

   function makeTempFile(fn)
     dim f
     set f = fso.OpenTextFile(fn, 2, True)  ' 2=書き込み, True=作成
     set makeTempFile = f
   end function

dim と 変数のスコープ

vbscriptでは、dim文で変数を定義します。
sub または function の中で定義した変数は、その関数の中がスコープになります。
関数の外で定義すると、グローバル変数になります。
また、class の中で定義することで、classのローカル変数にすることもできます。

vbscriptは、dim文を省略することもできますが、変数のスコープがはじめに現れた場所に依存して、関数内またはグローバルになります。

変数名の誤字によるバグを回避したり、変数のスコープを管理するためにも、vbsファイルの最初に「Option Explicit」を記述して、未定義の変数をエラーとして検出するようにしましょう。

dim文のほかに、 定数を定義する const や、 class を作成した際に class外部から参照させないための private もあります。

なお、vbs では、変数の型がありません。

 dim var1 as string~

の様に 「as 型」 を書くとエラーになります。
vbs では、全てが variant型で、代入した値や変数によって、型が変化します。
また、数値型や文字列型とは自動で変換されます。
後述の様に、object型とその他を明確に区別したい場合は、その型の値を代入します。

empty と null と nothing

変数の初期状態は empty です。

dim str1
if isempty(str1) then
  print "str1 is empty"
end if

なにか代入するとその値の型になります。型の名前は TypeName? 関数で取得できます。

str1 = 123
if NOT isempty(str1) then
  print "str1 is not empty. is " & typename(str1)
end if

nullやemptyを代入することも出来ます。

 str1 = null
 str1 = empty

オブジェクトを代入すると、オブジェクト型になります。

 set fso = CreateObject("Scripting.FileSystemObject")
 if isobject(fso) then
   print "is object"
 end if

これらを区別するには、

 isempty(変数名)
 isnull(変数名)
 isobject(変数名)
 変数名 is nothing

を使います。

nothing も オブジェクトの一種です。

 set obj1 = nothing
 if isobject(obj1) then
   print "is object"
 end if
 if obj1 is nothing then
   print "is nothing"
 end if

関数を定義する際、戻り値がある場合は、値かオブジェクトかで、呼び出し元での 代入文が変わりますので、どちらを返すのか決めて設計しましょう。

関数への引数では、値とオブジェクトのどちらでも受け入れる場合は、isobject の真偽を確認して場合わけをします。

下は、配列へ1つ追加する関数の例です。

 function add(dims, e)
   Redim Preserve dims( ubound(dims) +1 )
   if isobject(e) then
     set dims( ubound(dims) ) = e
   else
     dims( ubound(dims) ) = e
   end if
 end function

 dim arr
 arr = array()     ' 要素0個の配列
 add arr, "123"    ' 文字列を追加
 add arr, fso      ' オブジェクトを追加

実際に、値とオブジェクトを混在する配列は使用しないかもしれませんが(扱いづらいですし)、こんな感じで両対応の関数を作ることが出来ます。

ファイル操作

ファイル操作は、Scripting.FileSystemObject? を使用します。

   const ForReading = 1
   set fso = CreateObject("Scripting.FileSystemObject")
   set ts = fso.OpenTextFile("c:\temp\tempfile.txt", ForReading)
   print ts.readall
   ts.close
   set ts = nothing
   set fso = nothing

Scripting.FileSystemObject? によるファイル操作は、テキストファイルのみ動作します。文字コードは Windows既定, Unicode を指定できますが、 UTF-8の様な文字コードは扱えません。
バイナリデータも、chr(10) の様に文字コードを指定した文字列として扱うことは可能ですが、ファイル入出力時に、改行コードやBOM文字、EOF文字が処理されて、期待するバイナリファイルにならないことがあります。

数値と数字

数値と数字は、使用する場所によって、数値だったり文字列だったりします。
できるだけ、意識して使い分けましょう。

   str1 = "456"
   int1 = cint(str1)
   long1 = clng(str1)
   int2 = int(int1/10)
   int3 = cint(int1/10)
   int4 = str1 + 123
   str4 = str1 + "123"

cint() は 16bit整数に変換、 clng() は 32bit整数に変換、int() は intに切り捨て。
この例の int2 には 45 (45.6を切捨て)、 int3 には 46 (45.6を四捨五入) が入ります。
int4 には 579、 str4 には "456123" が入ります。

文字と文字列

文字も文字列も " " で囲んで記述します。

    str1 = "123456"
    str2 = mid(str1,3,1)
    str3 = """123""と""456"""

mid は 文字列の一部を返します。 C# や perl の substring に似ています。
mid(文字列,開始位置,長さ) で、 開始位置は0が1文字目です。
「"」自身を文字列中では "" として記述します。

vbscript 内部では、文字列はunicodeで表現されているので、半角/全角の区別はありません。
vbscript には、 文字列と文字の区別はありません。 長さ1の文字列で代用します。

   str2 = chr(9)
   str3 = "これは\0で区切っています" & chr(0) & "続きもある"

chr() は 指定した文字コードが1文字の、長さ1の文字列を返します。
chr(0) は C++ では \0 で文字列の終了ですが、 vbscript は 文字列は長さで管理していて、\0 も 文字列中に含めることが出来ます。

if文

if 文は、 then の右に 処理を1つ書くか、 then の下の行に 処理を複数行書きます。
then の下に書いたときは、 elseif か else で続けて、 end if で閉じます。
then の右に書いたときは、 end if は省略できます。

 str4 = "これはどんな文字列かな"
 if mid(str4,3,1) = "ど" then print "「ど」があるね"
 if instr(str4,"文字") >= len(str4)/2 then
    print "後半に ""文字"" がある"
 end if

vbscript の if文は、式を全て評価してから、if文全体の真偽を判定します。

 set obj = func1()
 if (NOT obj is nothing) and obj.flag = 2 then
   ' foo
 end if

この例の場合、obj が オブジェクトであっても、なくても、.flag を参照するので、obj が オブジェクトでなかった場合に、エラーになります。

下の様に、if文をネストさせて、式の評価順に依存しないようにします。

 if NOT obj is nothing then
   if obj.flag = 2 then
     ' foo
   end if
 end if

継続行 と コメント

vbscriptでは、 「 _」で次の行へ継続( _ の前にスペースあり)、「'」 があると行末まで無視します。

str1 = "あいうえお"
str2 = mid (str1, _
            instr(str1, "う") -1 )  ' "う" 以後の文字列を取り出す

instrは、文字列を含む位置を返します(1~、含まないなら0)。
mid は 文字目が 0 なので、 instrの戻り値-1 の場所を指定することで、「含むならその文字以後、含まないなら、全体」という文字列の取り出し方ができます。

エラー処理

エラーは、自分で値チェックなどで検出する論理エラーのほか、WSHその他が発生させるランタイムエラーがあり、ランタイムエラーが発生すると、WSHそのものがエラー終了します。
ランタイムエラーをvbs内で処理するには、on error resume next を使います。

COMなどのオブジェクト呼び出しの先でエラーが発生した場合も、ランタイムエラーになります。

ランタイムエラーを処理するには、on error resume next を使用して、ランタイムエラー時に vbsが設定する Err変数 を参照してエラー判定をします。

 err1 = 0   ' エラー番号
 on error resume next  'ランタイムエラーでvbsを終了させない
 Err.Clear             'Err変数をクリア
 set obj1 = CreateObject("hogehoge.hogehoge1")
 if Err.Number <> 0 then err1 = Err.Number   'ランタイムエラー判定
 if err1 = 0 then
   if obj1.hagehage("てすと") <> 0 then
     err1 = 1              ' 論理エラー
   end if
 end if
 if err1 <> 0 then
   print "エラー発生 " & err1
 end if
 wscript.quit err1     ' エラー番号 を vbsの終了コードに

debug方法

vbsのデバッグは、

Script Debuger, Script Editor は、 cscript.exe で実行するときに //x をオプションに指定して実行すると、debugger が起動して、ステップ実行、 変数の確認 などができます。


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS