【VBA】変数に$(ドルマーク)をつける意味について

古くからVBAを保守している環境などでは、関数に$(ドルマーク、ダラー)がついているコードを見ることがあると思います。

例えば以下のようなコードになります。

Sub Macro1()
    Dim test As String
    Dim test2 As String
    
    test = Trim$(" 12345")
    test2 = Trim(" 12345")
End Sub

Trimは引数で与えた文字列からスペースを取り除くという関数です。

上記コードでは、Trim$で取得した値とTrimで取得した値はどちらも”12345″となります。

またLeft$とLeft、Mid$とMidなども全く同じ値が返却されます。

同じ戻り値となるので$(ドルマーク)を付ける意味はないと思われがちですが、$の有無で厳密に言うと動きが異なります。

$をつけた場合の動きの違いと、$をつける意義について記載をしていこうと思います。

$(ドルマーク)をつけると戻り値が文字列になる

いきなり結論となりますが、$(ドルマーク)をつけることによって関数の戻り値が文字列型になります

$をつけない場合、関数の戻り値はVariant型になります。

$をつけない場合ですが、引数に文字列を取るのに戻り値がVariant型になってしまうのは違和感があります。

ただ、マイクロソフトの公式ページのヘルプでも仕様として記載されています。

例えばLeft関数のヘルプは以下のとおりです。

https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/left-function

文字列の左から数えて指定した数の文字を含むバリアント型 (内部処理形式 String の Variant) を返します。

暗黙的な型変換があるため$は使わなくても良い

LeftやTrim関数の戻り値がVariant型になってしまうということを知ってから「戻り値が文字列であることを明示するためにLeft$やTrim$を使うほうが良いのではないか」と考えていた時期もありました。

しかし、現在では「どちらでも良い」と考えるようになっています。というのもVBAはかなり柔軟な言語なので、型の違いが致命的になるケースが少ないです。

例えばですが

Sub Macro1()
    Dim test As Integer
    Dim test2 As String
    test = CStr(12345)
    test2 = 12345

End Sub

上記コードを実行すると

Integer型の変数に文字列型の”12345″

String型の変数に数値型の12345

がそれぞれ格納されることになります。他の型定義がしっかりしている言語であれば、エラーとなってしまいそうですがVBAで上記コードを実行すると

正しい型に変換された値が格納されます。つまりLeft関数でVariant型が戻されたとしても、それを格納する変数が文字列型であれば文字列で格納されるということです。

更に以下のようにVariant型とString型を比較してみると

Sub Macro1()
    Dim test As Variant
    Dim test2 As String
    test = 12345
    test2 = "12345"
    
    MsgBox test = test2
End Sub

実行結果

同じ値だと評価されます。

この柔軟性は「逆にバグを乱発してしまいそう」だと思ってしまいます。

ただVBAでこの仕様となっている以上、$をつけないことによってプログラムの動きが変わってしまうことは皆無だと思ったので、敢えて$をつけるメリットは存在しないと思いました。


$をつけることによって混乱を生むかも?

逆に言うと$をつけて文字列型で返すデメリットも無いので、つけてもつけなくてもどちらでも良いのではないかと思いました。

なので結論としては「付けても付けなくてもどっちでも良い」が一般的な答えになりそうです。

一応、以下のサイトによると$付きの場合は速度面で有利とのことです。

正直内部の動き的には同じだと思うのですが、Variant型はメモリを少し多く確保するはずなのでその辺がパフォーマンスに影響する?

「どうせ使うなら速いほうがいいぜ」と思う人は$付き派でいくのは有りだと思います。(とは言え、ほぼ変わらないと思います。)

また、$付きの関数はNull 値を引数に使用して呼び出すとエラーが発生するという情報があります。戻り値がVariant型じゃないからだと思います。

https://docs.microsoft.com/ja-jp/previous-versions/office-development/cc376077(v=msdn.10)?redirectedfrom=MSDN

文字列型のバリアント値を返す関数では、Null 値を問題なく使用できます。

しかし、文字列型の初期値は空文字なのでNull 値を渡すという場面は考えられないです。よってこの仕様による違いも無視して問題なし。

個人的には、$は付けない方針で行きたいと思います。

理由としては…

  • $を付けない人が多数だと思うので、自分だけ$をつけるとコードの統一性が無くなりそう
  • $の意味を知らない人が混乱しそう(これは、なんだろうと疑問に思ってしまいそう)

という感じです。マイナーすぎる関数を使うと面倒な事に巻き込まれることになりそうなので、無難に付けないようにしています。

「そんなこと気にする必要あるか?」と言われそうですが、ベテランエンジニアのいる現場だと怒られたりすることは結構あるイメージです

(実際に「IIF」というマイナーな三項分岐関数を使ったら、「全部IF文に書き直せ」と言われたことがある…)


コメントを残す

メールアドレスが公開されることはありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)