ExcelVBA(マクロ)で変数を作る・宣言する方法/Dim、Static、Public、Option Explicitステートメントの使い方

military IT

VBAもプログラムですので、Excelに入力した値以外に「変数」を持つことができます。一時的に代入しておける値です。

Advertisements

変数の宣言(Dim)

変数の宣言方法は、変数名の前にDimを付けて記述します。

変数の宣言
Dim 変数名
d1
変数はアルファベット、日本語などで好きに名前が付けられます。
たとえばDimを使って「変数」という名前の変数を作成してみます。
d2
変数にはデータを格納することができます。
A1の数字を「変数」に代入し(この時点で「変数」 = 150)、「変数」を二倍した数値をB1に入力、というコードを作成します。
d3
A1になにか数字を入れてマクロを実行すると、
d4
「変数」を仲介して、数字が二倍されてB1に入力されました。
d5
数字、「_」も使えます(このコードは動きます)。ただし、変数名の頭に数字を付けるとエラーになります。
その他「!」「.」「@」「$」「&」「#」などの記号、関数名やメソッド名や定数と同じ名称、プロシージャ内で有効な変数名と同一の(カブる)名称、長さが256文字以上の名称は使えません。
大文字と小文字もデータ上区別されません。

データ型の指定

d6
変数の指定後に「As データ型」を付けることで、変数の種類を指定することができます。
特に指定しないとVariant型というなんでも格納できるデータ型になります。
データが軽くなるので、利用用途がわかっている変数はデータ型を指定するほうが本来望ましいですが、現代のPCでそれほどデータ型の重さを気にする必要はありません。むしろ可読性、ミスを防ぐ意味、または「分かってる感」を出すためにデータ型を指定するほうがウェイトが高いです。
ここではAs Rangeとすることで、変数にRangeオブジェクトを格納する、と指定しています。
d7
Rangeオブジェクトというのは大雑把に言えばセル、範囲のことです。これにRange(“A1”).Valueを代入するというのは、イメージとしてセルに=A1と書いたような状態です。
なので、これは問題なく動きます。

例:Byte型

d8
他のデータ型も見てみましょう。Byte型は0~255までの正の整数を格納することができる、非常にメモリ領域を使わない軽いデータ型です。
d9
255まではOKなので、100を200にしてアウトプットする処理は行えますが、
d10
もうちょっと大きな数字になると、
d11
音を上げます。オーバーフローというのは風呂から水があふれたような意味、想定された容量からデータがはみ出した状態で、この場合エラーになります。Variantを除くデータ型はそれぞれこのように用途に制限があります。

例:Date型

d41
Date型ではデータは日付として保管されます。
日付として認識されれば、”西暦/月/日”だろうが、
d44
和暦だろうがかまいませんが、””で囲む必要があります。
d43
または西暦表示を日付リテラルと呼ばれる##で囲む形でも指定できます。日付リテラルで囲まれた日付は、表示が自動で月/日/年の形に修正されます。
d42
どの形でも実行結果はこうなります。
date型の変数には時間を記録することも可能です。

String(2GBまでの文字列)、Integer(-32768~32767の整数)またはLong(-2147483648~2147483647の整数)、Object(オブジェクト全般)およびRangeなどのオブジェクト変数がよく使われます。

ExcelVBA(マクロ)のデータ型まとめ/オブジェクト型変数に対するSetメソッドの使い方
VBAで変数に対して使用できるデータ型の種類、使い方、注意点のまとめです。

複数の変数を同時に宣言

d12
Dim 変数1, 変数2のように,で区切って記述することで、複数の変数を同時に宣言することが可能です。
,で区切っていけば3つ以上も可能です。
d13
データ型を指定する場合、最後にAs データ型を付けると最後の変数(この場合「変数2」)にだけ適用されます。
この場合、変数1はVariant型になります。
d14
ふたつともデータ型を指定したければ、両方にAs データ型を付ける必要があります。

VBAに変数の宣言は必要ない?

「そもそもなぜVBAで変数を宣言する必要があるのか」という話をします。というのも、変数を宣言しないでいきなり使っても動くからです。

dim1
この画像では「motonokazu」という変数に100、tsuikaという変数に50を代入し、このふたつを足したものをA1セルに出力しています。問題なく150が出力されています。
dim2
ではこういった場合はどうでしょうか。

一見全く同じコードのように見えますが、出力される結果が違います。よく見ると、100を代入されているのは「motonokadu」、計算に使用されているのは「motonokazu」で、ちがう変数を使用していました。なので、新しい変数が作成されて、motonokazu(値は0)+tsuika(値は50)=50が出力される結果になっています。
この処理にはエラーが出ません。単純なケアレスミスですが、長いコードになるほど原因を発見するのが難しくなり、そもそもミスの存在そのものに長期間気付かない危険性が高まります。これを避けるために、当サイトでは(というか一般的に)変数名を宣言することを推奨しています。

Option Explicitの使い方

変数名の宣言を義務化
Option Explicit
dim4
Option Explicitはプロシージャの先頭に記述します。Option Explicitを付けた状態では、宣言していない変数を使うとエラーになります。
dim3
従って、このようにスペルミスした場合はエラーが表示され、問題を未然に防ぐことができます。
dim5
正しい変数名を指定すれば、ちゃんと式が動くことが確認できました。

自動的にOption Explicitを付ける

oe1
設定を変更することで、新しく作成したプロシージャに自動的にOption Explicitを付けることが可能です。
まずVBEを開いた状態でツールオプションをクリックし、
oe2
編集タブ「変数の宣言を強制する」にチェックを付けてOKを押します。
oe3
この状態でマクロを作成すると、自動的にOption Explicitが付いた状態で編集を始めることができます。

変数の適用範囲

プロシージャレベル変数

d15
プロシージャ内で変数を宣言し、これに100を代入して、メッセージボックスを表示してみます。
d16
特に問題なく期待通りの結果が出ました。
d20
今度はOption Explicitを付けて、macro2を作り、その中でmacro1内で宣言した変数を使ってみます。
d21
すると「変数が宣言されていない」とエラーが出ます。
プロシージャ内で宣言した変数は、通常そのプロシージャの中ででしか使えません。macro2で同じ変数を使おうと思ったら再度プロシージャ内で宣言する必要があり、このふたつは名前は同じですが全く別の変数として扱われます。
こうしたプロシージャ内で完結する変数をプロシージャレベル変数と呼びます。
プロシージャレベル変数に代入した値は、プロシージャ終了後破棄されます。

モジュールレベル変数

d22
今度はプロシージャが始まる前に変数を宣言します。
d23
まずmacro1を実行すると、同様の結果が出ます。
d24
macro2も実行してみます。こちらも同様の結果になりました。
プロシージャの「前」に宣言する場合、これはモジュールレベル変数と呼ばれます。また変数を書いた場所(モジュールの頭~プロシージャの頭の間)を宣言セクションと呼びます。
モジュールレベル変数は、モジュール内のどのプロシージャでも使用可能で、プロシージャ終了後も代入した値が保持され続けます。
d26
モジュールというのはひとつ~複数のプロシージャを含む固まりのことです。要するに窓ひとつ=モジュールです。モジュールレベル変数を別のモジュールで使用しようとすると、
d27
それはそれでエラーになります。

プロシージャレベル変数の値を処理終了後も保持(Static)

d28
先述のとおり、プロシージャレベル変数の値は処理終了後に破棄されます。
たとえばこの式では変数に変数+100をして出力しているので、値が保持されていれば200,300..と値が増えていくはずですが、
各回値が初期化されるので、何度やっても同じ値になります。
d30
そこで、変数の宣言時にDimではなく、Staticステートメントで宣言してみます。
Static=静的という意味で、この形で宣言した変数は、プロシージャレベルであっても処理終了後も値が保持されます。
静的な変数名の宣言
Static 変数名
d31
結果として、処理が実行されるたびに値が増えていきます。

変数を他のモジュールでも使用(Public)

d32
似たような感じで、他のモジュールでも参照できるモジュールレベル変数を作ることができます。
最初にPublicを付けて、宣言セクション(プロシージャの前)で宣言します。
すべてのモジュールで共有する変数名の宣言
Public 変数名
d33
macro1で作成したPublicの変数を、macro2で使用してみます。
d34
macro2だけ実行すればこうなりますし、
d35
macro1→macro2と実行すればこうなります。値も引き継がれます。
d36
Publicは必ず宣言セクションで宣言してください。
d37
プロシージャ内でPublicで宣言すると、実行時エラーになりますし、他のモジュールから参照もできなくなります。

モジュールレベル変数専用の宣言(Private)

d38
宣言セクションでPrivateステートメントで変数を宣言すると、Dim同様にモジュールレベルの変数を作成できます。
特にDimで宣言した時と変数の性質は変わりません。
モジュールレベル変数の宣言
Private 変数名
d39
DimやStatic同様、他のモジュールからは参照できません。
d40
Dimとちがい、Privateではプロシージャレベルの変数は作れません。
絶対にモジュールレベルの変数を作りたい、という区別に使うのであればアリだと思います。

定数の宣言(Const)

定数の宣言
Const 定数名 = 値
const4
Const 定数 = 値のように記述することで、ユーザー定義型の定数を宣言することができます。
定数は変数と同じように使うことができますが、値を宣言時以外変更できません。
const6
逆に言えばそれ以外は大体同じです。値を途中で代入したく(されたく)ない数値、変更する必要のない文字列などに使用します。

定数については別記事で詳しく解説していますので、興味のある方はご参照ください。

ExcelVBA(マクロ)でユーザー定義型の定数を宣言する方法/Constステートメントの使い方
「定数」とは変更できない数、値を代入した入れ物で、中身を変更できるものは変数と呼ばれます。たとえば極端に大きくてかつ固定の数字、あとでまとめて変更するかもしれないけど基本固定したい数値(消費税率)などに使用します。 ユーザーが定義できる定...

配列変数の宣言

array1
変数名(最大値)と宣言することで、配列変数を作成することができます。
array2
配列変数は変数(番号)という名称の別々に使える変数の集合体です。初期値が0で最大値までの数が作れます(つまり最大値が3の場合、1,2,3,4で4つ作れる)。
array4
あとは普通の変数と似たような感じです。
別に変数1、変数2……のように作ってもいいんですが、似たような変数が300個ぐらいある場合などは配列変数にしたほうが無難です。

配列変数について詳しくはこちら。

ExcelVBA(マクロ)で配列変数を作る方法/ReDim、Preserve、Option Baseステートメント、Array、UBound、LBound関数の使い方
他のプログラミング言語同様、VBAにも配列を作る機能が用意されています。ここでは配列作成の基本および補足機能について解説しています。

VBAにおける変数の宣言、宣言の義務化、データ型の指定などについては以上です。

やりたいことから方法を探すエクセルExcel操作・関数・VBA(マクロ)逆引きまとめ
逆引き(やりたいことから探す)Excel記事まとめ
関数・演算子・メソッド・プロパティ名から探すExcel/VBA(マクロ)使い方・組み合わせ方まとめ
こちらはExcelやメソッドの諸機能を、機能の名称から探せるまとめ記事です。

コメント