VBScript: 変数や演算子を使って定数を定義する方法
VBScript では読み取り専用の変数を作るために Const ステートメントが用意されている。
しかし、そこで指定できるのはリテラル定数のみであり、このようなステートメントは許可されていない。
Const kConstant0 = 1 + 2 Const kConstant1 = "Hello, " & "World"
これは大変不便である。そこで、このような定数を定義するためのラッパーを作成した。
・ConstWrapper.vbs
Function Constant(ByVal name, ByVal value)
  Dim literal
  Select Case VarType(value)
  Case vbEmpty: literal = "Empty"
  Case vbNull : literal = "Null"
  Case vbInteger, vbLong, vbSingle, vbDouble, vbCurrency, vbBoolean, _
      vbDecimal, vbByte
    literal = value
  Case vbString
    If InStr(value, vbCr) Or InStr(value, vbLf) Then
      Err.Raise 1, "Constant", _
          "ValueError: value contains a newline"
    End If
    literal = """" & Replace(value, """", """""") & """"
  Case vbDate
    literal = "#" & _
        Join(Array(Year(value), Month(value), Day(value)), "-") & " " & _
        Join(Array(Hour(value), Minute(value), Second(value)), ":") & "#"
  Case Else
    Err.Raise 2, "Constant", _
        "ValueError: type '" & TypeName(value) & "' cannot be a constant"
  End Select
  Execute "Const " & name & "=" & literal
End Function
・使用例
Constant "kConstant0", 1 + 2 Constant "kConstant1", "Hello, " & "World"
・テストコード
If WScript.FullName <> WScript.Path & "\cscript.exe" Then
  Dim args, i, shell
  args = """" & WScript.ScriptFullName & """"
  For Each i In WScript.Arguments: args = args & " """ & i & """": Next
  Set shell = CreateObject("WScript.Shell")
  shell.Run WScript.Path & "\cscript.exe //NOLOGO " & args, 1, False
  WScript.Quit
End If
Dim gCount: gCount = 0
Check "0"
Check "1"
Check "0000000000000000001"
Check "32767"        ' 2^15-1
Check "32768"        ' 2^15
Check "2147483647"   ' 2^31-1
Check "2147483648"   ' 2^31
Check "-0"
Check "-1"
Check "-32767"       ' -(2^15-1)
Check "-32768"       ' -(2^15)
Check "-2147483647"  ' -(2^31-1)
Check "-2147483648"  ' -(2^31)
Check "&O000000"       ' 0
Check "&O00000000000"  ' 0
Check "&O00000000001"  ' 1
Check "&O77777"        ' 2^15-1
Check "&O17777777777"  ' 2^31-1
Check "&O177777"       ' -1
Check "&O37777777777"  ' -1
Check "&O100001"       ' -(2^15-1)
Check "&O100000"       ' -(2^15)
Check "&O20000000001"  ' -(2^31-1)
Check "&O20000000000"  ' -(2^31)
Check "&H0000"      ' 0
Check "&H00000000"  ' 0
Check "&H00000001"  ' 1
Check "&H7fff"      ' 2^15-1
Check "&H10000"     ' 2^15
Check "&H7fffffff"  ' 2^31-1
Check "&Hffff"      ' -1
Check "&Hffffffff"  ' -1
Check "&H8001"      ' -(2^15-1)
Check "&H8000"      ' -(2^15)
Check "&H80000001"  ' -(2^31-1)
Check "&H80000000"  ' -(2^31)
Check "0."
Check "3.14159265358979"
Check "1e2"
Check "1.2e-3"
Check """"""
Check """"""""""
Check """Hello, World"""
Check "#1-2#"
Check "#01-02#"
Check "#1/2#"
Check "#1 2#"
Check "#Jan-2#"
Check "#2-Jan#"
Check "#1-2-3#"
Check "#2003-1-2#"
Check "#2-3-Jan#"
Check "#2003-2-Jan#"
Check "#4:5#"
Check "#04:05#"
Check "#4:5:6#"
Check "#04:05:06#"
Check "#1-2-3 4:5:6#"
Check "#4:5:6 1-2-3#"
Check "#2003-01-02 04:05:06#"
Check "True"
Check "False"
Check "Empty"
Check "Null"
Check "CSng(1.2)"
Check "CCur(1.2)"
Check "CByte(255)"
' Error cases
ON ERROR RESUME NEXT
Check "vbCrLf"
WScript.Echo "[Error:" & Err.Number & "]", Err.Source, Err.Description
Check "WScript.Arguments"
WScript.Echo "[Error:" & Err.Number & "]", Err.Source, Err.Description
Check "Array()"
WScript.Echo "[Error:" & Err.Number & "]", Err.Source, Err.Description
ON ERROR GOTO 0
MsgBox "Click OK to exit."
Function Check(ByVal description)
  PackString description, 24
  Execute "PackString VarType(" & description & _
      ") & "": "" & TypeName(" & description & "), 20"
  Execute "Constant ""k" & gCount & """," & description
  Execute "If IsNull(k" & gCount & _
      ") Then PackString ""null"", 24 Else PackString k" & gCount & ", 24"
  Execute "PackString VarType(k" & gCount & _
      ") & "": "" & TypeName(k" & gCount & "), 20"
  WScript.Echo
  gCount = gCount + 1
End Function
Function PackString(ByVal value, ByVal width)
  WScript.StdOut.Write value & String(width - Len(value), " ")
End Function
・出力例
0 2: Integer 0 2: Integer 1 2: Integer 1 2: Integer 0000000000000000001 2: Integer 1 2: Integer 32767 2: Integer 32767 2: Integer 32768 3: Long 32768 3: Long 2147483647 3: Long 2147483647 3: Long 2147483648 5: Double 2147483648 5: Double -0 2: Integer 0 2: Integer -1 2: Integer -1 2: Integer -32767 2: Integer -32767 2: Integer -32768 3: Long -32768 3: Long -2147483647 3: Long -2147483647 3: Long -2147483648 5: Double -2147483648 5: Double &O000000 2: Integer 0 2: Integer &O00000000000 2: Integer 0 2: Integer &O00000000001 2: Integer 1 2: Integer &O77777 2: Integer 32767 2: Integer &O17777777777 3: Long 2147483647 3: Long &O177777 2: Integer -1 2: Integer &O37777777777 2: Integer -1 2: Integer &O100001 2: Integer -32767 2: Integer &O100000 3: Long -32768 3: Long &O20000000001 3: Long -2147483647 3: Long &O20000000000 3: Long -2147483648 5: Double &H0000 2: Integer 0 2: Integer &H00000000 2: Integer 0 2: Integer &H00000001 2: Integer 1 2: Integer &H7fff 2: Integer 32767 2: Integer &H10000 3: Long 65536 3: Long &H7fffffff 3: Long 2147483647 3: Long &Hffff 2: Integer -1 2: Integer &Hffffffff 2: Integer -1 2: Integer &H8001 2: Integer -32767 2: Integer &H8000 3: Long -32768 3: Long &H80000001 3: Long -2147483647 3: Long &H80000000 3: Long -2147483648 5: Double 0. 5: Double 0 2: Integer 3.14159265358979 5: Double 3.14159265358979 5: Double 1e2 5: Double 100 2: Integer 1.2e-3 5: Double 0.0012 5: Double "" 8: String 8: String """" 8: String " 8: String "Hello, World" 8: String Hello, World 8: String #1-2# 7: Date 2012/01/02 7: Date #01-02# 7: Date 2012/01/02 7: Date #1/2# 7: Date 2012/01/02 7: Date #1 2# 7: Date 2012/01/02 7: Date #Jan-2# 7: Date 2012/01/02 7: Date #2-Jan# 7: Date 2012/01/02 7: Date #1-2-3# 7: Date 2003/01/02 7: Date #2003-1-2# 7: Date 2003/01/02 7: Date #2-3-Jan# 7: Date 2003/01/02 7: Date #2003-2-Jan# 7: Date 2003/01/02 7: Date #4:5# 7: Date 4:05:00 7: Date #04:05# 7: Date 4:05:00 7: Date #4:5:6# 7: Date 4:05:06 7: Date #04:05:06# 7: Date 4:05:06 7: Date #1-2-3 4:5:6# 7: Date 2003/01/02 4:05:06 7: Date #4:5:6 1-2-3# 7: Date 2003/01/02 4:05:06 7: Date #2003-01-02 04:05:06# 7: Date 2003/01/02 4:05:06 7: Date True 11: Boolean True 11: Boolean False 11: Boolean False 11: Boolean Empty 0: Empty 0: Empty Null 1: Null null 1: Null CSng(1.2) 4: Single 1.2 5: Double CCur(1.2) 6: Currency 1.2 5: Double CByte(255) 17: Byte 255 2: Integer vbCrLf 8: String [Error:1] Constant ValueError: value contains a newline WScript.Arguments 9: Object [Error:2] Constant ValueError: type 'Object' cannot be a constant Array() 8204: Variant() [Error:2] Constant ValueError: type 'Variant()' cannot be a constant
Error型、Decimal型、非オートメーションオブジェクトは VBScript では作成が難しかったので省略。
渡された引数を一度 String型 に変換してから Execute 文を実行しているため、型が変わるケースもある。
尚、Execute 文の特性上、改行を含む文字列はどうしても定義することはできない。
 
 
0 件のコメント:
コメントを投稿