| <> | |||||||||||||||||||||||||||||||||||||
| <> | |||||||||||||||||||||||||||||||||||||
型は覚えなくていい | |||||||||||||||||||||||||||||||||||||
変数には型という仕組みがあります。 変数は、何かを入れる入れ物のようなものですが、たとえばテニスラケット用のケースにゴルフのクラブは入りませんよね。あるいは、ギターのケースにトロンボーンは入りません。また、もし濡れた物を入れるなら、きっと水が漏れないビニール製の入れ物を使うでしょう。紙の袋では破れてしまうかもしれません。変数にもいろいろなタイプがあり、数値を入れる専用の型や、文字列を入れる専用の型などがあります。変数を宣言するときは、その変数に何を入れるかをあらかじめ想定して、適切な型を指定しなければなりません。 VBAでは、次のような型があります。よく使う型は太字にしてあります。
よく使う型最もよく使われる型は、なんといっても長整数型(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 tmpEnd Sub 10÷4は2.5です。しかし、変数tmpには2しか入っていません。このように、小数点以下の数値を扱う変数は単精度浮動小数点型(Single)を使います。 Sub Sample2() Dim tmp As Single tmp = 10 / 4 MsgBox tmpEnd 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 IfEnd 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.NameEnd Sub Setの使い方は「Setを使うケース」で解説します。 型は覚えなくていいどうです?面倒くさいですか? もう20年以上前ですが、私が初めてプログラミング言語を学んだときも、この変数の型で悩みました。「いくつの整数を格納するかなんて、プログラムを実行してみなければわからない。そもそも、数値が入るか文字列が入るか事前にわからないときは、どーすりゃいいの?」みたいに。ですから、ビギナーの方が、この変数の型で悩む気持ちはよくわかります。ですが、ちょっと待ってください。上の表の一番下にバリアント型(Variant)というのがあります。格納できるデータには「すべてのデータ」とあります。そう、バリアント型(Variant)の変数は、何でも入れることができる万能の型なんです。整数だろうが、文字列だろうが、小数点以下の数値だろうが、配列だろうが、オブジェクトだろうが、もう何でも格納できちゃいます。 そんな便利な型があるのなら、何も面倒くさい型指定なんてする必要ないじゃん! そう感じた方もきっといるでしょう。 そうです。その通りです。どの型を指定すればいいかわからないときはバリアント型(Variant)を指定すればいいのです。 「どの型を指定すればいいかわからない → だから変数は宣言しない」という発想が乱暴だと言ったのは、そういう意味です。「どの型を指定すればいいのかわからない → だったらバリアント型(Variant)を指定すればいい → そのかわり変数の宣言はする」と、そう考えれば楽でしょ。変数の宣言は、決して難しくありません。「Dim 変数名」と書けばいいのですから。 バリアント型(Variant)の変数を宣言するには、 Dim 変数名 As Variant と書きます。あるいは、もっと簡単な方法があります。VBAでは、型の指定を省略すると、その変数はバリアント型(Variant)が指定されたものとみなす、というルールがあります。したがって、バリアント型(Variant)の変数は Dim 変数名 だけでいいんです。これなら超簡単ですね。 変数の型がわからないのなら、無理して覚えなくていいです。型指定がネックになって変数の宣言を省略するくらいなら、全部の変数をバリアント型(Variant)にすればいいです。ただし、適切な型を指定できる方が、できないよりはいいでしょう。ですから、VBAの学習を続けて、余裕ができたら型についても学んでください。 バリアント型変数のデメリット何でも格納できる万能のバリアント型(Variant)は、しかし「あまり使うべきではない」とも言われています。その理由は、おおむね次の2点です。
バリアント型(Variant)変数は、その他の型に比べて実行速度が遅くなります。しかし、非常に高速なCPUやメモリを搭載した現在のパソコンでは、その差はごくわずかです。たとえば、次のマクロで確認してみましょう。 Declare Function GetTickCount Lib "kernel32" () As LongSub Sample6() Dim i As Long, ST As Long ST = GetTickCount For i = 1 To 10000 Cells(i, 1) = i Next i MsgBox (GetTickCount - ST) / 1000End SubSub Sample7() Dim i As Variant, ST As Long ST = GetTickCount For i = 1 To 10000 Cells(i, 1) = i Next i MsgBox (GetTickCount - ST) / 1000End 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 + BEnd SubSub Sample9() Dim A As Variant, B As Variant A = InputBox("数値1は?") B = InputBox("数値2は?") MsgBox A + BEnd 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 + DEnd SubSub 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 + DEnd Sub 【Sample10の実行結果】 【Sample11の実行結果】 本来なら型指定をすべき変数を、バリアント型(Variant)として扱うデメリットはほかにもあります。
確かに、次のようなコードを見ると、何となく落ち着きません。 Sub Sample12() Dim buf Dim i buf = InputBox("名前は?") For i = 1 To 5 Cells(i, 1) = buf Next iEnd SubInputBox関数は文字列を返しますので、それを受ける変数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 iEnd Subバリアント型(Variant)変数を多用するということは、歯ブラシだろうがエンピツだろうが、何でもかんでもスーツケースに入れるようなものです。変数の型指定を理解している者からすると、違和感を感じるのも無理はありません。 理想は、適切な型を宣言できるようになることです。そのために学習することも必要です。ただし、変数の型を適切に使い分けられないビギナーのうちは、無理して苦労しなくていいです。バリアント型を使ってください。そして、余裕ができたら、変数の型についても学習してください。「型は覚えなくていい」というのは、そういう意味です。 ツイートする |