型宣言を省略するとVariant型
VBAの変数宣言には型の宣言を省略することが出来ます。省略した場合はVariant型となります。
そのため、以下の2つの変数宣言はどちらも同じVariant型になります。
1 2 |
Dim a Dim b As Variant |
型は数値型と文字列型とクラス型(オブジェクト型)とユーザー定義型の4種類
型宣言で使う種類には、数値型 と 文字列型 と クラス型(オブジェクト型) と ユーザー定義型の4種類があります。
その中でも数値型は一番種類が多く、Byte、Boolean、Integer、Long、Single、Double、Currency、Date、Decimal、LongLong、LongPtrの10種類があります。Boolean型はTrueとFalseですが、それらの定数の実体はTrue=-1とFalse=0ですので数値型になります。
あとの文字列型はString、クラス型は任意のクラス、ユーザー定義型も任意のユーザー定義型になります。
ユーザー定義型とは他のプログラミング言語で言う構造体のことです。
クラス型は一般的にはオブジェクト型という表記がされますが、オブジェクト指向で使われる「オブジェクト」という定義が分かりにくいものではなく、クラスのインスタンスを格納するための型になります。わけわからんという場合は、変数名にドット(.)を付けると、メソッドやプロパティが出るやつ、と覚えていても問題ありません。
例えば、以下のコードであれば、Range(“A1”)もオブジェクト(クラスのインスタンス)ですし、その次のOffset(0, 1)もオブジェクト(クラスのインスタンス)です。
そして、変数v1,v2,v3はいずれも「A1セルから一つ右のセルの値」が設定されています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
Sub VariantTest() Dim r Dim o Dim v1 Dim v2 Dim v3 Set r = Range("A1") Set o = Range("A1").Offset(0, 1) v1 = Range("A1").Offset(0, 1).Value v2 = r.Offset(0, 1).Value v3 = o.Value End Sub |
型を宣言するメリット
クラス型とユーザー定義型は候補が表示される
型を宣言するメリットは数値型や文字列型の場合は無いのですが、クラス型やユーザー定義型の場合にはメリットがあります。
それは、クラス型の場合はメソッドやプロパティがドット(.)を入力したあとに候補が表示され、ユーザー定義型の場合もドット(.)のあとにメンバー変数の候補が表示されることです。
そして、クラス型とユーザー定義型は必ず型宣言すべきです。
処理速度がほんの少しだけ速い
型を宣言した場合はVariant型よりもほんの少しだけ処理速度が速いです。どれぐらい速いのかと言いますと、体感速度として何が速いのか分からないぐらいは速いです。
数値型とVariant型の比較であれば、CPUがCore i3とかでも100万回のループ処理で1秒の差があるかどうか。
言い方を変えると、大して変わらない、ということです。
なので私はよほど大量のデータを扱う場合で処理速度が優先度として高い場合などでない限り型宣言はしません。
関数の引数のエラー処理の実装が軽減できる
関数を自作する場合に引数の型を宣言しておけば、Variantのようになんでも引数として渡されることがなくなり、本来は文字列型で渡されるべきところに数値型で渡されていないか、などといったエラー処理を実装しなくてよくなるという面はあります。
ただ、多くの場合はちょっと動かしてみればすぐに分かるような話ですので、呼び出す側に型宣言を強制することが良いことなのかどうかは判断が分かれるでしょう。バリバリの業務用のマクロで、エラーは一切許さない!というようなものであれば厳密な型宣言をして呼び出し元と呼び出し先の不整合がないようにすることも必要な場合はあるでしょう。
ここはどういうものを作るかで分かれる部分です。
もし関数の引数に型宣言がない場合で関数に型判定のエラー処理を実装していない場合、呼び出し側で全然違う型を使って関数を呼び出しても、その間違いに気が付くのは関数を実行したときエラーが表示されてからになることがあります。
それを避けるために型宣言をする、という面ではメリットになります。
型宣言をしない場合に起きる問題
型宣言をしない場合に起きる問題が一つあります。それは、+演算子の挙動です。+演算子は数値の足し算として利用しますが、文字列同士の連結にも使えます。個人的には「こんな間違いを起こすような言語仕様にすんなよ」と思うのですが、そうは言っても仕方がないので、コーディング時に気を付けなければなりません。
不注意で+演算子を使う変数が文字列なのか数値なのかをはっきりしない場合に想定とは逆の動作になる恐れはあります。具体的には数値として123+4=127を求めたいところが、文字列であることを見落として”123″ + “4” = “1234”になる場合やその逆の場合です。
しかし、そもそもの話ですが、文字列の連結では+演算子を使わず、&演算子で連結することを習慣付けておく方がよいと思います。
Excelの関数も連結には&を使いますので、ルールとして「文字列は&で連結する」と統一している方が間違いを減らせます。
型宣言をした方がいいのか、しない方がいいのか
私は数値型と文字列型の場合はほとんど型宣言をしません。クラス型とユーザー定義型の場合のみ型宣言をしていると言ってもいいぐらいです。正確には、クラス型とユーザー定義型は必ず型宣言をします。
数値型と文字列型の型宣言を省略する理由は、面倒なのと、やらなくてもいいことをやる必要性を感じないことと、そして最大の理由の、型宣言をしなくて困ったことが無い、という実体験からです。ただ、その前提には、コードとして型宣言を書いてなくても、こういうコードを書いたらどういう型になる、ということをちゃんと理解していることがあります。
じゃあ、型宣言はした方がいいのか、しない方がいいのか、という話になると、やらなくていいや、と思う方はやらなくていいと思います。もちろん理解した上で判断できればそれにこしたことはないですが、動けばOK!というのも一つの考え方です。
そんな程度の話です。
プログラミング言語にはVBAのように型宣言を省略できるものもあれば、C言語等のように省略できないものもあります。ただ、いずれの場合においても、型宣言しようがしまいが、プログラムの挙動に使う変数がどういうものであるのかを理解している方が、よりラクにコーディングできます。
少なくとも、String型とInteger型の使い分けができるようにはなっている方がいいです。そうすると、型宣言を省略していたとしても「これは数値、これは文字列、これは小数点ありの数値」と判別付くようになります。
もしあなたが初学者だったり本職プログラマーではない場合は、「型宣言はよくわかんない。動けばOK!」でも全然いいと思います。