5.Excelマクロ

 ExcelマクロはVisual Basic(以下VBという。)というプログラミング言語によって記述される。

 VBはExcelとは異なるアプリケーションソフトであり、独自の世界を構成している。作成されたExcel
マクロを実行することは、Excelの操作をVBに委ねることを意味し、本来ユーザがすべき操作をVBに代
行させることを意味する。きめが細かく一般性の高いExcelマクロを作成するためには、自動記録によ
るマクロの作成だけでなく、VBの文法を理解した上で、直接プログラム入力することでマクロを作成す
ることが必要となる。以下ではVBの文法を簡単に説明する。

5.1 変数名

 Excelの場合、データを保存する場所(セル)にはA1やB5などのようにあらかじめ名前が付いている
が、VBの場合は、データを保存する場所(変数という。)に名前が付いておらず、変数名(変数の名
前)は、自分で決めなければならない。変数名作成のルールは、先頭の1文字が英字であることと、
使える文字が英数字(36文字、英字に大文字小文字の区別はない。)であることである。X、XX、X1、
XYZ、A00Bなどが変数名の例である。

 X = 5 は“代入文”と呼ばれるVBの命令であり、「変数名Xという名前の付いた変数(データ保存
場所)にデータ5を保存しなさい。」という意味である。ただし、このとき変数名Xという名前の付い
た変数がないときには、名前の付いていない変数にXという名前を付けて保存する。逆に、変数Xが
存在するときには、それまで保存されていたデータを消去して、指示されたデータを保存する。すな
わち、データを保存する変数を記述すれば自動的に変数が作成される。

5.2 代入文

 代入文の意味は、上で説明したものであるが、一般的には

		変数名=算術式

と記したものである。左辺には一つの変数名しか記述することができない。右辺の算術式とは、デー
タないし数式のことであり、数式はExcelの数式と同様に記述したものである。ただし、Excelの数式
では参照するセルの番地(A1やB5など)を記すことができるが、VBの場合は変数名を記すことになる。
また、関数の名前がExcelとVBでは異なることがあるので注意する必要がある。

		X = Y + 2 * Z - 5

が代入文の例であり、変数YとZは、この命令が実施されるときにYとZに保存されているデータに
置き換えられて右辺の算術式が計算され、計算結果が変数Xに保存される。Yに10、Zに3が保存され
ているときには、11がXに保存される。

		X = X + 1 や X = X + Y

という代入文をしばしば用いるが、その意味は、この命令が実施される直前にXに保存されていたデー
タに1ないし変数Yに保存された値を加え、その結果をXに保存することである。したがって、この命
令が実施されると、Xに保存されたデータが1ないし変数Yの値だけ増えることになる。

5.3 配列

 VBでは、データを保存する場所として変数を用いることを先に説明したが、“配列”と呼ばれるデー
タ記憶場所もよく使われる。配列とは、指定した大きさの表形式の保存場所である。表形式という意味
ではExcelのワークシートと同じであるが、Excelワークシートの大きさは縦65,536、横256に定まって
いるが、VBの配列は自分で大きさを指定するものである。また、Excelワークシートの名前はSheet1や
Sheet2のように最初から付いているが、VBの配列の名前(配列名という。)は自分で決めなければなら
ない。配列名のルールは変数名のルールとまったく同じである。注意すべきことは、配列名と変数名で
同一名を重複して使用してはならないということである。

 配列を使用するときは、使用するより前に配列を用意しておかなければならない。配列を用意させる
命令は

		ReDim A(10), B(5,10)

である。この命令は

  「配列名がAとBの2つの配列を用意せよというものであり、Aは大きさ10の1次元配列(数学で
  のベクトルに相当する。)、Bは縦5横10の2次元配列(数学での行列に相当する。)にせよ。」

というものである。10個のデータ保存場所で構成される配列Aのそれぞれのデータ保存場所の名前は
A(1)、A(2)、....、A(10) であり、これらは変数とまったく同様にして使用する。また、50個のデータ
保存場所で構成される配列Bのそれぞれのデータ保存場所の名前は B(1,1)、B(1,2)、....、B(5,10)
である。厳密にいうと、配列は0番目から存在する。すなわち、A(0)、B(0,0)、B(0,5)、B(5,0)なども
あるので、Aは11個、Bは66個になる。

 配列の便利なところは、

		ReDim A(N) や A(K) = 1

といった記述が許されていることである。最初の命令は「大きさNの1次元配列Aを用意せよ。」とい
うものである。Nは変数であり、この命令の前にNにデータが保存されていなければならないが、Nに
保存されているデータの値分の大きさの配列Aが用意される。後の命令は「配列AのK番目の要素にデ
ータ5を保存せよ。」というものである。このときも変数Kに保存されているデータを参照して、その
値に応じた場所にデータ1を保存する。さらに、ReDim A(N+1) や A(K+1) = 1 のような記述も許され
る。

5.4 繰り返し命令

 繰り返し命令は非常に重要なものであり、繰り返し命令の存在しないプログラムは手作業で行った方
が簡単であると言っても過言ではない。繰り返し作業があるからこそ、プログラムを作成し、使用する
と言えるであろう。いくつかの繰り返し命令が用意されているが、ここでは最も代表的な For〜Next 
命令のみを説明する。For〜Next 命令は

		For  K = 1  To  10
		    ◇◇◇◇◇
		Next  K

と記述するものであり、赤字の部分は決まり文句である。For と Next の直後に記される変数名(この
例ではK)は同じものでなければならない。この命令は、「変数Kを1から10まで変化させ、Next文まで
の間に記された命令を繰り返しなさい。」というものである。すなわち、最初に配列Kに1を保存し、
Next 文までの命令を実施し、For 文に戻る。次にKに2を保存し、Next 文までの命令を実施し、For
文に戻る。以下同様にして、最後にKに10を保存して Next 文までの命令を実施し、すべての繰り返し
が終わったので、Next 文の次の命令に進む。この例の場合は For 文と Next 文の間に記された命令が
10回繰り返されることになる。

 また、次のような記述も許されている。

		@ For K = 5 To 10
		A For K = 1 To N
		B For K = 0 To 10 Step 2
		C For K = 1.5 To 2 Step 0.1
		D For K = 5 To 1 Step -1

@は5から10で6回繰り返すことになる。Aは変数Nに保存されている値分だけ繰り返すことになる。
B、C、Dには Step が追加されているが、Step は増分を意味し、BはKを0、2、4、6、8、10と変え
て繰り返すことを意味し、6回繰り返すことになる。CはKを1.5、1.6、1.7、1.8、1.9、2と変えて6
回繰り返す。DはKを 5、4、3、2、1 と変えて5回繰り返す。@Aの場合は Step 1 が省略されてお
り、Step が省略されている場合は Step 1 を意味すると決められている。

 For〜Next 命令の例として、1から100までの総和を求める問題を考えてみよう。総和を保存する変数
をSとし、Sに1を足し込み、Sに2を足し込み、...、Sに100を足し込めばよい。それらの命令は、
S=S+1、S=S+2、...、S=S+100 であり、さらに、K=1、S=S+K、K=2、S=S+K、...、K=100、S=S+K となる
ので、For〜Next 命令が使えることになる。プログラムは次のようになる。

		S = 0
		For K = 1 To 100
		  S = S + K
		Next K

 先頭行(S = 0)は、変数Sに何かデータが保存されていた場合を避けるためのものである。しかし、
変数Sが初めて使用されるときは、0が保存されているので、なくてもかまわない。長いプログラムの
場合は、すでに使用しており0以外のデータが保存されている場合もあるので、先頭行を付けることを
習慣化しておくことが望ましい。この構文は応用の広いものであるので覚えてほしい。

 For〜Next命令を二重三重に重ねて使用する場合もある。

		For K1 = 1 To N
		   For K2 = 1 To M
		      ◇◇◇◇◇
		   Next K2
		Next K1

赤字の部分を一つの命令とみなせばよいので、それほど難しくないと思われる。この場合、各K1に対し
てK2がM回繰り返されるので、全体で◇◇◇◇◇がN×M回繰り返されることになる。

 For〜Next 命令で注意すべきことは、For 文に記述された変数(上の例ではK1、K2、N、M)を、For
文と Next 文の間では代入文等で変更してはならないことである。

5.5 場合分け

 状況に応じて実施すべき命令を変えるときに使うのが場合分け命令である。場合分け命令は

		IF X > 0 THEN
		  ○○○○○
		ELSE
		  △△△△△
		ENDIF

と記述するものである。この命令の意味は「変数Xに保存されているデータが正であるときは命令群
○○○○○を実施し、そうでないときは命令群△△△△△を実施せよ。」というものである。

		IF A = 0 THEN
		  ○○○○○
		ENDIF

のように ELSE 部分を省略することができる。この場合は、変数Aに保存されたデータが0のときのみ
○○○○○を実施し、そうでないときは何もしないことになる。なお、THEN の部分を省略することは
できない。

 条件文である X > 0 または A = 0 の部分には、=、<>(≠のことで、>< でもよい。)、>、<、>=
(≧のことで 、=> でもよい。)、<=(≦のことで 、=< でもよい。)を用いた数式を記述する。
X+1 >= Y*Z のように両辺共に数式としてもよいし、移項して 1 >= Y * Z - X のようにしてもよい。
すなわち、条件文として、数学で使う等式や不等式を使うことができる。しかし、あまり複雑な条件文
は分かりにくくなるので避けた方がよいであろう。上の例でも、事前に R = Y * Z - X のようにして
変数Rに保存しおけば、条件文は 1 >= R ないし R <= 1 でよいことになる。

5.6 ジャンプ命令

 VBは、基本的に書かれている順番に上から下へ命令を処理するが、いくつかの命令を飛び越したり、
戻ったりすることもでき、そのときに使う命令がジャンプ命令である。ジャンプ命令は

		GoTo ラベル

と記述するもので、その意味は「ラベルのところにジャンプせよ。」というものである。しかし、この
命令を使うためには、ジャンプ先であるラベルがプログラム中になければならない。

 ラベルには、文字 (英字、漢字、ひらがな、カタカナ) で始まり、コロン (:) で終わる任意の文字
の組み合わせを使うことができるが、同一プログラム内で重複するラベルを使うことはできません。
大文字小文字は区別されません。また、ラベルは、行頭から記述しなければなりません。

		abc:

というラベルがあるとき、そこへジャンプする命令は次のようになる。

		GoTo abc

ジャンプ命令は、場合分け命令と組み合わせて使用されることが多い。

5.7 Excelとのやりとり

@ ExcelのアクティブセルのデータをVBの変数Nに読み込むVBの命令は次式である。

		N = ActiveCell

A VBの変数Sに保存されているデータをExcelのアクティブセルに出力するVBの命令は次式である。 

		ActiveCell = S

B Excelのアクティブセルを移動させるVBの命令の例は

		ActiveCell.Offset(2, 1).Range("A1").Select

 であり、「現在アクティブなセルから下に2つ右に1つ行ったところのセルをアクティブにせよ。」
 という意味である。

		ActiveCell.Offset(-1, 0).Range("A1").Select

 は、「現在アクティブなセルのすぐ上のセルをアクティブにせよ。」という意味である。

		ActiveCell.Offset(-N, 1).Range("A1").Select

 は、「現在アクティブなセルからN(変数であり、そこに保存されている値になる。)個上の右隣の
 セルをアクティブにせよ。」という意味である。