第2回 マクロによる基本的な処理の記述

概要

 マクロにおいて複数の処理を記述する際の基本的な考え方と記法を学びます.まずセル上のデータに対する単純な計算を行うマクロの作成を通して,処理の対象となるデータを扱う際の基本的な考え方と記法を学習します.つぎに,あらかじめ用意された複数の処理を条件に応じて選択的に実行する「条件分岐」の考え方と記法を学習します.

セクション

1. 変数の考え方とセルの値の計算
2. 条件分岐の考え方
3. 条件分岐の応用

1. 変数の考え方とセルの値の計算

 セルに入力された値を使って計算をする方法を学習します(practice02.xls, Sheet1).

1.1 計算手順の構想

 セルに入力された値に対して何らかの計算を施し,その結果を再びセルに戻すマクロを作成しましょう.計算を自動化するマクロを作成できれば,Excelを活用する様々な場面で役立ちます.

 最も簡単な例として「税込み価格計算」をおこなうマクロを考えてみます.以下の図のように,A2に税抜き価格を入力したうえでマクロを実行すると,B2に消費税5%を加算した税込み価格を出力するようにします.

税込み価格計算1  税込み価格計算2

 マクロを作成する際には,まず始めに計算の手順を大まかに構想します.たとえば今回の「税込み価格計算」を行うマクロの場合,以下のような手順が考えられます.

  1. 「税抜き価格」の値を取得する
  2. 取得した「税抜き価格」を元に,「税込み価格」を算出する
  3. 算出した「税込み価格」を出力する

 マクロの作成は,いきなりVBA言語を記述するのではなく,まずは処理の手順について構想を立てるところから始まります.事前に手順を構想するのは,ある程度マクロに関する知識や理解がないとやりづらい面もあります(たとえば「値を取得する」などの耳慣れない表現もありますが,詳細は後ほど説明します).しかし最初にきちんと構想を立てることによって,後でより間違いの少ないマクロが書けるばかりでなく,結果としてマクロの理解を速めることにもつながります.したがって,分かる範囲で構わないので,必ず最初に自分の頭で構想する,ということを習慣づけましょう.

1.2 ソースコードの記述

 構想に従って実際に書かれたマクロの記述のことを「ソースコード」と呼びます.先程のマクロのソースコードを見ながら,計算を行うマクロの書き方の基本を学習しましょう.

 以下はこのマクロのソースコードです(説明を容易にするため左端に行数を入れてあります).


1: Sub 税込み価格計算()
2:	Dim 税抜き価格 As Long
3:	Dim 税込み価格 As Double
4:
5:	' 「税抜き価格」の値を取得する
6:	税抜き価格 = Range("A2").Value
7:
8:	' 取得した「税抜き価格」を元に,「税込み価格」を算出する
9:	税込み価格 = 税抜き価格 * 1.05
10:
11:	' 算出した「税込み価格」を出力する
12:	Range("B2").Value = 税込み価格
13:
14: End Sub
		

1.2.1 マクロ名

 1行目ではマクロ名を宣言しています.マクロ名はマクロ全体のタイトルに当たります.VBAでは日本語も利用できますので,マクロ全体の目的を適切に反映する分かりやすい名称をつけましょう(たとえば「テスト1」や「example02」などの名称では,後で見たときに何のために作成したものか分からなくなります).

1.2.2 変数の宣言

 2,3行目は「変数を宣言する」記述です.

 変数とは,数字や文字などの値を記憶するためのメモの役割を果たします.1つの変数には1つの値を書き込んでおくことが出来ます.通常,変数に書き込んだ値は何らかの計算や処理のために利用します.

 変数を利用する際には,事前に変数の利用を「宣言」する必要があります.変数の宣言とは,その変数の変数名(変数ごとに付けられる名称,マクロ作成者が自由につけられる)と,その変数に記憶する値のデータ型(整数,小数,文字など,値の形式の区別を表す記号,プログラミング言語ごとに決まっている)を登録する処理です.変数の宣言は以下の書式で行います.


Dim 変数名 As データ型
		

 2,3行目は以下のように記述されています


2:	Dim 税抜き価格 As Long
3:	Dim 税込み価格 As Double
		

 2行目では「税抜き価格」という変数名を持った,1つの変数の利用が宣言されています.変数名には記号類を除いた文字を用いることが可能です.従ってマクロ名と同様に日本語を用いることも出来ます(ただし先頭の文字に数字を使うことは出来ません).

 変数「税抜き価格」のデータ型はLongです.LongはVBAでは「整数」を扱うデータ型を表す記号です.ですから,以後,この「税抜き価格」という変数は整数の値を記憶するためだけに使われます.

 同様に,3行目ではDouble型のデータを記憶する「税込み価格」という変数の利用が宣言されています.Double型は「小数」を扱うデータ型の記号です.

参考!:VBAで利用可能なデータ型

VBAでは以下のデータ型を利用することが出来ます(一部抜粋).

データ型の種類 記号 詳細
整数型 Integer -32,786~32,786の範囲の整数
長整数型 Long Integerでは扱えない大きな桁数を持つ整数
単精度浮動小数点数型 Single 小数点を含む数値
倍精度浮動小数点数型 Double Singleでは扱えない大きな桁数を持つ小数
文字列型 String 英文字や仮名漢字等で構成される文字データ
ブール型 Boolean 条件式の判断結果など.値はTrue/Falseの2種類
オブジェクト型 Object オブジェクトを参照するためのアドレス

1.2.3 値の取得

 6行目はセルA2に入っている値を取得し,それを変数「税抜き価格」に書き込む処理です.

 値の取得とは,セルに入力されている値を取り出して入手する処理です.これはマクロの側からセルへ値を出力する(第1回3.1.3を参照)のとちょうど正反対の処理に当たります.今回のマクロでは,セル(A2)にユーザーが入力した税抜き価格を取得します.税込み価格を算出するためには,計算を行う前に,計算の対象となる税抜き価格を知る必要があるからです.

 セルの値を取得するためには,セルを表すRangeオブジェクトのValueプロパティにアクセスします.例えば以下の1行目はA2のセルに入っている値を取得する記述,2行目は現在選択されているセルの値を取得する記述です.


Range("A2").Value
ActiveCell.Value
		

 ただしこれだけでは取得した値がどこに行ってしまうのかが不明です.そこで,実際にセルの値を取得する際には,「代入文」を使って,取得した値を変数に書き込むように記述します.

 代入文の書式は以下の通りです.=(イコール)で挟んだ右辺で取得した値(以下の例では選択されたセルの値)を,左辺にある変数Aに書き込みます.


変数A = ActiveCell.Value
		

 以下はマクロの6行目の記述です.代入文を使って,A2のセルから取得した値を変数「税抜き価格」に書き込む処理を実行します.仮にA2に300という値が入っている場合,この行を実行すると変数「税抜き価格」に300という値が書き込まれます.

 代入文は,右辺と左辺がイコールであることを表しているのではなく,「右辺から左辺へ値を書き込む」という方向を持った処理であるという点に留意してください.


6:	税抜き価格 = Range("A2").Value
		

1.2.4 計算式

 9行目では税込み価格の計算を行っています.


9:	税込み価格 = 税抜き価格 * 1.05
		

 変数「税抜き価格」に書き込まれた値に対して1.05をかけることで税込み価格を算出し,その値を代入文を使って変数「税込み価格」に代入しています.代入文では右辺が先に実行され,その後で値が左辺に代入されます.ですから,この式では先に「税抜き価格 * 1.05」が実行されることになります.

 変数に書き込まれた値を利用するためには,利用したい箇所で,その変数の変数名を記述します.上記の例では,変数「税抜き価格」に300という値が入っている場合,代入文の右辺は「300*1.05」となります.結果として,計算結果である315が左辺の「税込み価格」に代入されることになります.

 ちなみに変数「税込み価格」は小数を扱うDouble型の変数です.Double型として宣言した理由は,上記の計算結果が必ずしも整数とはならないからです(ワークシートの側で,セルB2の表示形式を「通貨,小数点以下の桁数0」にしておけば,計算結果が小数の場合でも四捨五入されて整数として表示されます).

 四則演算を行う場合,通常の計算式と同様,項同士を演算記号(VBAでは演算子と呼ぶ)で挟みます.計算結果はそのままにしておくと消えてしまうので,代入文を使って変数に書き込みます.

参考!:VBAの演算子

 四則演算を行う演算子は以下の通りです.

演算子 意味
+ 足し算
- 引き算
* かけ算
/ 割り算
Mod 割り算の余り

1.2.5 値の出力

 12行目は算出した税込み価格をセルB2に出力する処理です.

 特定のセルに文字列を出力する記述は第1回の3.1.3で学習しました.12行目の記述も全く同じことをしています.


12:	Range("B2").Value = 税込み価格
		

 代入文の右辺には実際の値ではなく変数名が記述されています.変数「税込み価格」にその時入っている値が,セルB2に出力されます.

 セルへ値を出力する処理は,セルから値を取得する処理とちょうど正反対の記述をします.以下の1行目は変数Aに書かれた値を選択されたセルに対して出力します.反対に2行目は,選択されたセルに入っている値を変数Aに代入します.どちらも対象となるセルを表すRangeオブジェクトのValueプロパティへアクセスするという点が共通していますが,代入文のどちら側に置くかによって,値の取得か出力かの意味が決まります


ActiveCell.Value = 変数A
変数A = ActiveCell.Value
		

1.2.6 ブロックとブロックコメント

 マクロ内部の,変数の宣言以降の記述は,3つの「ブロック」から成り立っています(5〜6行目,8〜9行目,11〜12行目).各ブロックの冒頭には,構想の段階で記述した3つの計算の手順がそのまま「ブロックコメント」として挿入されています.

 ブロックは,マクロを構成する記述のかたまりのことです.マクロを作成する際には,構想の段階で課題の解決に至るプロセスをいくつかの手順に分割して記述します.ソースコードはそれぞれの手順を達成するための処理として位置付けられます.結果としてマクロの内部には,課題の解決に至る手順ごとのソースコードの記述のかたまり,すなわちブロックが構成されます.

 ブロックは1行ないし複数行のソースコードによって構成されます.今回の例ではそれぞれのブロックごとに1行だけソースコードが書かれていますが(6,9,12行目),いつもそうであるとは限りません.

 ブロックコメントは,各ブロックの目的を記述したものです.ブロックコメントは,マクロに与えられた課題を「目的」として捉えるならば,ブロックコメントはマクロ全体の目的を達成するための,より具体的な下位レベルの目的を表します.ソースコードは各ブロックの目的を達成するための手段であるといえます.

全体の目的と下位レベルの目的

 本講座では,マクロを作成する際に手順の分割を適切におこなうこと,かつ分割された各手順の目的をブロックコメントによって簡潔に表現することを理想とします.そのためには,きちんと構想を行った上でソースコードを記述しなければなりません.ブロックの分割を示す空行(4,7,10,13行目)やブロックコメントは,実際のマクロの動作には関与しないため,省略してもマクロの機能に問題は生じません.しかし本講座では,マクロの作成に対する理解を深めるため,ブロックの分割とブロックコメントの付加を推奨します.

1.3 練習問題

 元金(日本円)を米ドルに換算するマクロを作成しましょう(practice02.xls, Sheet2).マクロの仕様は,以下の図のように,あらかじめ1ドル価格と換算前の元金を所定のセルに入力しておき,マクロを実行すると米ドル換算額が表示されるものとします.

 作成する際には,ソースコードを書く前に必ず計算手順の構想を記述し,かつブロックコメントをきちんと挿入してください.

米ドル換算,シート画面

2. 条件分岐の考え方

 条件に応じて異なる仕事を実行する「条件分岐」の考え方と書き方を学習します.

2.1 条件分岐とは何か

 条件分岐とは,あらかじめ決められた条件を満たすか満たさないかに応じて,処理を選択的に実行させるしくみです.

 テストの得点に応じて成績判定を行うマクロの例で考えてみましょう(practice02.xls, Sheet3).仮に以下のようなテストの得点表があったとします.以下の得点表の中で,成績優秀者だけをひと目でわかるようにするマクロを考えてみましょう.

テスト得点表

 仮に成績優秀者の基準を80点以上とします.氏名の入力されたセルを選択しマクロを実行すると,その学生のテスト得点が80点以上である場合のみ,学生の氏名と得点の入力されたセルの背景色を水色に変更するマクロを作成します(以下の図参照).

テスト得点表・セル選択状態 氏名を選択した状態でマクロを実行すると...  テスト得点表・マクロ実行後

2.1.1 処理の手順の構想

 上記のマクロの処理の手順を考えてみましょう.

 処理の内容は,大まかに表現すれば「選択された学生が成績優秀者(得点が80点以上)ならセルの背景色を水色に変更,それ以外の場合は何もしない」ということです.これを具体的な処理の手順として表現してみましょう.

 たとえば以下のような手順を考えることが出来ます.

  1. 選択された学生の得点を取得する
  2. 得点を判定する
  3. 得点が80点以上ならば,選択された学生の氏名・得点のセルの背景色を水色にする

 「条件分岐」の考え方が必要なのは,上記の手順の「得点が80点以上ならば」という部分です.ここでは「得点が80点以上か否か」が条件として評価され,80点以上ならば条件が成立します.そして,条件が成立したときだけ「セルの背景を水色にする」という処理が実行されます.結果として,条件が不成立ならばなにもしないことになります.

2.1.2 フローチャートによる処理手順の表現

 上記の処理の手順はフローチャートを用いると以下のように表現できます.フローチャートは処理の手順を図式化する1つの方法です.記法は図右側にある通りです.

フローチャート・成績判定

 フローチャートはプログラムを設計する際に用いる記法です.図式化することによって,複雑な処理手順を整理することが出来ます.

2.2 Ifステートメントと条件式

2.2.1 Ifステートメント

 上記のような「条件分岐」の構造を持った処理を表現する際には「Ifステートメント」を用います.Ifステートメントの一般的な記法は以下の通りです.


If 条件式 Then
	条件成立の時に行う処理
End If
		

 上記のステートメントの実行順序は次の通りです.まず最初に「条件式」が評価されます.今の段階では条件式の書き方を学んでいませんが,ここにはたとえば「得点が80点以上」といった意味の記述が書かれます.評価の結果,条件が成立した場合は「条件成立の時に行う処理」を順次実行し,End If以降の処理に進みます.「セルの背景色を水色にする」という処理はここに記述します.もしも条件が不成立の場合,この部分に書かれた処理は無視され,そのままEnd If以降の処理に進みます.

2.2.2 条件式

 条件式の箇所には「条件成立(プログラミングではTrueと呼ぶ)/不成立(同じくFalseと呼ぶ)」の判定結果を出すことの出来る様々な記述が入ります.その中で最も基本的なのは,変数の値の大小を判定する条件式です.

 仮にInteger型の変数「得点」があるとします.「変数「得点」の現在の値が80以上ならばTrue」を表現する条件式は次の通りです.


得点 >= 80
		

 上記の>=の記号は「左辺が右辺よりも大きいか等しいならばTrue」を表します.この条件式をIfステートメントに組み込むと以下のようになります.


If 得点>=80 Then
	セルの背景色を水色にする
End If
		

 条件式を構成する>=のような記号のことを「比較演算子」と呼びます.

参考!:VBAで用いられる比較演算子

 VBAでは以下の比較演算子を用いることが出来ます.

比較演算子 意味
< 左辺が右辺より小さい
<= 左辺が右辺以下
> 左辺が右辺より大きい
>= 左辺が右辺以上
= 左辺と右辺が等しい
<> 左辺と右辺が等しくない

2.3 ソースコードの記述

 以下は2.1の課題を解決するマクロの記述例です.


Sub テスト得点評価()
	Dim 得点 As Integer

	' テストの得点を取得する
	得点 = ActiveCell.Offset(, 1).Value	'得点の入力されたセル(氏名の右隣の列)の値を取得する

	' 成績優秀者を判別する
	If 得点 >= 80 Then  '得点が80点以上の場合
		ActiveCell.Interior.ColorIndex = 34 '氏名のセルの背景色を水色にする
		ActiveCell.Offset(, 1).Interior.ColorIndex = 34 '得点のセルの背景色を水色にする
	End If
End Sub
		

 ブロックコメントの記述は,2.1.1で示した処理手順の記述と異なる部分があります.その理由を,ブロックコメントと行コメント(各行に付加されたコメント,それぞれの行の処理の目的を記述する)の関係に注目しながら考えてみましょう.

3. 条件分岐の応用

 より複雑な条件分岐に対応するマクロの書き方を学習しましょう.

3.1 If〜Else〜の構造

 先程のテスト得点評価マクロの機能を拡張します.現状では成績優秀者の基準を変更して評価をやり直すようなケースで少々不便な点があります.たとえば成績優秀者の基準を75点以上としてマクロを実行した後で,基準を80点に戻して再びマクロを実行しようとすると,得点表の変更されたセルの背景色をいったん手動で「色なし」に戻す必要が生じます.学生の数が多くなると手間がかかります.これでは面倒なので,マクロ実行時に,成績優秀者以外のセルの背景色を積極的に「色なし」にするように仕様を変更します.

 以下は上記の変更を反映させたフローチャートです.

フローチャート・成績判定2

 最初に作成したものと異なる点は,「条件不成立(False)の場合」にも処理をさせる点です.このような構造をVBAで記述する場合,一般的に以下のような書き方をします.


If 条件式 Then
	条件成立の時に行う処理
Else
	条件不成立の時に行う処理
End If
		

 上記の書き方に従って,先程作成したマクロを書き換えてみましょう.「色なし」を指定するためには,ColorIndexプロパティに対して色番号のかわりに「xlNone」を代入します.

3.2 If〜ElseIf〜Elseの構造

 テスト得点評価マクロの機能をさらに拡張します.今度は成績優秀者と同時に「赤点」の学生も判別できるようにしましょう.仮に赤点の基準を40点以下,セルの背景色をピンク色(色番号22)とします.すると,マクロの処理の構造は以下のフローチャートのようになります.

フローチャート・成績判定3

 処理の手順は次の通りです.まず成績優秀者を判別します.得点の値を評価し,80点以上ならばセルの背景色を水色にします.80点以上でなければ,今度は赤点の学生を判別します.得点の値を評価し,40点以下ならばセルの背景色をピンク色にします.どちらにも該当しない学生は,セルの背景色を色なしにします.

 上記の処理を実現するためには,IfステートメントにElseIfを書き加えます.


If 条件式1 Then
	条件式1成立の時に行う処理
ElseIf 条件式2 Then
	条件式1不成立かつ条件式2成立の時に行う処理
Else
	条件式1,条件式2ともに不成立の時に行う処理
End If
		

 上記の書き方の場合,実行順序は次のようになります.まず始めに条件式1が評価され,Trueの場合は「条件式1成立の時に行う処理」を行い,End Ifに進みます.条件式1がFalseの場合,条件式2が評価されます.条件式2がTrueの場合「条件式1不成立かつ条件式2成立の時に行う処理」を行い,End Ifに進みます.条件式2もFalseの場合,「条件式1,条件式2ともに不成立の時に行う処理」を行い,End Ifに進みます.

 なお,ElseIfは1つだけでなく,必要に応じて書き加えることが出来ます(If〜ElseIf〜ElseIf・・・ElseIf〜End Ifのように).また,Elseを省略することも可能です.

 マクロに赤点の判別機能も加えたい場合,条件式1は「得点が80点以上」,条件式2は「得点が40点以下」となります.これらを参考に,マクロの機能を拡張してみましょう.

3.3 練習問題

 BMI(Body Mass Index:体格指数)を算出し,肥満度を判定するマクロを作成しましょう.

3.3.1 BMIとは

 BMIとは体重と身長のバランスをチェックして外見的な肥満度を調べる指数です.この指数は以下の式によって算出します.

 BMI=体重Kg/(身長m)2

 この値が22となることが理想と言われ,健康管理の目安として国際的に用いられています(ただしこの指数は体脂肪を考慮しないため,あくまで「目安」であると考えられます).以下の式によって,身長に応じた標準体重を求めることが出来ます.

 標準体重=22×(身長m)2

 また,BMIの値に対する評価は以下のように行います.

BMI値 評価
18.5未満 低体重
18.5以上25未満 普通体重
25以上30未満 肥満度1
30以上35未満 肥満度2
35以上40未満 肥満度3
40以上 肥満度4

3.3.2 マクロの仕様

 身長と体重を所定のセルに入力した後でマクロを実行すると,BMI値,標準体重,判定(BMI値に対する評価)が表示されるようにします(practice02.xls, Sheet4).

BMI判定1 マクロを実行すると... BMI判定2

 さらに,詳細な点について以下の条件を付けます.

  1. 身長はセンチメートル単位,体重はキログラム単位で入力する
  2. BMI値は小数点以下1桁まで算出する
  3. 標準体重はキログラム単位で,小数点以下1桁まで算出する
  4. 判定は文字列で表示する

3.3.3 ヒント

 以下のヒントを参考に,上記の仕様を満たすマクロを作成してみましょう.

  1. 身長はセンチメートル単位で受け取るので,BMI値の算出の前に必ずメートル単位に直すこと
  2. 「体重Kg/(身長m)2」の「(身長m)2」の部分は,()を用いて「(身長*身長)」と記述する
  3. 小数点以下の値を四捨五入し,指定した桁数に変換するためには,「Application.WorksheetFunction.Round(小数値, 桁数)」を用いる.たとえば変数aの値を小数点以下1桁に変換して変数bに代入するためには,「b = Application.WorksheetFunction.Round(a, 1)」と記述する(このとき変数a,変数bのデータ型はSingleまたはDoubleなければならない)
  4. セルに文字列型のデータを出力する際には,文字列を必ず""で囲む.たとえば「Range(A1).Value = "標準体重"」

ページ冒頭へ戻る
目次ページへ戻る