(for Internet Explorer)
→ VBA
→ VBScript ポケットリファレンス
→ WSH 2_0 (Web)
関連
Windows の標準的なスクリプトです。拡張子= (*.vbs)
Windows2000 以降ではデフォルトで入っています。
WSH (WScript.exe) が VBScript などのスクリプトを解析して実行します。
COM オブジェクトを通して、Windows や MS-Office を操作できます。
Windows Script Encoder で、バイナリ形式にすることもできます。
→ VisualBasic
参考
.vbs ファイルをダブルクリックしてから実行開始まで時間がかかるときは、ウィルス
対策ソフトのスクリプトに関するチェックをしないようにしてください。 チェックをしなく
ても、Windows のセキュリティ機能によって、ユーザーの許可無く悪意のあるスクリ
プトが実行されることはありません。
→ bashlib
→ PowerShell
新規 VBS ファイルの作成
メモ帳を開いて、VBS を記述し、ファイルを保存するときにファイル名の最後に .vbs を
付けてください。
→ new_vbs
特殊記号一覧 (VBScript)
Sub
Function
Class
' comment
( )
.
new
Set
&
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
GoTo も無い。
' コメント
If a = "" Then
If a <> "" Then
If a <= "" Then
If cond Then ...
WScript.Sleep( 1000 )
WScript.Quit
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
大文字小文字を区別しない比較
If cond1 and cond2 Then
For Each の中で Exit For しないで
ループから抜けたとき、a は Empty になります。
型判定
真 = 偽以外、 偽 = False or 0 or Empty or Null
If a Is b Then
同じオブジェクトかどうかを判定します。
参考
キーワード:
Until は偽の
ときにループ
For Each s  In Array( "A", "B", "C )
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
関連
(Array( "no", "yes" ))(( value )and 1)
Do While cond
  Exit Do
Loop
文を実行する順番を入れ替えます。
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 オブジェクトのメソッドは省略できます。
引数が1つのときは、Sub でも括弧付きで呼び出せてしまいますが、これは Sub の
第1パラメータに渡す前に評価している(+0のように効果の無い計算をしている)
ことになります。 このとき、評価後の値が渡るので、ByRef の引数であっても、
値渡しになり、関数内で引数の変数に設定した値を、呼び出し元が取得することが
できなくなります。
ByRef の引数に、オブジェクトのプロパティ (例:obj.prop)を渡すと、参照渡しには
なりません。 一度、単純変数を引数に指定して呼び出した後で、単純変数から、
プロパティに設定してください。
参照返し
引数で出力するときは、呼び出し側ですぐ分かるように、一旦 out 変数に入れる方法も
あります。out 変数から代入されたところから、s が変化した場所が分かります。
Dim  s, out
GetString  out
s = out
関連
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


 
プリエンプション(スレッドのコンテキスト・スイッチ)を発生させる代わりに、関数から戻って、
ユーザーがスレッドを切り替えることを
擬似マルチスレッド
と呼びます。
擬似マルチスレッドに対応するには、関数(処理)の途中からリターンする 「中断」 機能だけでなく、
関数の途中から 「再開」 する機能を、関数に組み込む必要があります。 そのため、途中の状態(
ローカル変数だった変数、ループ変数)は、スレッドのコンテキスト(クラス)に配置します。
他のスレッドやプロセスの処理を待つ直前で、関数を区切ります。
参考
必要になったときに速く実行できるように、事前に読み出したりダウンロードしておくこと。
プリフェッチしたデータは、キャッシュに格納されます。
参考
一般的なスレッド
プリフェッチするスレッド
プリフェッチするときの動作を示します。
プリフェッチ(リード開始)要求
キャッシュにない状態
リーディング状態
キャッシュにある状態
リード要求
要求に対する処理が、状態によってどのように変化するかを一覧します。
キャッシュにない状態
リーディング状態
(ミス ヒットした場合)
キャッシュにある状態
プリフェッチ要求
リード要求
リード開始
なにもしない
なにもしない
プリフェッチ要求と、リード完了待ち
リード完了待ち
キャッシュからリード
リード完了待ち
キャッシュからリード
プリフェッチ要求をする API 関数では、プリフェッチするスレッドに関する情報にアクセスできる
オブジェクトを返してください。 たとえ、すでにキャッシュにある状態でもです。 そうすれば、
リード要求をする API 関数から、プリフェッチ要求をする API 関数を呼び出すだけで、
その返り値から状態(リーディング状態、キャッシュにある状態)を判断できるようになるから
です。 また、キャッシュに関する情報(パスなど)も得られます。
プリフェッチが完了した順番でリード要求をしない場合(プリフェッチを「開始」した順番でリード
要求をする場合などでは)、最初に開始したデータが大きいと、プリフェッチとリードが並列して
処理できる期間が少なくなりますが、正しく処理されます。 ただし、キャッシュが有限の場合、
キャッシュの内容の置き換えによって再度プリフェッチが必要になる場合があります。
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
検証コード:
検証コード:
    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
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
検証コード:
    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
×
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
良いコード
返される値はオブジェクト参照ですが、同じ 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 ...
ダミーの引数を定義してください。
関連
→ CallByName
詳細
GetRef関数の返り値は、ディスパッチID = 0 なメソッド(Default のメソッド)
を持った IDispatch オブジェクトへの参照です。