今回のVBScript入門記事では、若干今さら感が有りますが「データ型」について紹介していきます。
VBScriptでは比較的他の言語よりも制約の緩いデータ型ですが、プログラミングを習得する上で必ず理解する必要がある仕組みなので、しっかり学習していきましょう。
データ型とは
正確性に欠ける説明になりますが、データ型とは
「変数に入れることができる値の種類」
と理解してください。
ここではまず一般的な「データ型」を説明し、後からVBScript固有の特性を説明します。
一般的なプログラム言語のデータ型
通常、プログラム内で変数を使う場合は、明示的にその変数名を宣言しますが、その際に併せてその変数の「データ型」を指定します。
例えば今回のVBScriptと似たプログラミング言語として、MS Officeで実装されている「VBA」の場合で言えば以下のような宣言方法になります。
Dim Moji As String
過去の記事では、VBScriptでの変数についての解説をしており、賢明な皆さまにおいては、その時に紹介した変数の宣言方法と類似しているが相違も有ることがわかるかと思います。
VBScriptでは、
Dim Moji
と変数を宣言しますが、VBAでは、そこに更に
As String
と続いています。
この部分が変数の「型」を指定する記述になります。
今回の「String」は文字列を格納できる型です。
よって、文字列ではない値は格納できません。
ただ、プログラム言語によっては、Stringで型を指定した変数に、100 などの数値を代入した場合、100 を”数値”ではなく”文字列”として自動的に置き換えて変数に格納してくれます。
この仕組みを「暗黙の型変換」と呼び、VBAでもこの仕組みが利用できます。
VB系言語で扱えるデータ型
まずはMicrosoftのVBAのリファレンス記事をご参照ください。
Microsoft Office VBAリファレンス -データ型の概要-
こちらを見ていただくと、色々な型が存在しているのがわかるかと思います。
VBAのリファレンスページなので、VBScriptでは存在しない型も幾つか有りますが、主要な型は共通です。
この一覧を見ると、記述が難解で桁数の多い数字も並んでいるため、データ型とは難しい仕組みと感じてしまうかも知れませんが、覚えるべき型はこのなかの一部なので安心してください。
VBScriptにおけるデータ型の特徴
これまでのVBScriptの入門記事に掲載したサンプルプログラムでも何度か変数の宣言はしていますが、その際に、前述したVBAの様な型指定を含んだ変数の宣言をしていません。
これは型の指定を省いている訳でもなく、VBScriptの言語仕様として「変数に対して型の指定ができない」からです。
ただ、プログラム言語において、どの言語でも必ず変数にはその変数を扱うためにデータ型を指定します。
VBScriptでは変数を宣言すると、内部的には「Variant(バリアント)型」という”なんでも入れることができる“データ型が指定されて変数が生成されます。
“なんでも入れることができる”という意味は、例えば前述のVBAの場合、以下のように変数を宣言したとします。
Dim Suchi As Integer
これは「Suchi」という名前の変数を「Integer = 数値」型専用として宣言します。という意味です。
このように宣言した変数に対しては数値(整数)しか代入できません。
例えばVBAで以下の様に代入するとどうなるでしょうか。
Suchi = "ABC"
この場合は「型が一致しません」とエラーになります。
上記の変数「Suchi」は数値用のデータ型が指定されている為、数値ではない「ABC」という文字列を代入しようとしたので、それはできませんよとエラーになります。
では、前述した「Variant型」の場合は、格納する値に制約はない為、数値だろうが文字列だろうが代入できます。
だったら、格納する値に制約がある通常のデータ型ではなく、制約のない「Variant型」の方が便利じゃないかっと思われる人も居るかも知れません。
ただ、信頼性の高いプログラムを作るうえでは、変数にはそれぞれ適したデータ型を指定する必要があります。
以降の項で、データ型の重要性について説明していきます。
データ型の扱いが不適切なサンプルコード
当項目では、VBScriptがVariant型しか指定できないことによる問題点や、組み込み関数の戻り値のデータ型を適切に処理できていない事例を紹介していきます。
Variant型に起因した不適切な代入
早速サンプルプログラムを見てみましょう。
このサンプルプログラムでは変数「Hensu」に対して100を代入し、それを互いに足した結果をメッセージボックスに表示しています。
まずは正しく実装したプログラムを見てみましょう。
Option Explicit Dim Hensu Hensu = 100 Msgbox Hensu + Hensu
このサンプルプログラムを実行すると、以下のメッセージボックスが表示されます。
「Hensu」の値の100に同じ「Hensu」の値の100を足しているので、答えは当然200ですね。
これは問題の無い動きです。
続いて、問題のある実装をしたプログラムを見てみましょう。
Option Explicit Dim Hensu Hensu = "100" Msgbox Hensu + Hensu
このサンプルプログラムを実行すると、以下のメッセージボックスが表示されます。
100+100=200のはずが、100100になってしまいました。
その原因は今回と前回のサンプルプログラムの違いによって発生しているのですが、違いはわかりましたでしょうか?
その違いとしては、問題のあるプログラムでは、100に対してダブルクォーテーションで囲った値を変数に代入しています。
その為、変数「Hensu」は文字列型として扱われ、文字列の100に対して、文字列の100をプラスの四則演算子で繋いでおり、四則演算子のプラスは、文字列同士を繋ぐと、文字列の結合処理として動作するため、100100という文字列が出来上がったという流れです。
もし、変数宣言時にVBAの様に型を指定でき、データ型を「Integer」と指定できれば、上記の問題のあるプログラムではプログラム実行時に、文字列の100を代入しようとしてエラーになります。
エラーになることで、誤った処理が実装されてしまわないように未然に防げます。
では、次のサンプルプログラムを見てみましょう。
関数の戻り値のデータ型の扱いが不適切
このサンプルプログラムでは、数値の100に対してLeft関数で左側の一文字目の1を切り取って演算します。
構文
Left(strString, lngCnt)
文字列の左端から指定された文字数分の文字列を返します。
引数
strString
文字列式の左端から文字列が取り出されます。
lngCnt
取り出す文字列の文字数を示す数式を指定します。
Option Explicit Dim Hensu Hensu = 100 Msgbox Left(Hensu,1) Msgbox Left(Hensu,1) + Left(Hensu,1)
このプログラムを実行すると、2回メッセージボックスが表示されます。
一回目のメッセージボックスは以下のようになります。
これは変数「Hensu」に数値の100が代入されて、「Left関数」にて100の一番左側の文字を一文字分切り取った値をメッセージボックスに表示しています。
ここまでは問題は無いです。
二回目のメッセージボックスは以下のようになります。
8行目の処理では、Hensuに対してLeft関数で切り出した文字の1を互いにプラスの演算子で足して、その結果をメッセージボックスに表示したのですが、その値は2ではなく、11となりました。
前項のサンプルコードのように、数値をダブルクォーテーションで括った訳ではないのに、なぜ数値の1が文字列として互いに結合されてしまったのでしょうか?
原因を次項で解説します。
「暗黙の型変換」と戻り値のデータ型
まず、前述したLeft関数の説明を見ると、Left関数の第1引数は「strString」と記載されています。
ここから第1引数は文字列型の値を指定する必要があることがわかります。
ただ、実際にプログラム上で渡した値は、ダブルクォーテーションで括っていない100という数値が入った変数です。
この状態でLeft関数を実行してもエラーが発生せずに1という値を返せたのは、前述した「暗黙の型変換」により、Left関数に変数「Hensu」に入っている値は数値ではなく文字列と自動的に置き換えられたことを意味します。
また、前述したLeft関数の説明では、”指定された文字数分の文字列を返します。“とあります。
Left関数の戻り値は仕様として常に文字列のデータ型として値を戻す為、その戻された値同士をプラスの演算子で足しても、文字列同士が結合されてしまうということになります。
適切にデータ型を扱ったサンプルコード
前項の例にもある通り、VBScriptでは、変数の宣言時にデータ型を指定できません。
その為、変数にはどんな値でも格納できることにより、意図しない型変換が発生するなどの不具合の原因になり得ます。
よって、VBScriptでは宣言した変数に対して、どんなデータ型の値を格納するかについてプログラム作成者側で管理しコントロールする必要があります。
プログラム作成者側で管理、コントロールをして実装した場合のサンプルコードを以下で記載します。
Option Explicit Dim Hensu Hensu = 100 Msgbox CInt(Left(Hensu,1)) + CInt(Left(Hensu,1))
不適切なサンプルプログラムで記述したLeft関数を使用した値の演算を適切に実行できるように修正したプログラムになります。
注目すべきは、Left関数で1文字分切り出した値に対して、更にCInt関数の引数に指定しています。
このCInt関数とはなんでしょうか?
構文
CInt(expression)
指定された値を「Integer型」に変換して返します。
引数
expression
任意の文字列式または数値式。
要約すると、このCInt関数の引数に文字列を渡すことで、対象の値が数値として扱える場合は数値にデータ型を変換して返してくれます。※ひらがな等の数値に変換できない値を引数にした場合はエラーになります。
よって、CInt関数を使って数値に変換して戻された値同士を、プラスの演算子で繋いだことで1+1の演算結果として2をメッセージボックスに表示できました。
当記事の冒頭でお伝えした通り、VBScriptでは変数宣言時に型指定ができない言語仕様ですが、内部的にはしっかりとデータ型の仕組みが存在しており、上記のように、必要によって値をデータ型関連の関数で変換し、意図した処理になるように管理することが重要です。
より深く理解するために
当項では、データ型をより深く理解するための知識を紹介していきます。
押さえておくべきVBScriptの内部データ型
前述のリンクで紹介したMicrosoftのVBAリファレンスのページにて色々なデータ型が紹介されていますが、前述した通り、すべてを把握する必要はありません。
また、VBScriptではさらに使用できるデータ型も少ないため、よく使われるデータ型の特性を理解して使い分けることは容易です。
当項では「押さえておくべきVBScriptの内部データ型」を紹介します。
データ型名 | 内容 |
---|---|
整数型 (Integer) | 比較的桁数の少ない整数を扱うためのデータ型です。 数値なので四則計算に使用できます。 VBScriptの場合は、-32,768 ~ 32,767が扱えます。 小数は扱えず、小数を格納しようとすると小数値は切り捨てられます。 |
長整数型 (Long) | 大きな桁数の数値を扱うためのデータ型です。 数値なので四則計算に使用できます。 VBScriptの場合は、-2,147,483,648 ~ 2,147,483,647が扱えます。 |
倍精度浮動小数点数型(Double) | 小数を含んだ数値を扱うためのデータ型です。 小数を含んだ数値の四則計算に使用できます。 -1.79769313486232E308 ~ -4.94065645841247E-324 (負の値) および 4.94065645841247E-324 ~ 1.79769313486232E308 (正の値) が扱えます。 |
文字列型 (String) | 可変長文字列を扱うためのデータ型です。 文字列を切り出したり結合したりする場合は文字列型である必要があります。 |
日付型 (Date) | 日付を扱うデータ型です。 日付に対する演算や日付関数の引数には日付型の値を使用する必要があります。 西暦 100 年 1 月 1 日~西暦 9999 年 12 月 31 日が扱えます。 |
ブール型 (Boolean) | 真偽値(TrueまたはFalse)を扱うデータ型です。 VBScriptの組み込み関数の戻り値などにも使われます。 値を指定しない場合の初期値はFalseになります。 |
オブジェクト型 (Object) | オブジェクトを格納(参照)するデータ型です。 オブジェクト以外の値は格納できません。 |
この型は長整数型よりも大きい、
-922,337,203,685,477.5808 ~ 922,337,203,685,477.5807
の値を扱えます。
VBScriptでの主要な型変換関数
プログラミングでは、必要によって前項のサンプルプログラムの様に型を変換して必要な処理を実装します。
当項では、覚えておくべき主要な型変換関数の紹介をしていきます。
関数 | 構文 | 説明 |
---|---|---|
CInt 関数 及び CLng 関数 | CInt(expression) CLng(expression) | 引数で渡された値を整数型、及び長整数型に変換します。 共に整数に変換する処理に変わりはないため、値の大きさで使い分けることが面倒であれば、常にCLngを使用しても構いません。 小数を含む値を引数に指定した場合は切り捨てられます。 文字列関数などで生成した数値で演算が発生する場合は必ずこの関数で整数に変換しましょう。 |
CStr 関数 | CStr(expression) | 引数の値を文字列型に変換します。 文字列操作系関数の引数に直接数値を渡しても、暗黙の型変換で処理できてしまうことも多いですが、意図しない挙動を防ぐために、必ず当関数で文字列型に変換してから処理を行いましょう。 |
CDate 関数 | CDate(date) | 引数の日付文字列を日付型に変換します。 日付操作関連の関数に日付形式の文字列を渡しても、暗黙の型変換で一応動きますが、いったん当関数で日付型に変換した値を使用するほうが安全です。 |
CDbl 関数 | CDbl(expression) | 引数の値を倍精度浮動小数点数型に変換します。 小数が発生する計算をすると、暗黙の型変換でこのDouble型に置き換えてくれますが、意図しない切り捨てをされる可能性がある為、当関数で変換したほうが無難です。 |
最後に
今回は「データ型」について紹介しました。
VBScriptでは変数に対してデータ型を指定する仕様がないため、データ型を意識しないままプログラミングをしてしまう人も居るかも知れませんが、前述した通り内部的にはデータ型が存在し、正確で安全なプログラムを作成する場合は、必ず適切なデータ型を意識する必要があります。
また、データ型という仕組みはVBScriptに関わらず、他のプログラミング言語においても必ず必要になる知識です。
確実に習得しておきましょう。
ではでは、今回も読んで頂きましてありがとうございました。
それではごきげんよう。
↓次回の記事はこちら
前回の記事はこちら
Windows10で文字化けする場合
Windows10でテキストファイルを作成した場合の規定の文字コードがVBScriptに対応していないことが原因です。
詳しい原因の解説と、その対応方法を記事にしてあるので参照してください。
実例を後述するので、今は読み飛ばしてください。