【エクセルVBA雑学】データ型とは何か詳しく説明してみる
VBAのdim文には「データ型」を決定する機能があります。
たとえば、次のように変数Rowを宣言すると、変数Rowのデータ型は「Long型」になります。
Dim Row As Long
この「データ型」とは、そもそも何なのでしょうか?
この記事の目次
インターネットでよくみる「データ型」の説明
インターネットで「データ型」について調べてみると、次のような内容が出てきます。
- データ型の種類
-
Boolean型、Integer型、Long型、Double型、String型などの種類があります
- それぞれの「データ型」に入れられる値
-
データ型 入れられる値 Boolean型 True または False Integer型 -32,768 ~ 32,767 Long型 -2,147,483,648 ~ 2,147,483,647 Double型 正数 4.94065645841247 x 10-324 ~ 1.79769313486232 x 10308 負数 -1.79769313486232 x 10308 ~ -4.94065645841247 x 10-324 String型 任意の文字データ Date型 任意の日付データ Variant型 任意のデータ
実際にプログラムを組むことだけを考えれば、上のような仕組みがあるということを認識して丸暗記すれば問題はありません。
また、「データ型」の「イメージ」として次のような説明がされます。
- データ型ごとに「データ型のマークがプリントされた箱」が準備されていて
- その箱には「それに合う値」しか入れられない
単にVBAのプログラムを組めればいいというだけなら、この程度の理解でも十分です。
丸暗記では疑問に答えられない
でも、単に丸暗記するだけでは、次のような根本的な疑問には答えられません。
- なぜ、データ型は必要なのか
- なぜ、入力可能な値の範囲が「-32768~32767」など「半端な数字」なのか
- なぜ、範囲外の値を入れるとエラーになるのか
- なぜ、何種類ものデータ型があるのか。1つじゃダメなのか
それに、根本的な話として、単なる丸暗記だと、つまらなくないですか?
そこで、このページでは、上のような疑問を解決するために、このような「データ型」の仕組みを、すこし突っ込んで解説していこうと思います。
プログラムを組むために必須ではない「雑学的な」知識ですが、興味がある方は読んでみてください。
データ型とは何か?
データ型とは、一言でいうと、
「普段使っているデータ」を「パソコンに記録できる値」に「変換」する仕組み
のことをいいます。
このページでは、Long型など冒頭の表で書いたデータ型(いわゆるプリミティブ型)の、説明をしていこうと思います。
Worksheet型、Range型などの「オブジェクト」については、このページでは説明しませんので、ご注意ください。
パソコンにデータを記録する仕組み
パソコンには0~255しか記録できない
以前、別の記事で「変数」のイメージを紹介しました。
そこでは、変数を、箱の中の「紙」にデータを書き込むイメージで紹介しました。
ところで、上の説明では、意図的に「あいまいに」説明をしていた部分があります。
実は、パソコンの仕組みとして、この「紙」には0~255までの値しか記録ができないのです。
もう少し正確に言うと、この「紙」には、
「00010001」「10101010」というように、0か1かの数字を「8個」記録することができます。
0か1かの数字を「8個」記録できるということは、
- 1桁につき2パターンの情報を記録できるので
- 8桁あれば、28 = 2×2×2×2×2×2×2×2 = 256 パターンの値が記録できる
ということになります。
この256パターンを0~255に割り当てて《「0~255までの値」を記録できる》と考えるわけです。
0~255以外のデータを扱いたいときには?
当然ですが、エクセルVBAなどのプログラムで扱うデータには、0から255以外のデータも出てきます。
そこで、様々なデータを記録するためには、次の2つのことが必要になります。
- i) 十分な数の箱を確保する
-
どんな変換ルールを作ったとしても、1つの箱だけでは0~255までの「256パターン」しか扱えません。
これでは、「数値」を記録するにしても、「文字」を記録するにしても、記録できるパターン数が少なすぎます。
たとえば、「文字」を記録したい場合。
小学校で習う漢字だけでも約1,000文字あります。それ以外にも、ひらがな、カタカナ、数字、記号などをあわせると、使う文字の種類は1,000文字を大きく超えます。
ですから、仮に、
- 「あ」→「0」
- 「い」→「1」
- ・・・
- 「ん」→「45」
- ・・・
と割り当てていったとしても、とても「0~255」まででは収まりません。
そこで、実際には記録したい値に応じて、必要な数だけ箱を確保します。
ある情報を「複数の箱」を使って表すことにすれば、それだけ表現できるパターン数は増えます。
たとえば、
- 2箱あれば、256 × 256 = 65,536パターン
- 4箱あれば、256 × 256 × 256 × 256 = 4,294,967,296パターン
のデータを表現することができます。
先ほどの「文字」の例にもどると、2箱で1文字を表現することにすれば、2箱で65,536パターンを表現できるわけです。
これだけのパターン数があれば、日本語の1文字を記録するには十分です。
- ii) 変換ルールを決める
-
次に、確保した「箱」に、記録したいデータを何らかのルールで0~255の数字に変換をして記録をします。
たとえば、「あ」「い」という文字は、次のようなイメージで変換して記録されます。
データ型を指定して「箱の数」「変換ルール」を決める
このように、プログラムで使うデータをパソコンに記録するためには、次の2つが必要になります。
- 必要な箱数の確保
- 箱に値を格納するための変換ルールの決定
ここで出てくるのが「データ型」です。
変数宣言時に「データ型」を指定することで、この2つの要素を決めているのです。
いくつか、実際の例を見てみましょう。
例1: Integer型
Integer型では、箱を2つ確保します。
箱が2つあるので、
「256×256=65,536パターン」(=0~65,535)
の表現ができます。
それを、次のように割り当てます。
区分 | 元の値 | 箱 | ||
---|---|---|---|---|
パターン | それぞれの箱に記録する値 | |||
正 の 数 |
0 | → | 0 | 「0」「0」 |
1 | → | 1 | 「0」「1」 | |
... | ... | ... | ||
32,766 | → | 32,766 | 「127」「254」 | |
32,767 | → | 32,767 | 「127」「255」 | |
負 の 数 |
-32,768 | → | 32,768 | 「128」「0」 |
-32,767 | → | 32,769 | 「128」「1」 | |
... | ... | ... | ||
-2 | → | 65,534 | 「255」「254」 | |
-1 | → | 65,535 | 「255」「255」 |
実際の動作イメージは、次のような感じです。
Dim Row As Integer 'Integer型のために「2箱」確保
Row = 32766 '「32766」をInteger型の変換規則で変換
'「127」「254」をそれぞれの箱に格納
Debug.Print Row '箱に格納された「127」「254」をInteger型の
'変換規則で戻す。その結果の「32766」を表示
例2: Long型
Long型では、箱を4つ確保します。
箱が4つあるので、
「256×256×256×256=4,294,967,296パターン」(=0~4,294,967,295)
の表現ができます。
それを、次のように割り当てます。
区分 | 元の値 | 箱 | ||
---|---|---|---|---|
パターン | それぞれの箱に記録する値 | |||
正 の 数 |
0 | → | 0 | 「0」「0」「0」「0」 |
1 | → | 1 | 「0」「0」「0」「1」 | |
... | ... | ... | ||
2,147,483,646 | → | 2,147,483,646 | 「127」「255」「255」「254」 | |
2,147,483,647 | → | 2,147,483,647 | 「127」「255」「255」「255」 | |
負 の 数 |
-2,147,483,648 | → | 2,147,483,648 | 「128」「0」「0」「0」 |
-2,147,483,647 | → | 2,147,483,649 | 「128」「0」「0」「1」 | |
... | ... | ... | ||
-2 | → | 4,294,967,294 | 「255」「255」「255」「254」 | |
-1 | → | 4,294,967,295 | 「255」「255」「255」「255」 |
Dim Value As Long 'Long型のために「4箱」確保
Value = -2147483647 '「-2147483647」をLong型の変換規則で変換
'「128」「0」「0」「1」をそれぞれの箱に格納
Debug.Print Value '箱に格納された「128」「0」「0」「1」を
'Long型の変換規則で戻す。
'その結果の「-2147483647」を表示
例3: String型
String型では、箱を「文字数×2つ」確保します。
そして、箱2つで「1文字」を表現します。
実際の動作イメージは、次のような感じです。
Dim Word As String 'String型の変数を確保
Word = "あいう" '「あいう」をString型の変換規則で変換
'必要な箱数(6箱)を確保
'「48」「66」「48」「68」「48」「70」を
'それぞれの箱に格納
Debug.Print Word '箱に格納された
'「48」「66」「48」「68」「48」「70」を
'String型の変換規則で戻す。
'その結果の「あいう」を表示
実際には、String型については、内部的にもう少し複雑な処理をしていると思います。
このページの説明は、あくまで「雰囲気を掴むため」の説明だということで、ご理解ください。
例4: Double型
かなり難しいので、このページでの説明は省略します。
興味があれば、「浮動小数点 表現」などで、検索をしてみてください。
データ型の疑問に答える
さて、ここまで説明してきたことを前提知識として、データ型の疑問に答えていきましょう。
なぜ「データ型」が必要なのか?
人間が扱いやすいデータを、パソコンが扱えるデータ(0~255)に「変換」をする必要があるからです。
「データ型」を使うことで、この「変換作業」を、パソコンが自動的に行ってくれます。
なぜ、Integer型、Long型などに入れられる「値の範囲」が中途半端なのか?
1箱ごとの記録パターン数が中途半端な数(=256パターン)だからです。
たとえば、Integer型の場合を考えてみます。
Integer型では「2箱」使うので、表せるパターン数は「65,536(=256×256)」パターンです。
このパターン数で、数字を表そうとすると、表せる数字の範囲は「-32,768~32,767」という半端な範囲になってしまうわけです。
Long型やDouble型の値の範囲が中途半端な理由もまったく一緒です。
基本的には、確保した数の箱に応じて、入れられる数値の範囲が決まっているのです。
なぜ、範囲外の値を入れるとエラーになるのか?
「データを記録するための変換」ができないからです。
Integer型に、
- 範囲外の数字(たとえば、123,456)
- 文字(たとえば、「あいう」)
を入れようとしても、箱に入れるための「変換」ができないためエラーになってしまいます。
なぜ、何種類ものデータ型があるか?
それぞれのデータ型に「長所」「短所」があるからです。
たとえば、Long型、Double型、String型、Variant型の比較をすると次のようになります。
データ型 | 数値計算の可否 | 格納できるデータの種類 | 必要容量の少なさ (=箱の数の少なさ) |
動作速度 |
---|---|---|---|---|
Long型 | 可能 | 整数のみ | ◎ | ◎ |
Double型 | 可能 | 整数・小数 | ○ | ○ |
String型 | 不可能 | すべての文字 | △ | ○ |
Variant型 | 可能 | すべてのデータ | × | × |
このように、各データ型には、長所・短所があります。
ですから、効率的なプログラムを組むためには、データ型を使い分ける必要があります。
データ型の使い分け方の目安
データ型は、次のように使い分けましょう。
データ型の意味がよくわからないときはVariant型
データ型の意味が、イマイチよくわからないというときはVariant型を使いましょう。
特に、VBAに慣れていないうちは、Variant型を使えば十分でしょう。
次のようにDim文の後に、データ型を指定しなければ、自動的にVariant型になります。
Dim Value 'これでVariant型になる
以下は、細かく使い分けたい人向けの指針です。
Integer型は使わずLong型を使う
通常、Integer型を使うメリットは「必要な箱の数が少ない」ところにあります。
ところが、VBAのInteger型は、内部的にLong型に変換して処理されています。
その結果、必要な容量は変わらず、しかもLong型に変換する分動作速度も遅くなってしまうようです。
このように、Integer型を使うメリットはありませんので、Long型を使いましょう。
For~NextループにはLong型を使う
For~Nextループでは、ほとんどの場合「整数」しか出てこないはずです。
ですから、For~Nextループで使う「カウンタ変数」にはLong型を使いましょう。
Dim Row As Long
For Row = 1 To 10
Cells(Row, 1).Value = Cells(Row, 2).Value
Next
日付はDate、小数はDouble
日付、小数は専用のデータ型を使いましょう。
セルの内容を格納するときはVariant型を使う
セルには、数値だけでなく文字、日付データなどが入力される可能性もあります。
そのため、セルの値を「変数」に格納する場合には、特別な理由がない限りはVariant型を使いましょう。