型は覚えなくていい


変数にはという仕組みがあります。

変数は、何かを入れる入れ物のようなものですが、たとえばテニスラケット用のケースにゴルフのクラブは入りませんよね。あるいは、ギターのケースにトロンボーンは入りません。また、もし濡れた物を入れるなら、きっと水が漏れないビニール製の入れ物を使うでしょう。紙の袋では破れてしまうかもしれません。変数にもいろいろなタイプがあり、数値を入れる専用の型や、文字列を入れる専用の型などがあります。変数を宣言するときは、その変数に何を入れるかをあらかじめ想定して、適切な型を指定しなければなりません。

VBAでは、次のような型があります。よく使う型は太字にしてあります。

型名 型指定文字 格納できるデータ
ブール型 Boolean TrueまたはFalse
バイト型 Byte 0~255までの整数
整数型 Integer -32,768~32,767の整数
長整数型 Long -2,147,483,648~2,147,483,647の整数
通貨型 Currency -922,337,203,685,477.5808 ~ 922,337,203,685,477.5807の固定小数点数
単精度浮動小数点数型 Single 負の値:約-3.4×10(38乗)~-1.4×10(-45乗)正の値:約1.4×10(-45乗)~1.8×10(38乗)
倍精度浮動小数点数型 Double 負の値:約-1.8×10(308乗)~-4.0×10(-324乗)正の値:約4.9×10(-324乗)~1.8×10(308乗)
日付型 Date 日付:西暦100年1月1日~西暦9999年12月31日時刻:0:00:00 ~ 23:59:59
文字列型 String 任意の長さの文字列
オブジェクト型 Object オブジェクト
バリアント型 Variant すべてのデータ

よく使う型

最もよく使われる型は、なんといっても長整数型(Long)文字列型(String)でしょう。整数を格納する型は、長整数型(Long)のほかにInteger(整数型)もありますが、Integer(整数型)は最大で32,767までしか入りませんから、特別な事情がある場合を除いて、整数を入れる変数は長整数型(Long)で宣言すればいいでしょう。また、たとえば月を表す数値(1~12)のように、非常に小さい整数を格納する変数としてバイト型(Byte)を使っているケースをときおり見かけますが、これは相応しくありません。バイト型(Byte)は、バイナリデータという特別な値を格納するために用意された型です。もちろん、単純な数値を格納することも可能ですが、すごく変です。

  • 整数を入れる変数 → 長整数型(Long)
  • 文字列を入れる変数 → 文字列型(String)

と覚えておきましょう。ほとんどのマクロでは、これだけで十分です。

長整数型(Long)型は整数しか格納できない点に留意してください。小数点以下の数値は格納できません。次のマクロで確認してみましょう。

Sub Sample2()
    Dim tmp As Long
    tmp = 10 / 4
    MsgBox tmp
End Sub

10÷4は2.5です。しかし、変数tmpには2しか入っていません。このように、小数点以下の数値を扱う変数は単精度浮動小数点型(Single)を使います。

Sub Sample2()
    Dim tmp As Single
    tmp = 10 / 4
    MsgBox tmp
End Sub

ブール型(Boolean)は、TrueまたはFalseのいずれかを格納するときに使います。

Sub Sample3()
    Dim flag As Boolean
    If Range("A1") <> "" Then
        flag = True
    Else
        flag = False
    End If
    If flag Then
        MsgBox "セルA1は空ではありません"
    Else
        MsgBox "セルA1は空です"
    End If
End Sub

日付型(Date)は、日付や時刻のデータを格納するときに使います。

Sub Sample4()
    Dim tmp As Date
    tmp = Now
    MsgBox Year(tmp)
End Sub

セル自身やワークシート自身など、オブジェクトを格納するときはオブジェクト型(Object)を使います。

Sub Sample5()
    Dim ws As Object
    Set ws = ActiveSheet
    MsgBox ws.Name
End Sub

Setの使い方は「Setを使うケース」で解説します。

型は覚えなくていい

どうです?面倒くさいですか?

もう20年以上前ですが、私が初めてプログラミング言語を学んだときも、この変数の型で悩みました。「いくつの整数を格納するかなんて、プログラムを実行してみなければわからない。そもそも、数値が入るか文字列が入るか事前にわからないときは、どーすりゃいいの?」みたいに。ですから、ビギナーの方が、この変数の型で悩む気持ちはよくわかります。ですが、ちょっと待ってください。上の表の一番下にバリアント型(Variant)というのがあります。格納できるデータには「すべてのデータ」とあります。そう、バリアント型(Variant)の変数は、何でも入れることができる万能の型なんです。整数だろうが、文字列だろうが、小数点以下の数値だろうが、配列だろうが、オブジェクトだろうが、もう何でも格納できちゃいます。

そんな便利な型があるのなら、何も面倒くさい型指定なんてする必要ないじゃん!

そう感じた方もきっといるでしょう。

そうです。その通りです。どの型を指定すればいいかわからないときはバリアント型(Variant)を指定すればいいのです。

「どの型を指定すればいいかわからない → だから変数は宣言しない」という発想が乱暴だと言ったのは、そういう意味です。「どの型を指定すればいいのかわからない → だったらバリアント型(Variant)を指定すればいい → そのかわり変数の宣言はする」と、そう考えれば楽でしょ。変数の宣言は、決して難しくありません。「Dim 変数名」と書けばいいのですから。

バリアント型(Variant)の変数を宣言するには、

Dim 変数名 As Variant

と書きます。あるいは、もっと簡単な方法があります。VBAでは、型の指定を省略すると、その変数はバリアント型(Variant)が指定されたものとみなす、というルールがあります。したがって、バリアント型(Variant)の変数は

Dim 変数名

だけでいいんです。これなら超簡単ですね。

変数の型がわからないのなら、無理して覚えなくていいです。型指定がネックになって変数の宣言を省略するくらいなら、全部の変数をバリアント型(Variant)にすればいいです。ただし、適切な型を指定できる方が、できないよりはいいでしょう。ですから、VBAの学習を続けて、余裕ができたら型についても学んでください。

バリアント型変数のデメリット

何でも格納できる万能のバリアント型(Variant)は、しかし「あまり使うべきではない」とも言われています。その理由は、おおむね次の2点です。

  1. マクロの実行速度が遅くなる
  2. 誤動作を招く原因になる

バリアント型(Variant)変数は、その他の型に比べて実行速度が遅くなります。しかし、非常に高速なCPUやメモリを搭載した現在のパソコンでは、その差はごくわずかです。たとえば、次のマクロで確認してみましょう。

Declare Function GetTickCount Lib "kernel32" () As Long
Sub Sample6()
    Dim i As Long, ST As Long
    ST = GetTickCount
    For i = 1 To 10000
        Cells(i, 1) = i
    Next i
    MsgBox (GetTickCount - ST) / 1000
End Sub
Sub Sample7()
    Dim i As Variant, ST As Long
    ST = GetTickCount
    For i = 1 To 10000
        Cells(i, 1) = i
    Next i
    MsgBox (GetTickCount - ST) / 1000
End Sub

【Sample6の実行結果】

【Sample7の実行結果】

実行したパソコンは、Windows XP(Home)+Excel 2007+Atom+1GBメモリの、いわゆるネットブックです。

For Nextのループで使用するカウンタ変数iを、Sample6では長整数型(Long)で宣言し、Sample7ではバリアント型(Variant)にしました。10000回のループを実行して、その差はわずか0.078秒です。これって、重要な問題でしょうか?

誤動作の原因になるというのは、一例を挙げると次のようなケースです。

Sub Sample8()
    Dim A As Long, B As Long
    A = InputBox("数値1は?")
    B = InputBox("数値2は?")
    MsgBox A + B
End Sub
Sub Sample9()
    Dim A As Variant, B As Variant
    A = InputBox("数値1は?")
    B = InputBox("数値2は?")
    MsgBox A + B
End Sub

【Sample8の実行例】

【Sample9の実行例】

InputBox関数は、マクロ実行中にユーザーからデータを受け取る命令です。InputBoxは、入力されたデータを文字列形式で返します。Sample8では、変数Aと変数Bがどちらも長整数型(Long)で宣言しています。文字列型で返された「100」と「200」は、自動的に型変換されて、整数として2つの変数に格納されます。変数Aと変数Bには整数が入っているのですから「A + B」で足し算が行われて「300」が表示されます。

一方のSample9は、変数Aと変数Bがバリアント型(Variant)で宣言されています。InputBoxは文字列型を返しますので、「100」と「200」はどちらも文字列として格納されます。文字列に対して「+演算子」を使うと、「&演算子」と同じように文字列同士が結合されます。したがって「100」と「200」が結合されて「100200」となりました。

変数の型指定によって実行結果が異なるのは事実ですが、誰もが、毎回、必ず遭遇する現象ではありません。たとえば、次のようなケースでは問題ありません。長整数型(Long)もバリアント型(Variant)も、同じ結果になります。てことは、バリアント型でもOKということです。

Sub Sample10()
    Dim A As String, B As String
    Dim C As Variant, D As Variant
    A = "100"
    B = "200"
    C = "100"
    D = "200"
    MsgBox A + B
    MsgBox C + D
End Sub
Sub Sample11()
    Dim A As Long, B As Long
    Dim C As Variant, D As Variant
    A = 100
    B = 200
    C = 100
    D = 200
    MsgBox A + B
    MsgBox C + D
End Sub

【Sample10の実行結果】

【Sample11の実行結果】

本来なら型指定をすべき変数を、バリアント型(Variant)として扱うデメリットはほかにもあります。

  1. カッコ悪い
  2. 何となく美しくない
  3. ベテランから嫌われる

確かに、次のようなコードを見ると、何となく落ち着きません。

Sub Sample12()
    Dim buf
    Dim i
    buf = InputBox("名前は?")
    For i = 1 To 5
        Cells(i, 1) = buf
    Next i
End Sub

InputBox関数は文字列を返しますので、それを受ける変数bufは文字列型が一般的です。For Nextステートメントで使うカウンタ変数は、長整数型(Long)が相応しいでしょう。できれば、次のように型指定されていた方が、何となくしっくりきます。

Sub Sample12()
    Dim buf As String
    Dim i As Long
    buf = InputBox("名前は?")
    For i = 1 To 5
        Cells(i, 1) = buf
    Next i
End Sub

バリアント型(Variant)変数を多用するということは、歯ブラシだろうがエンピツだろうが、何でもかんでもスーツケースに入れるようなものです。変数の型指定を理解している者からすると、違和感を感じるのも無理はありません。

理想は、適切な型を宣言できるようになることです。そのために学習することも必要です。ただし、変数の型を適切に使い分けられないビギナーのうちは、無理して苦労しなくていいです。バリアント型を使ってください。そして、余裕ができたら、変数の型についても学習してください。「型は覚えなくていい」というのは、そういう意味です。