知らずに落ちると抜け出せなくなるVBAの落とし穴です。
- 足し算の結果がかなり大きな誤った値になる
- セルの表示書式を「文字列」にすると正しく計算されない
あたりにお悩みの方は、この落とし穴に落ちていないかご確認ください。
「+」を文字列に対して使うと連結演算子(&と同じ)になる
タイトルのコードを実行してみて下さい。
MsgBox "1" + "1"
見事に「11」が表示されます。
正確には「"11"」ですね。
VBAの「+」演算子はかなり珍しい特徴があり、
文字列同士に使用した場合は「&」と同じ連結演算子になります。
これは文字列と文字列に使用したとき限定の挙動で、
どちらかが数値であればいつもの加算演算子として動きます。
"1"+"1" | 11 |
1+"1" | 2 |
"1"+1 | 2 |
"1"+"1"+1 | 12 |
1+"1"+"1" | 3 |
そうそう発生するような罠ではないのですが、
だからこそ知らずに発生すると原因究明が困難になります。
この仕様は覚えておきましょう。
注意すべき処理
実際は"1"+"1"なんて処理はやりませんので、
注意すべきは変数やセルから値を取得する場合です。
これが発生する主なパターンは以下の2つです。
文字列の一部を数値として抜き出す場合
Left/Mid/Right関数などを使用し「○日」から○を取り出した場合、
結果が数字であっても返り値の型は文字列です。
このため以下のコードの結果は「1020」になってしまいます。
MsgBox Left("10日", 2) + Left("20日", 2)
セル値が「文字列」になっている場合
セルの書式が文字列になっている場合など、
セルの値が文字列の場合も同じ罠が発生します。
例えば以下のシートはA列とB列の表示書式が「文字列」になっており、
緑の▲が表示されている値は文字列です。
このとき、このシートに対して実行される
MsgBox Range("A1") + Range("B1")
これは「11」を表示します。
画像にある通り、セルの数式で「=A1+B1」を計算したときと結果が異なります。
シート数式における「+」はまごうことなく加算演算子ですので、
この違いは当然なのですが、うっかりしやすい部分なので気を付けましょう。
バリアント変数に注意
上記2パターンの問題は、変数を使っていると遭遇しにくいです。
Long型の変数に入れれば文字列も数値に自動で変換されるため、
Dim x As Long, y As Long x = Left("10日", 2) y = Left("20日", 2) MsgBox x + y
このコードはしっかり「30」を計算してくれます。
しかし、変数の型を指定しない「バリアント変数」を使用した場合は、
文字列は文字列のまま変数に格納されるため、
Dim x, y x = Left("10日", 2) y = Left("20日", 2) MsgBox x + y
このコードの結果は「1020」になります。
変数の型は可能な限り指定するよう心がけましょう。