(for Internet Explorer)
← ▼
→ VBA
→ VBScript ポケットリファレンス
→ VBSReference
→ WSH 2_0 (Web)
VBScript (WSH)
→ 文法、制御構文
→ パラメータ （コマンドライン）
→ プログラム起動
→ ファイル操作
→ 演算子、型
→ 文字列
関連
Windows の標準的なスクリプトです。拡張子= (*.vbs)
Windows2000 以降ではデフォルトで入っています。
WSH (WScript.exe） が VBScript などのスクリプトを解析して実行します。
COM オブジェクトを通して、Windows や MS-Office を操作できます。
Windows Script Encoder で、バイナリ形式にすることもできます。
→ エラー、デバッグ
→ ユーザーインターフェイス
→ 標準入出力
→ 変数、Nothing、配列
→ レジストリ
→ Windows スクリプト テクノロジ (Web)
→ WScript.Shell リファレンス - Microsoft (Web)
→ VBScript関数リファレンス - Yoshio Kanaya (Web)
→ vbslib - Vector (Web)
→ vbslib - SagePlasir21 (Web)
→ クラス
→ VisualBasic
→ vbslib
参考
.vbs ファイルをダブルクリックしてから実行開始まで時間がかかるときは、ウィルス
対策ソフトのスクリプトに関するチェックをしないようにしてください。 チェックをしなく
ても、Windows のセキュリティ機能によって、ユーザーの許可無く悪意のあるスクリ
プトが実行されることはありません。
→ デバッガのインストール
→ bashlib
→ PowerShell
← ▼ ▲
新規 VBS ファイルの作成
メモ帳を開いて、VBS を記述し、ファイルを保存するときにファイル名の最後に .vbs を
付けてください。
→ new_vbs
← ▼ ▲
特殊記号一覧 （VBScript）
Sub
→ 関数
Function
Class
→ クラス
' comment
( )
→ 関数
→ 配列
.
→ クラス
new
Set
&
→ 文字列連結
→ 16進数
← ▼ ▲
While cond
WEnd
Do
Exit Do
Loop
Do
Exit Do
Loop While cond
For i=1 To 4 Step 2
Exit For
Next
If cond Then
...
ElseIf cond Then
...
Else
...
End If
Select Case value
Case value
Case 0, 1
Case 2 to 5
Case Else
End Select
For Each a In コレクション
Next
コレクション(0)
コレクション.Count
→ VB Script ポケットリファレンス p028
文法、制御構文
Do Until cond
Exit Do
Loop
GoTo も無い。
' コメント
分岐
繰り返し
If a = "" Then
If a <> "" Then
If a <= "" Then
コメント
→ コメント
→ 分岐
→ 繰り返し
→ 関数、コール
If cond Then ...
→ エラー処理, On Error
停止、終了
WScript.Sleep( 1000 )
WScript.Quit
→ 停止、終了
→ クラス
→ WScript::Quit
→ WScript::Sleep
If cond Then ... : Else ...
If cond Then ... :_
Else ...
If cond Then
...
ElseIf cond Then ... : ElseIf cond Then ... Else ... End If
If UCase("abc") = UCase("AbC") Then
大文字小文字を区別しない比較
UCase
If cond1 and cond2 Then
and
For Each の中で Exit For しないで
ループから抜けたとき、a は Empty になります。
→ 複合条件文 And Or Not
→ +, & 演算子、型
型判定
真 = 偽以外、 偽 = False or 0 or Empty or Null
If a Is b Then
同じオブジェクトかどうかを判定します。
参考
キーワード：
While WEnd
For Each In
Do Loop
Until は偽の
ときにループ
For Each s In Array( "A", "B", "C )
continue
C言語の continue に相当する予約語はありません。
ガード節
ループ内の
は、次のようにコーディングしてください。
Do
do_it = True
If ... Then _
do_it = False '// continue as カード節
If do_it Then
: 通常処理
End If
'// 中断したときだけループするなら、ここで If do_it Then Exit Do
Loop
→ NaturalDocs 対応コメント
関連
(Array( "no", "yes" ))(( value )and 1)
三項演算子相当の式
Do While cond
Exit Do
Loop
→ Do...Loop ステートメント (Web)
→ Transpose
文を実行する順番を入れ替えます。
do_it
← ▼ ▲
main xx, 12
Sub main( x, ByVal y )
Exit Sub
End Sub
x = f( 0 )
Function f( x )
Set f = Nothing
End Function
関数、コール
→ プログラム起動
引数は、参照渡し(call by reference) なので、関数内で x を変えると、関数から抜け
ても変わっています。
ByVal を付けると 値渡し(call by value) です。 ByRef を付けると参照渡しです。
f( , 1 )
引数の省略ができます。
省略した引数は、VarType( a ) = vbError になります。
ただし、VBS で定義した関数やメソッドは、最後の引数を省略できません。
引数の数が違うというエラーに、最後をコンマだけにすると構文エラーになります。
COM オブジェクトのメソッドは省略できます。
→ GetRef
引数が１つのときは、Sub でも括弧付きで呼び出せてしまいますが、これは Sub の
第1パラメータに渡す前に評価している（+0のように効果の無い計算をしている）
ことになります。 このとき、評価後の値が渡るので、ByRef の引数であっても、
値渡しになり、関数内で引数の変数に設定した値を、呼び出し元が取得することが
できなくなります。
ByRef の引数に、オブジェクトのプロパティ (例：obj.prop）を渡すと、参照渡しには
なりません。 一度、単純変数を引数に指定して呼び出した後で、単純変数から、
プロパティに設定してください。
値渡しと参照渡し
引数の省略、可変長引数、Option_ 引数
参照返し
→ Dictionary::Item
引数で出力するときは、呼び出し側ですぐ分かるように、一旦 out 変数に入れる方法も
あります。out 変数から代入されたところから、s が変化した場所が分かります。
Dim s, out
GetString out
s = out
→ 値渡しと参照渡し
→ 引数の省略、可変長引数、Opt 引数
関連
→ Array 関数
→ LoadXML (vbslib)
→ new_ClassA_array (vbsool)
FuncA Array( ,,2 )
FuncA "<PARAM param1='abc'/>"
VBS で定義した関数やメソッドに、任意の数の引数を取りたいときは、Array 関数や
XML を経由する方法があります。
参考
オプション的な引数（マイナーな引数）は、Option_ 引数にするとよいでしょう。
Option_ 引数は、通常の引数列の最後に加える引数です。（言語仕様ではなく応用です）
Option_ 引数は、通常 Empty を指定しますが、Integer 型（フラグ変数）やクラスなどを
使えばどんなパラメータも追加できます。 ちなみに Option は VBScript の予約語なので
Option_ にしています。
Sub FuncA( ParamA, ParamB, Option_ )
定義例：
使用例：
FuncA 1, 2, Empty
← ▼ ▲
擬似マルチスレッド
'***********************************************************************
'* Function: Func
'***********************************************************************
Sub Func()
Set threads = new ArrayClass
threads.Add = FuncStart()
:
Do
is_waiting = True
For Each thread In threads.Items
is_waiting = is_waiting and _
_
thread.Dispatch
If IsEmpty( thread.StepIndex ) Then _
Exit Do
Next
If is_waiting Then _
WScript.Sleep 100
Loop
End Sub
'***********************************************************************
'* Function: FuncStart
'***********************************************************************
Function FuncStart()
Set a_Me = new FuncClass
local_variable = "A"
'// ================================ Start of pseudo multi thread.
a_Me.StepIndex = 2
a_Me.local_variable = local_variable
End Function
'***********************************************************************
'* Class: FuncClass
'***********************************************************************
Class FuncClass
Public StepIndex
'// Local variables
Public local_variable
'***********************************************************************
'* Method: Dispatch
'***********************************************************************
Public Sub Dispatch()
Select Case Me.StepIndex
Case 2: Me.Step2
Case 91: Me.FinalizeStep1
Case Else: Error
End Select
End Sub
'***********************************************************************
'* Method: Step2
'***********************************************************************
Public Sub Step2()
local_variable = Me.local_variable
'// ================================== End of pseudo multi thread.
local_variable = "B"
'// ================================ Start of pseudo multi thread.
Me.StepIndex = 91
Me.local_variable = local_variable
End Sub
'***********************************************************************
'* Method: FinalizeStep1
'***********************************************************************
Public Sub FinalizeStep1()
local_variable = Me.local_variable
'// ================================== End of pseudo multi thread.
local_variable = "C"
'// ================================ Start of pseudo multi thread.
Me.StepIndex = Empty
'// ================================== End of pseudo multi thread.
End Sub
End Class
'* Section: Global
プリエンプション（スレッドのコンテキスト・スイッチ）を発生させる代わりに、関数から戻って、
ユーザーがスレッドを切り替えることを
擬似マルチスレッド
と呼びます。
擬似マルチスレッドに対応するには、関数（処理）の途中からリターンする 「中断」 機能だけでなく、
関数の途中から 「再開」 する機能を、関数に組み込む必要があります。 そのため、途中の状態（
ローカル変数だった変数、ループ変数）は、スレッドのコンテキスト（クラス）に配置します。
他のスレッドやプロセスの処理を待つ直前で、関数を区切ります。
→ スレッド (コンピュータ) - Wikipedia (Web)
参考
→ 【簡単理解】Javaのスレッド・マルチスレッドとは？ (Web)
← ▼ ▲
プリフェッチ
→ プリフェッチ - Wikipedia (Web)
必要になったときに速く実行できるように、事前に読み出したりダウンロードしておくこと。
プリフェッチしたデータは、キャッシュに格納されます。
参考
一般的なスレッド
プリフェッチするスレッド
プリフェッチするときの動作を示します。
プリフェッチ（リード開始）要求
キャッシュにない状態
リーディング状態
キャッシュにある状態
リード要求
→ 擬似マルチスレッド
要求に対する処理が、状態によってどのように変化するかを一覧します。
キャッシュにない状態
リーディング状態
（ミス ヒットした場合）
キャッシュにある状態
プリフェッチ要求
リード要求
リード開始
なにもしない
なにもしない
プリフェッチ要求と、リード完了待ち
リード完了待ち
キャッシュからリード
リード完了待ち
キャッシュからリード
プリフェッチ要求をする API 関数では、プリフェッチするスレッドに関する情報にアクセスできる
オブジェクトを返してください。 たとえ、すでにキャッシュにある状態でもです。 そうすれば、
リード要求をする API 関数から、プリフェッチ要求をする API 関数を呼び出すだけで、
その返り値から状態（リーディング状態、キャッシュにある状態）を判断できるようになるから
です。 また、キャッシュに関する情報（パスなど）も得られます。
プリフェッチが完了した順番でリード要求をしない場合（プリフェッチを「開始」した順番でリード
要求をする場合などでは）、最初に開始したデータが大きいと、プリフェッチとリードが並列して
処理できる期間が少なくなりますが、正しく処理されます。 ただし、キャッシュが有限の場合、
キャッシュの内容の置き換えによって再度プリフェッチが必要になる場合があります。
→ DownloadStart (DownloadAndExtractFileIn7zClass)
← ▼ ▲
複合条件文 And Or Not
Func 0, 0, out '// False
Func 1, 0, out '// False
Func 0, 1, out '// False
Func 1, 1, out '// True
WScript.Echo out
Sub Func( a, b, out )
and_ = ( a > 0 )
If and_ Then and_ = ( b > 0 )
If and_ Then
out_bool = "True"
Else
out_bool = "False"
End If
out = out & a &" and "& b & " = "+ out_bool + vbCRLF
End Sub
If not IsEmpty( obj ) and obj.VarA = 1 Then
C言語と異なり、and の両方は必ず実行されるため、
上記の文は obj が Empty のときに例外が発生します。
次のようにしてください。
and_ = ( not IsEmpty( obj ) )
If and_ Then and_ = ( obj.VarA = 1 )
If and_ Then
C言語式の And 文 (&&)
→ C言語式の And 文 (&&)
検証コード：
C言語式の Or 文 (||)
→ C言語式の Or 文 (||)
検証コード：
or_ = ( IsEmpty( obj ) )
If not or_ Then or_ = ( obj.VarA = 1 )
If or_ Then
C言語と異なり、or の両方は必ず実行されるため、
上記の文は obj が Empty のときに例外が発生します。
次のようにしてください。
If IsEmpty( obj ) or obj.VarA = 1 Then
Func 0, 0, out '// False
Func 1, 0, out '// True
Func 0, 1, out '// True
Func 1, 1, out '// True
WScript.Echo out
Sub Func( a, b, out )
or_ = ( a > 0 )
If not or_ Then or_ = ( b > 0 )
If or_ Then
out_bool = "True"
Else
out_bool = "False"
End If
out = out & a &" or "& b & " = "+ out_bool + vbCRLF
End Sub
×
×
obj.VarA = 1
obj.VarA = 1
IsEmpty( obj )
obj.VarA = 1
not IsEmpty( obj )
obj.VarA = 1
まずは、C言語のように and or を含む文を記述してから、下記のリンク先を
参照して対処してください。
VB では C言語と異なり、and や or の後の条件文を必ず実行します。
このために、前の条件文によって後の条件文でエラーになることがあります。
not IsEmpty( obj )
IsEmpty( obj )
○
○
→ 論理演算、ビット演算
関連
not
not
C言語式の Not 文 (!)
→ C言語式の Not 文 (!)
Not 演算子は、整数を構成するビットをすべて反転することです。
すべてのビットが 0 (=False) か、すべてのビットが 1 (=True=-1) でなければ、
Not 演算してしなくても常に真になります。
C言語では、演算結果は整数の 0 か 1 のみになります。
Func 0
Func 1
Func -1
Sub Func( a )
If a Then
WScript.Echo "a = True"
Else
WScript.Echo "a = False"
End If
If not a Then
WScript.Echo "not a = True"
Else
WScript.Echo "not a = False"
End If
End Sub
検証コード：
書きかけ
→ MISRA 12.4
Func 0, 0, 0, 0, out '// False
Func 1, 0, 0, 0, out '// False
Func 0, 1, 0, 0, out '// False
Func 1, 1, 0, 0, out '// True
Func 0, 0, 1, 0, out '// False
Func 1, 0, 1, 0, out '// False
Func 0, 1, 1, 0, out '// False
Func 1, 1, 1, 0, out '// True
Func 0, 0, 0, 1, out '// False
Func 1, 0, 0, 1, out '// False
Func 0, 1, 0, 1, out '// False
Func 1, 1, 0, 1, out '// True
Func 0, 0, 1, 1, out '// True
Func 1, 0, 1, 1, out '// True
Func 0, 1, 1, 1, out '// True
Func 1, 1, 1, 1, out '// True
WScript.Echo out
Sub Func( a, b, c, d, out )
and1 = ( a > 0 )
If and1 Then and1 = ( b > 0 )
and2 = ( c > 0 )
If and2 Then and2 = ( d > 0 )
If and1 or and2 Then
out_bool = "True"
Else
out_bool = "False"
End If
out = out +"( "& a &" and "& b &" ) or ( "& c &" and "& d & _
" ) = "+ out_bool + vbCRLF
End Sub
検証コード：
C言語式の And と Or の複合文
and1 = ( a > 0 )
If and1 Then and1 = ( b > 0 )
and2 = ( c > 0 )
If and2 Then and2 = ( d > 0 )
If and1 or and2 Then
If ( a > 0 and b > 0 ) or ( c > 0 and d > 0 ) Then
×
○
← ▼ ▲
GetRef
Function GetRef( FuncName as string ) as Function or Sub
文字列で指定したシンボルのプロシージャを返します。
FuncName に指定したプロシージャが定義されていないときは、エラー 5 になります。
サンプル：
Dim sub_x
Set sub_x = GetRef( "sub1" )
sub_x '// sub1 を呼び出します
Sub sub1()
MsgBox "X"
End Sub
Dim sub_x
On Error Resume Next
Set sub_x = GetRef( "sub1" )
On Error Goto 0
If IsEmpty( sub_x ) Then MsgBox "Not defined"
MsgBox "err = " & Err.Number
Sub sub1
Err.Raise 1,,"Error in sub1"
End Sub
プロシージャが定義されているかどうかの判定
IsEmpty
1.
標準的なエラーメッセージを表示する
2.
エラーコードやエラーメッセージを Err オブジェクトに設定する
3.
IsEmpty が On Error Resume Next のように働き、次の行から実行する。
GetRef でプロシージャが取得できたかどうか（定義されているかどうか）は、
IsEmpty sub_x で判定することはできません。
エラー 5 が発生したかどうかで判定してください。
IsEmpty sub_x とすると、sub1 が定義されていなければ、期待通り "Not defined"
と表示しますが、sub1 が定義されていると、sub1 を呼び出してしまいます。
さらに、次のような特殊な動きになります。
悪いコード
Dim sub_x, en
On Error Resume Next
Set sub_x = GetRef( "sub1" )
en = Err.Number : On Error GoTo 0
If en = 5 Then MsgBox "Not defined"
MsgBox "err = " & Err.Number
Sub sub1
Err.Raise 1,,"Error in sub1"
End Sub
良いコード
→ IsDefined (vbslib)
返される値はオブジェクト参照ですが、同じ FuncName を指定しても、同じオブジェクト
への参照にはなりません。
GetRef で取得した関数は、ExecuteGlobal でオーバーライドしても、無くなりません。
Dim ref
ExecuteGlobal "Function F() : F=1 : End Function"
Set ref = GetRef( "F" )
echo "F, ref"
echo F() & ", " & ref()
ExecuteGlobal "Function F() : F=2 : End Function"
echo F() & ", " & ref()
出力内容
F, ref
1, 1
2, 1
If GetRef("sub1") Is GetRef("sub1") '// False
クラスの中のメソッドは指定できません。
引数が無い関数（例：上記 sub_x）は、下記コードでも呼び出してしまいます。
If IsEmpty( sub_x ) Then ...
ダミーの引数を定義してください。
関連
→ EventResponders クラス
→ DefaultFunction
→ CallByName
詳細
GetRef関数の返り値は、ディスパッチID = 0 なメソッド（Default のメソッド）
を持った IDispatch オブジェクトへの参照です。
→ 掲示板過去の記事 (Web)
←
↓