• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:VBAの定数の使い方で、計算値を定数に入れることは可能ですか。)

VBAの定数の使い方と注意事項

このQ&Aのポイント
  • VBAの定数を使って計算値を定数に入れることはできません。定数には固定的な数値や文字列を入れるべきです。
  • 定数式には動的な要素を含めることはできません。計算値を定数に入れる場合は、変数を使用する必要があります。
  • VBAの定数はプログラムの実行中に変更することができないため、定数には固定的な値を入れることが重要です。

質問者が選んだベストアンサー

  • ベストアンサー
  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.3

#2の回答者です。 本当は、変数と定数の区別のつかない段階で、混乱するので、余計な話は聞かないで進めていったほうがよいのですが、一応、お答えしておきます。 定数は、変動したり値やプロパティを取得するものには使えません。だから、本来、比較のしようがありません。 グローバル変数のメリットとしては、一定の環境で、再取得することなく使えることです。主に、Auto_Open で取得して、最後まで使うことが多いです。グローバルにしておけば、他のプロシージャにでも、使えます。再取得する必要がないので、当然、処理スピードは上がります。 メモリについては、このレベルでは気にするほどのものはありません。String 型ですと、文字数に比例しますが、数値型は、仮にLong 型でも、4 Byte しかありません。Integer型は、2 Byte ですが、事実上、32ビットパソコンでは、4 Byte =32ビット分を使用します。メモリについては心配はほぼないと思います。処理速度の違いですが、定数と変数の違い自体は比べようもありませんが、再取得は別として、変数が100個も使うならともかく、その差は検知できないはずです。 グローバル変数のデメリットは、実は、マクロ稼働中にエラーが発生して、グローバル変数の内容がなくなってしまう、という問題があります。そうすると、以下のようなチェックコードが必要になるということがあります。 If g_Count =0 Then  Call RowCount End If '// Public g_Count As Integer Public Function RowCount()  g_Count = Application.WorksheetFunction.CountA(Range("A1:IV1")) End Function 普通は、こんなことは気にしなくてよいのですが、複雑な内容のマクロですと、必要になることがあります。また、なるべく、変数の名称は、プロシージャ内の変数とは区別がつくようにしてやることがコツです。こういうマクロは、1~2年レベルの経験では使わないと思います。 >ある固定的な値を入れる容器として、 >定数を使った場合でも、 >また、グローバル変数を使った場合でも動く 具体的な状況が思い浮かびません。どちらでも動くから、定数を使うというものでもないように思います。 前回も書いたように、消費税や数式の係数に対して用いるというのが、基本です。

nbsp0606
質問者

お礼

詳細な補足をありがとうございます。 定数とグローバル変数は、同じ土俵で比べられるものではないようですね。 用途が似ているようで似ていない、全くフィールドの異なる概念であるように思いました。 よって、両者のどちらを使うかで迷う、ということはない、ということなのでしょうね。 >具体的な状況が思い浮かびません。 苦し紛れに、具体的な状況を挙げさせて頂くと、 たとえば、 >グローバル変数のメリットとしては、一定の環境で、再取得することなく使えること とありましたが、 定数では、またげないスコープに対し、オールラウンドに、ある特定の値を使い回したい場合、 各スコープで、毎回、定数宣言をするよりかは、 どこか1箇所でグローバル変数宣言をして、その特定の値を使うようにしたほうが、 「その特定の値 に種類が50ほどある場合」なんかには、 コードが短くなり、メリットがあるのかなぁ、なんて思いましたが、いかがでしょう? その場合、 Public Sub Global_Var_Dim()   Public global_var01 as Single = 0.05   Public global_var02 as Single = 1.05   Public global_var03 as Single = 3.14     :     :   Public global_var48 as Single = 1.41421356   Public global_var49 as Single = 2.71828   Public global_var50 as Single = 1.7320568 End Sub こんなプロシージャを、どこか1箇所で実行するようにします。 一方、上記を定数で処理するとなると、 50個の特定の値を、各スコープで毎回、宣言することになりますよね。 これを私は冗長と考えたわけですが、何か見落としなどはありますでしょうか。 ※ まだVBA初心者であるため、文法的に変なことを言っているかもしれません。 考え方の大枠として、こんなことはできないだろうか~?といった話として、 解釈頂けると助かります。 もしまたよろしければ教えて下さい。

その他の回答 (3)

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.4

>定数では、またげないスコープに対し、オールラウンドに、ある特定の値を使い回したい場合、 >上記を定数で処理するとなると、50個の特定の値を、各スコープで毎回、宣言することになりますよね。 定数も変数も、基本的にはスコープは同じです。またげないということはありませんが、そこまでのレベルが必要になるというのは、入門の方からすれば、遥か彼方のテクニックだと思います。 Public global_Var(49) As Single '注:VBAでは、Single 型は慣例的にDouble型にすることが多い '私は、こういう場合は配列に確保します。 Private Sub Global_Var_Dim()   global_var(0) = 0.05   global_var(1) = 1.05   global_var(2) = 3.14   ・   ・   ・   ・   ・ End Sub または、Long型の場合は、列挙型にすることが多いです。 しかし、実際問題として、あまり、公にしていないのですが、プロの作ったものは、この場合、アドイン(.xla)にして、シートにデータを置き、そこから取り出す書かたをする人が多いようです。秘匿性がないので、あまり格好良くないのですが、決め打ちでやってみると、取り出すことが可能です。Excel VBAというものは、そういうものだとするしかありません。それ以外の方法(暗号化)もあるようですが、私自身、それ以上のことはしたことがありません。そこまで必要とされないからです。

nbsp0606
質問者

お礼

さらなる補足をありがとうございます。 >定数も変数も、基本的にはスコープは同じです。 あらら、では、私の挙げた例は適切ではありませんでしたね。苦笑 しかし、おかげさまで、 定数とグローバル変数の使い分けが少し分かったように思います。 ありがとうございます。 >シートにデータを置き、そこから取り出す書かたをする人が多いようです。 そういうテクニックもあるわけですね。 >'注:VBAでは、Single 型は慣例的にDouble型にすることが多い >'私は、こういう場合は配列に確保します。 こちらも、勉強になりました。 メモリのことを気にして、できる限り、Doubleは使わずにSingleで確実に大丈夫な所はSingleで、 なんて私は考えていましたが、業界の慣例ではDoubleにすることが多いのですか~、始めて知りました。 それでは、定数をドッサリ使って、作業を再開したいと思います。 終始、丁寧に回答下さり、ありがとうございました。

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.2

元のコードからすれば、以下のようにするのが自然だと思います。 '// Option Explicit Public g_Count As Integer '←Global 変数の場合は、標準モジュールに置きます。 'モジュールレベルなら、Private m_Count As Integer Sub TestMacro1() '←Global変数を使っている場合は、同じモジュールでなくても可能   g_Count = Application.WorksheetFunction.CountA(Range("A1:IV1"))  MsgBox g_Count End Sub 定数というのは、固定値ですから、変動しないことが条件です。 例えば、消費税として、Const RATE As Double = 0.05 など、定数(Constant)を使います。ワークシートの変動する条件の値を取る場合は、変数(Variable)です。

nbsp0606
質問者

お礼

.CountAなどを用いて計算した値を使い回す際に使用する「データの入れ物」は、 定数ではなくグローバル変数が良さそうですね。 当初、私は、例えば、消費税のような定数で良いようなものまで、 グローバル変数に入れて、固定的なグローバル変数というような扱いで、 まるで定数のように使っていたのですが、 「定数」そのものの存在を、ごく最近知りましたので、 定数にできるものは全て定数にしてしまおうと考え、 今回のような疑問にぶち当たりました。 定数で問題ないものを、仮にグローバル変数に入れて使う場合に考えられるメリット、デメリットがあれば、 教えて頂けると嬉しいです。 (どなたでも結構ですので、心当たりのある方、お願い致します。) 定数の場合、コード中に値が変更されてしまわない、 というメリットがあるように思いますが、それを踏まえた上で、 ここで私が知りたいメリットとは、具体的には、「処理速度」の面のメリットです。 メモリの食い、なども気になります。 ある固定的な値を入れる容器として、 定数を使った場合でも、 また、グローバル変数を使った場合でも動く という場合には、 やはり、グローバル変数ではなく、定数の方を使うべきなのでしょうか。 変なことを質問しているとは思いますが、 もしまた機会がございましたら、教えて下さい。

  • nag0720
  • ベストアンサー率58% (1093/1860)
回答No.1

>やはり、定数値には、固定的な数値(上記例では、Integer)や文字列を入れるべきなのでしょうか。 その通りです。 使えるのは、リテラル値、その他の定数、Isを除く算術演算子や論理演算子を組み合わせた式です。 シート関数の利用はもちろんシート内容も参照することはできませんし、VBAの関数も使うことはできません。 たとえば、 Const a As Single = 5.5 * 3 Sub Test() MsgBox Int(a) End Sub は大丈夫ですが、 Const a As Single = Int(5.5 * 3) Sub Test() MsgBox a End Sub はだめです。

nbsp0606
質問者

お礼

大変わかりやすい回答をありがとうございます。 >使えるのは、リテラル値、その他の定数、Isを除く算術演算子や論理演算子を組み合わせた式 上記に気をつけて、定数宣言をしていこうと思います。 分かりやすい具体例もありがとうございました。

関連するQ&A

専門家に質問してみよう