VBAで定数の宣言にデータ型を指定するAsほにゃららを書きますか?

ことりちゅん(・8・)の、思い立ったが吉日、Twitterアンケートです。 今日は定数の宣言で型宣言文字を書くべきか否か、疑問に思ったので調査をしてみました。 書かない人 Const PI = 3.14 書く人   Const PI As Double = 3.14
15
いみひと @nukie_53

@KotorinChunChun VBAは、全ての整数表現をまずはIntegerで考えようとするので、リテラル値の評価時に指定しないとダメ、という話ですね。 自分も一時期悩まされました。

2020-02-12 20:38:49
VBA100本ノックとエクセル問題 @yamaoka_ss

@nukie_53 @KotorinChunChun これって、constの型というよりclngの問題な気がするのですが、どうなんでしょうか。

2020-02-12 21:07:49
ちゅん🐤 @KotorinChunChun

@yamaoka_ss @nukie_53 質問の意味が私にはイマイチ分かりませんorz (この場合、CLng()は関係ないんじゃないかな?って) (VBAのリテラルを解釈する仕組みの問題的な?)

2020-02-12 21:29:47
VBA100本ノックとエクセル問題 @yamaoka_ss

@KotorinChunChun @nukie_53 すみません、ぱっと見で反応してしまった部分もあるのですが、 画像のようなことかなと思ったので。 例えば、 Const i As Long = 5.5 これは、6になるので。 pic.twitter.com/Zl5hu1AWu7

2020-02-12 21:34:09
拡大
ちゅん🐤 @KotorinChunChun

@yamaoka_ss @nukie_53 確かにConst に限った話じゃないので、あらゆる場面で起こりますよね。常に気をつけなければ。 5.5が6になるのは、別件のような気もしますね。 VBAが実数を整数に暗黙的にキャストする時は、なぜか丸めが起こるという・・

2020-02-12 22:53:51
VBA100本ノックとエクセル問題 @yamaoka_ss

@KotorinChunChun @nukie_53 はい、つまり言わんとしたのは、longにリテラルをいれる場合全般の話であって、constの型の話とはちがうのではないか、ということです。

2020-02-12 23:05:16
ちゅん🐤 @KotorinChunChun

@yamaoka_ss @nukie_53 全くもって仰るとおりですね。 私がここでヤバいと思ったのは、Constで型指定をする理由として 「型指定をしないと思わぬ挙動をしそうで怖い」 が多く挙げられると思うからです。 これが転じて 「型指定をしているConstの宣言は安全である」 と信じていたら、罠にハマるからヤバいぞと思った訳です。

2020-02-12 23:11:15
ちゅん🐤 @KotorinChunChun

@yamaoka_ss @nukie_53 特に16進数リテラルってConstで設定する傾向が強い気がするので、この組み合わせのバグは起こりやすいんじゃないかなと。(私だけ?) だから、Constの型指定を気にする人は、値の方にも型指定しましょうね!(軽い煽り)と言いたかったのですが、上手く意図は伝わって無さそうです。

2020-02-12 23:13:29
VBA100本ノックとエクセル問題 @yamaoka_ss

@KotorinChunChun @nukie_53 はい、16進はやってしまいますので要注意だと思います。 追加で言うなら、 Const i = 10000 Debug.Print i * 10 これはエラーになりますので、型指定もしくは型文字どちらかは必要だと思います。

2020-02-12 23:16:45

要するに 両辺の型指定がされていないことによる問題 です。

Const i = 10000&
Debug.Print i * 100&

で十分ですが、As Longは &を付けない人対策 で書いたほうが安全と言えるでしょう。

まとめ

ちゅん🐤 @KotorinChunChun

結果はこのようになりました。 8割の方は書く派みたいですね! pic.twitter.com/JUWw7nSdEr

2020-02-13 00:35:24
拡大

本日のアンケートはこのような結果になりました。

書かない:21%
書く:79%

As ほにゃららを書かないことによるリスクを懸念しての投稿でしたが、直接的なリスクはなさそうだと言う事が分かりました。

しかし、全然別の視点において、書いておくのは一定の効果がある事も分かりました。

  • 32767以下の整数で宣言した場合にIntegerになってしまう。
  • Integer同士で計算させて結果が32768を超えるとオーバーフローする
  • よって、As ほにゃらら を書く書かないに関わらず、すべてのリテラルには型指定文字を書いた方が安全である。
Sub Test()
    Const NUM1 As Long = 32767  'Longになる
    Const NUM2 = 32767&         'Longになる
    Const NUM3 = 32767          'Integerになる

    Debug.Print NUM1 + 1&   ' long + long = long : 安全
    Debug.Print NUM1 + 1    ' long +  int = long : 安全

    Debug.Print NUM2 + 1&   ' long + long = long : 安全
    Debug.Print NUM2 + 1    ' long +  int = long : 安全

    Debug.Print NUM3 + 1&   ' long + long = long : 安全
    Debug.Print NUM3 + 1    '  int +  int =  int : 32768以上はオーバーフローする
End Sub

くれぐれも、ご安全に!!!

また
・アンケートに答えてくださった方
・リプライで反応をくれた方
・更には色々な意見をくださった方
いつも有難うございます。

参考資料

リンク エクセルの神髄 定数宣言のConstと型宣言文字|VBA入門 前回は変数を説明しましたが、変数があれば、当然の定数もありConstで宣言します。つまり、変数は値が変わるもの、定数は値が変わらないものです。定数とは、数値や文字列の代わりに使用される、意味を持たせた名前のことです。 1 user 1
リンク docs.microsoft.com 定数の宣言 (VBA)
リンク docs.microsoft.com データ型の概要 1 user
リンク docs.microsoft.com 型文字 - Visual Basic 3 users
リンク docs.microsoft.com Const ステートメント (VBA)