
VBAの定数の使い方で、計算値を定数に入れることは可能ですか。
例えば、モジュール先頭に、
Option Explicit
Const TEISU_COUNT As Integer = Application.WorksheetFunction.CountA(Range("A1:IV1"))
と書き、その下に、
Sub TestTeisu()
MsgBox TEISU_COUNT
'↑定数式が必要です、のようなエラーが出ます。なぜでしょう?
'エラー時、「.CountA」にスポットがあたります。
'つまり、ここがダメということでしょうか?やはり、この点が動的だからでしょうか?
End Sub
と書いて、実行。
結果は、上述の通り、エラーとなります。
やはり、定数値には、固定的な数値(上記例では、Integer)や文字列を入れるべきなのでしょうか。
定数に入れることのできる値の注意事項について、
どなたかアドバイスして頂けますでしょうか。
宜しくお願い致します。
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年レベルの経験では使わないと思います。
>ある固定的な値を入れる容器として、
>定数を使った場合でも、
>また、グローバル変数を使った場合でも動く
具体的な状況が思い浮かびません。どちらでも動くから、定数を使うというものでもないように思います。
前回も書いたように、消費税や数式の係数に対して用いるというのが、基本です。
詳細な補足をありがとうございます。
定数とグローバル変数は、同じ土俵で比べられるものではないようですね。
用途が似ているようで似ていない、全くフィールドの異なる概念であるように思いました。
よって、両者のどちらを使うかで迷う、ということはない、ということなのでしょうね。
>具体的な状況が思い浮かびません。
苦し紛れに、具体的な状況を挙げさせて頂くと、
たとえば、
>グローバル変数のメリットとしては、一定の環境で、再取得することなく使えること
とありましたが、
定数では、またげないスコープに対し、オールラウンドに、ある特定の値を使い回したい場合、
各スコープで、毎回、定数宣言をするよりかは、
どこか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初心者であるため、文法的に変なことを言っているかもしれません。
考え方の大枠として、こんなことはできないだろうか~?といった話として、
解釈頂けると助かります。
もしまたよろしければ教えて下さい。
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というものは、そういうものだとするしかありません。それ以外の方法(暗号化)もあるようですが、私自身、それ以上のことはしたことがありません。そこまで必要とされないからです。
さらなる補足をありがとうございます。
>定数も変数も、基本的にはスコープは同じです。
あらら、では、私の挙げた例は適切ではありませんでしたね。苦笑
しかし、おかげさまで、
定数とグローバル変数の使い分けが少し分かったように思います。
ありがとうございます。
>シートにデータを置き、そこから取り出す書かたをする人が多いようです。
そういうテクニックもあるわけですね。
>'注:VBAでは、Single 型は慣例的にDouble型にすることが多い
>'私は、こういう場合は配列に確保します。
こちらも、勉強になりました。
メモリのことを気にして、できる限り、Doubleは使わずにSingleで確実に大丈夫な所はSingleで、
なんて私は考えていましたが、業界の慣例ではDoubleにすることが多いのですか~、始めて知りました。
それでは、定数をドッサリ使って、作業を再開したいと思います。
終始、丁寧に回答下さり、ありがとうございました。
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)です。
.CountAなどを用いて計算した値を使い回す際に使用する「データの入れ物」は、
定数ではなくグローバル変数が良さそうですね。
当初、私は、例えば、消費税のような定数で良いようなものまで、
グローバル変数に入れて、固定的なグローバル変数というような扱いで、
まるで定数のように使っていたのですが、
「定数」そのものの存在を、ごく最近知りましたので、
定数にできるものは全て定数にしてしまおうと考え、
今回のような疑問にぶち当たりました。
定数で問題ないものを、仮にグローバル変数に入れて使う場合に考えられるメリット、デメリットがあれば、
教えて頂けると嬉しいです。
(どなたでも結構ですので、心当たりのある方、お願い致します。)
定数の場合、コード中に値が変更されてしまわない、
というメリットがあるように思いますが、それを踏まえた上で、
ここで私が知りたいメリットとは、具体的には、「処理速度」の面のメリットです。
メモリの食い、なども気になります。
ある固定的な値を入れる容器として、
定数を使った場合でも、
また、グローバル変数を使った場合でも動く
という場合には、
やはり、グローバル変数ではなく、定数の方を使うべきなのでしょうか。
変なことを質問しているとは思いますが、
もしまた機会がございましたら、教えて下さい。
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
はだめです。
大変わかりやすい回答をありがとうございます。
>使えるのは、リテラル値、その他の定数、Isを除く算術演算子や論理演算子を組み合わせた式
上記に気をつけて、定数宣言をしていこうと思います。
分かりやすい具体例もありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) 3つのプロシージャをまとめたら実行時エラー発生で対応不能 6 2022/05/17 01:47
- Excel(エクセル) バイナリー演算を勉強したい 1 2023/04/19 14:17
- Visual Basic(VBA) マクロについて教えてください。 4 2023/06/06 09:06
- Visual Basic(VBA) VBA 改行コードの取り方 1 2022/03/22 14:14
- Excel(エクセル) VBAで組み合わせ算出やCOUNTIFSの処理を高速化したいです。 4 2022/04/07 02:38
- Visual Basic(VBA) VBAでのMATCH関数 3 2022/10/17 19:06
- Visual Basic(VBA) Excel のユーザー定義関数でソルバーが動作しない 1 2022/09/05 19:51
- Visual Basic(VBA) vba 等間隔の列に対しての計算 6 2022/05/17 20:15
- Visual Basic(VBA) ACCESS DAO で不要なテーブルのフィールド(列)の削除 4 2022/06/23 12:13
- Visual Basic(VBA) 前回ご教授いただいたコードに覚えたてのループ処理で品名りんごAから順に20回for nextでループ 7 2023/01/13 22:01
このQ&Aを見た人はこんなQ&Aも見ています
-
[VBS]変数を定数に変換する方法を教えて下さい。
Visual Basic(VBA)
-
VBAでセル入力の数式に変数を用いたい
Excel(エクセル)
-
VBAでエクセルシートを更新(リフレッシュ)する方法を教えて下さい。
Excel(エクセル)
-
-
4
エクセル: セルの枠を超えて表示
Excel(エクセル)
-
5
大量の変数を定義するにはどうしたら良いですか?
Visual Basic(VBA)
-
6
VBAでブックを非表示で開いて処理して閉じる方法
Excel(エクセル)
-
7
エクセルVBA 配列からセルに「関数式」を一気代入したい
Visual Basic(VBA)
-
8
VBA Constの指定シートのセルを指定する方法
Visual Basic(VBA)
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語 exitの使い方
-
Excel-vba 文字列と変数を...
-
フォームを開くときに、コンボ...
-
数字の位ごとの値を表示するプ...
-
フリーランタイマーの時間差分...
-
ラジオボタンの値の取得につい...
-
VBAで配列のNULL判定
-
DataGridView 複数行同時変更...
-
3bitアップダウンカウンタ(Up/...
-
Exit Subのような・・・。
-
【C++/CLI】String型文字列の位...
-
VBAでプロセデュア間で共有でき...
-
クッキーCookieで、値のサイズ...
-
配列の値を置換するにはどうす...
-
VBAでダブルコーテーション入り...
-
エラーの意味は? Lvalue req...
-
Windows11のカメラで動画を撮り...
-
jsp~jspにhiddenを使って変数...
-
SQL文 日付
-
プログラミングの問題です
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語 exitの使い方
-
Excel-vba 文字列と変数を...
-
フォームを開くときに、コンボ...
-
数字の位ごとの値を表示するプ...
-
VB6.0-整数と余りを求める
-
足して100になるような乱数のア...
-
ラジオボタンの値の取得につい...
-
C#で動的にコントロールを取得...
-
VBAで配列のNULL判定
-
データ構造のmapとは?
-
関数で複数の値を戻り値として...
-
世界のナベアツ
-
VBA コンボボックスの値をスピ...
-
VBAの定数の使い方で、計算値を...
-
スピンボタンで小数点
-
1つ前の値を変数に保存する方法
-
Nullってどういう意味ですか?
-
コンボボックスの名前を変数に...
-
DWORDって
-
vbaで極大値を抽出する方法
おすすめ情報