機能と数式 | VBA | セミナー | オンラインソフト | お問い合わせ | その他
Top > Excel > VBA > VBA高速化テクニック

型を指定する



昔から「こんなとき変数の型は…」という話題はプログラマたちにとって永遠のテーマでした。なぜなら、使用する変数の型によってプログラムのサイズや、実行速度が大きく変わると言われていたからです。では、VBAではどうなのか。さっそく検証してみましょう。

 Test1Test2%
1回目00:4700:2961.7%
2回目00:4700:3063.8%
3回目00:4700:2961.7%
4回目00:4800:2960.4%
5回目00:4700:2961.7%
6回目00:4700:3166.0%
7回目00:4600:3065.2%
8回目00:4700:3166.0%
9回目00:4500:3066.7%
10回目00:4600:3167.4%
平均00:4700:3064.0%

Sub Test1()
    Dim i As Variant, j As Variant
    For i = 1 To 30000
        For j = 1 To 30000
        Next j
    Next i
End Sub

Sub Test2()
    Dim i As Integer, j As Integer
    For i = 1 To 30000
        For j = 1 To 30000
        Next j
    Next i
End Sub

変数を使うとき、メモリの内部ではその変数分の領域を確保します。大きいデータを入れる変数は大きな領域を必要とし、小さい変数は小さい領域で済みます。そこで当然予想できるのは、大きい領域の変数は小さい変数に比べて使用に時間がかかるということです。

上記の検証は、For Nextステートメントを繰り返すだけの何もしないマクロです。ここで問題になるのは、カウンタ変数の型です。Test1ではバリアント型(Variant)、Test2では整数型(Integer)を使ってみました。結果は明かです。

バリアント型は何でも格納できる万能の変数型です。数値なら膨大な桁数を格納できます。一方の整数型は32,767から-32,767の数値だけを格納できるコンパクトな変数型です。For Nextステートメントのように何度も変数を操作するケースでは、この差が大きく影響してきます。

それなら、カウンタ変数は整数型で宣言すればいい…と理解できたものの、変数の宣言方法を誤ってはいけません。次のコードは3つの変数を宣言していますが、整数型で宣言されているのは最後の「k」だけです。最初の2つ「i」と「j」は整数型ではなくバリアント型変数になります。

Sub Sample()
    Dim i, j, k As Integer
End Sub

「iとjとkを整数型で」と宣言したつもりでも、VBAでは「iとjは型を省略、kは整数型で」という宣言になるのです。そしてこれもVBAのルールですが、変数の型を省略して宣言したとき、その変数はバリアント型になってしまいます。3つの変数全てを整数型で宣言するには、次のように書かなければなりません。

Sub Sample()
    Dim i As Integer, j As Integer, k As Integer
End Sub

さて、変数には他にも多くの型があります。他の型では速度がどう違うのでしょう。Test1と同じコードで、変数の型だけを変えて検証してみましょう。

 Test3Test4%
1回目00:3200:42131.3%
2回目00:3000:42140.0%
3回目00:3100:42135.5%
4回目00:3000:41136.7%
5回目00:3100:42135.5%
6回目00:3000:41136.7%
7回目00:3100:41132.3%
8回目00:3000:43143.3%
9回目00:3000:41136.7%
10回目00:3000:42140.0%
平均00:3100:42136.7%

Sub Test3()
    Dim i As Long, j As Long
    For i = 1 To 30000
        For j = 1 To 30000
        Next j
    Next i
End Sub

Sub Test4()
    Dim i As Double, j As Double
    For i = 1 To 30000
        For j = 1 To 30000
        Next j
    Next i
End Sub

Longは長整数型といって2,147,486,647までの整数を格納できます。なんと整数型(Integer)の約65、000倍。ところが実際は整数型(Integer)と比べてあまり差はありません。Test4で宣言したDoubleは倍精度浮動小数点型と呼ばれる型で、正の数は約4.9×10の-324乗〜1.8×10の308乗という…まぁ、要するに一般的なユーザーが使うのなら何も問題ない桁数を格納できるわけです。もちろん高速性は期待できません。

次は文字列型(String)とバリアント型(Variant)を比較してみましょう。

 Test5Test6%
1回目00:3000:37123.3%
2回目00:3000:36120.0%
3回目00:3100:37119.4%
4回目00:3000:37123.3%
5回目00:3000:37123.3%
6回目00:3000:37123.3%
7回目00:2900:37127.6%
8回目00:3000:37123.3%
9回目00:2900:36124.1%
10回目00:2900:36124.1%
平均00:3000:37123.2%

Sub Test5()
    Dim i As Integer, j As Integer, tmp As String
    For i = 1 To 10000
        For j = 1 To 10000
            tmp = "tanaka"
        Next j
    Next i
End Sub

Sub Test6()
    Dim i As Integer, j As Integer, tmp As Variant
    For i = 1 To 10000
        For j = 1 To 10000
            tmp = "tanaka"
        Next j
    Next i
End Sub

とまあ、変数の型によってマクロの実行速度が変わるわけです。私も拙著の中で「適切な型を宣言しましょう」と何度か書いています。しかし、最近になって考え方が変わりました。

最近のパソコンは非常に高速です。また、1秒が問題になるような速度重視のマクロを作る機会も、それほど多くはありません。それなら、Selectしないなど一般的な高速化に気を付けていれば、変数はバリアント型を多用してもいいんじゃないかな?って。

いくら速度的に不利だからといっても、やはり「Dim i As Integer, j As Integer, k As Integer」と書くよりも「Dim i, j, k」の方が簡単ですからね。速度的には不利だが記述の簡便さを重視して、あえて省略している…という認識を持てば、バリアント型の多用も悪くないと思います。まぁ、For Nextステートメントのカウンタ変数にバリアント型を使うのは、いささか抵抗もありますけど(^^;

なお、月数を表す1〜12のように、範囲の小さな整数値を入れる変数としてByte型を使うビギナーをたまに見かけますが、これは誤りですからやめましょう。Byte型は0〜255の整数値を格納できますが、これはバイトデータを格納するために用意されている型です。



このエントリーをはてなブックマークに追加