怠日記

写真・金魚・昆虫・プログラミングの趣味を語るサイトです。似たようなことをnoteにも書いたり書いてなかったり。

VBScript - データ型(バリアント型(Variant)とは)

VBScript の変数のデータ型は、すべてバリアント型(Variant)になる。

バリアント型(Variant)は次の特徴を持つ。

  • どんな値でも格納できる。数値でも文字列でも何でも OK 。
  • 格納された値をどのデータ型として扱うかを「内部処理形式」として持つ。
    たとえば整数を格納すれば内部処理形式は整数型となり、ブール型(True/False)を格納すれば内部処理形式はブール型となる。

内部処理形式の一覧

バリアント型(Variant)で持てる内部処理形式は以下のとおり。

内部処理形式説明
Empty 値初期値が代入されていないことを表す。
Null 値有効なデータを持たないことを表す。
ブール型(Boolean)真(True)または偽 (False) の真偽値
バイト型(Byte)0 ~ 255 の整数
整数型(Integer)-32,768 ~ 32,767 の整数
長整数型(Long)-2,147,483,648 ~ 2,147,483,647 の整数
単精度浮動小数点数型(Single)-3.402823E38 ~ -1.401298E-45 (負の値) および 1.401298E-45 ~ 3.402823E38 (正の値) の実数
倍精度浮動小数点数型(Double)-1.79769313486232E308 ~ -4.94065645841247E-324 (負の値) および 4.94065645841247E-324 ~ 1.79769313486232E308 (正の値) の実数
通貨型(Currency)-922,337,203,685,477.5808 ~ 922,337,203,685,477.5807 の数値
日付(時刻)型(Date)西暦100年1月1日~西暦9999年12月31日の日付(を表す数字)
文字列型(String)約2GBまでの文字を格納できる可変長文字列
オブジェクト型オブジェクトへの参照
エラー型エラー番号を持つデータ型

内部処理形式を VarType 関数で判定する

VarType(varname)

変数 varname の内部処理形式を表す数値を返す。

定数内容
vbEmpty0Empty 値(未初期化)
vbNull1Null 値(無効な値)
vbInteger2整数型(Integer)
vbLong3長整数型(Long)
vbSingle4単精度浮動小数点数型(Single)
vbDouble5倍精度浮動小数点数型(Double)
vbCurrency6通貨型(Currency)
vbDate7日付型(Date)
vbString8文字列型(String)
vbObject9オートメーション オブジェクト
vbError10エラー型
vbBoolean11ブール型(Boolean)
vbVariant12バリアント型(Variant)(バリアント型配列にのみ使用)
vbDataObject13非オートメーション オブジェクト
vbByte17バイト型(Byte)
vbArray8192配列(Array)

不具合?
Excel.Application を引数にすると vbString(8) が返される。
正しくは vbObject(9) ではないかと思うのだが……。

Dim xls
Set xls = CreateObject("Excel.Application")
WScript.Echo VarType(xls)
' → 8

内部処理形式を TypeName 関数で判定する

TypeName(varname)

変数 varname の内部処理形式を表す文字列を返す。

戻り値の一例を以下に挙げる。

戻り値説明
EmptyEmpty 値
NullNull 値
Integer整数型(Integer)
Long長整数型(Long)
Single単精度浮動小数点数型(Single)
Double倍精度浮動小数点数型(Double)
Currency通貨型(Currency)
Date日付型(Date)
String文字列型(String)
〈object type〉実際のオブジェクトの種類の名前 *後述
Booleanブール型(Boolean)
Byteバイト型(Byte)
Variant()配列(Array)

*TypeName 関数にオブジェクトを指定するとどのような文字列を返すのか。

例:Scripting.Dictionary は Dictionary が返された。

Dim a
Set a = CreateObject("Scripting.Dictionary")
WScript.Echo TypeName(a)
' → Dictionary

例:ADODB.Stream は Stream が返された。

Dim a
Set a = CreateObject("ADODB.Stream")
WScript.Echo TypeName(a)
' → Stream

計算結果が元のデータ型を超えると自動で拡張される

ByteIntegerLongSingleを格納している Variant に対して計算を行い、結果が元のデータ型の範囲を超えた場合、結果は Variant 内で次に大きいデータ型に昇格される。

  • ByteInteger
  • IntegerLong
  • Long または SingleDouble
  • CurrencyDouble → 実行時エラー

例1 Byte → Integer

Dim a, b, c
a = CByte(128)
b = CByte(128)
c = a + b
WScript.Echo TypeName(c)
' → Integer

例2 Integer → Long

Dim d, e, f
d = 32767   'Integerの最大値
e = 1
f = d + e
WScript.Echo TypeName(f)
' → Long

例3 Long → Double

Dim g, h, i
g = 2147483647  'Longの最大値
h = 1
i = g + h
WScript.Echo TypeName(i)
' → Double

例4 Single → Double

Dim j, k, l
j = CSng(340282350000000000000000000000000000000) 'Singleの最大値 3.4028235E+38
k = CSng(1)
l = j + k
WScript.Echo TypeName(l)
' → Double

例5 Double の計算でオーバーフロー

Dim m, n, o
m = 1.79769313486231E+308
n = 0.00000000000001E+308
o = m + n
WScript.Echo TypeName(o)
' → 実行時エラー #6 - オーバーフローしました。

例6 Currency の計算でオーバーフロー

Dim p, q, r
p = CCur(922337203685477)   'Currencyの最大値 922,337,203,685,477.5807
q = 1
r = p + q
WScript.Echo TypeName(r)
' → 実行時エラー #6 - オーバーフローしました。