はじめに
第2回までで、VBAの基本的な処理(条件分岐、ループ)を学びました。しかし、作りたいものが複雑になるにつれて、すべての処理を一つのSubプロシージャ(Sub...End Subの塊)に書き連ねていくと、コードが長大化し、解読や修正が非常に困難になります。
今回は、コードを整理整頓し、再利用しやすくするための「構造化」という重要な概念を学びます。その中心となるのが**SubとFunctionの使い分け**、そして予期せぬエラーに対応するためのエラー処理です。これができると、あなたのコードは単なる「動くコード」から「良いコード」へと進化します。
1. Subプロシージャ – 仕事をこなす手順書
Subは「Subroutine(サブルーチン)」の略で、一連の連続した処理を実行するための手順書です。これまで私たちが書いてきたコードはすべてSubプロシージャでした。
Subの主な特徴は以下の通りです。
- 値を返さない:
Subは一連の動作(セルの色を変える、データを書き出すなど)を実行するだけで、それ自体が結果の値を持つことはありません。 - 単独で実行可能: Excelの「マクロの実行」ダイアログから直接呼び出したり、ボタンに登録したりできます。
' 「特定の処理」を実行するSubプロシージャ
Sub FormatReport()
' 見出しを太字にする
Range("A1:D1").Font.Bold = True
' A列の幅を自動調整する
Columns("A").AutoFit
End Sub
2. Functionプロシージャ – 値を返す計算機
Functionは、何らかの計算や処理を行い、その結果として一つの値(数値や文字列など)を返す機能を持っています。Excelのワークシート関数(SUMやVLOOKUPなど)の自作版と考えると分かりやすいでしょう。
Functionの主な特徴は以下の通りです。
- 値を返す:
Functionは必ず「戻り値(返り値)」と呼ばれる結果を返します。 - 単独では実行しない:
Functionは他のSubやFunctionから呼び出されたり、ワークシートのセルに数式として入力されたりして使われます。
例:税込み価格を計算するFunction
' Function Function名(引数1 As 型, ...) As 戻り値の型
Function CalcTaxIncluded(price As Double) As Long
Const TAX_RATE As Double = 0.1 ' 消費税率10%
' Function名と同じ名前の変数に結果を代入することで、値が返される
CalcTaxIncluded = price * (1 + TAX_RATE)
End Function
このFunctionを、別のSubから呼び出して使うことができます。
Sub ShowPrice()
Dim productAPrice As Double
productAPrice = 5000
' 作成したFunctionを呼び出し、結果を変数に格納
Dim taxIncludedPrice As Long
taxIncludedPrice = CalcTaxIncluded(productAPrice)
' 結果をメッセージボックスで表示
MsgBox "税込み価格は" & taxIncludedPrice & "円です。"
End Sub
このように、特定の計算処理をFunctionとして部品化(モジュール化)することで、同じ計算が何度も必要になったときに、そのFunctionを呼び出すだけで済むようになります。
3. 引数(ひきすう) – プロシージャに情報を渡す
上記のCalcTaxIncluded(price As Double)のprice As Doubleの部分を**引数(ひきすう)**と呼びます。引数は、プロシージャ(SubやFunction)を呼び出す際に、外部から情報を渡すための入り口です。
引数を使うことで、プロシージャはより汎用(はんよう)的になります。例えば、税率も引数として渡せるようにすれば、将来税率が変わってもFunctionを修正する必要がなくなります。
' 税率も引数で受け取るように改良
Function CalcTaxIncluded2(price As Double, taxRate As Double) As Long
CalcTaxIncluded2 = price * (1 + taxRate)
End Function
Sub ShowPrice2()
' 呼び出す際に、具体的な値を2つ渡す
Dim result As Long
result = CalcTaxIncluded2(5000, 0.1)
MsgBox result
End Sub
4. エラー処理 – 予期せぬ事態に備える
作成したVBAが、常に想定通りのデータや環境で使われるとは限りません。ファイルが見つからなかったり、数値が入るべきセルに文字列が入っていたりすると、VBAはエラーを出して停止してしまいます。
On Error GoTo [ラベル名]という構文を使うと、エラーが発生した際に処理を中断せず、指定した場所にジャンプさせることができます。これにより、エラー発生時にユーザーに分かりやすいメッセージを表示したり、処理を安全に終了させたりすることが可能になります。
例:ゼロ除算エラーを回避する
Sub DivisionCalculator()
On Error GoTo ErrorHandler ' エラーが起きたらErrorHandler:へジャンプ
Dim numerator As Double
Dim denominator As Double
Dim result As Double
numerator = 100
denominator = 0 ' 本来はユーザー入力などを想定
result = numerator / denominator
MsgBox "計算結果: " & result
Exit Sub ' 正常終了時はエラー処理をスキップ
' エラー処理の本体
ErrorHandler:
MsgBox "エラーが発生しました。0で割ることはできません。"
End Sub
On Error GoTo ErrorHandler: この行以降でエラーが発生すると、ErrorHandler:と書かれた行までジャンプします。Exit Sub: 正常に処理が完了した場合、ErrorHandler:の処理を実行せずにプロシージャを抜けるために記述します。ErrorHandler:: エラー発生時の処理を記述する場所を示すラベルです。
まとめ
今回は、VBAコードを構造化し、品質を高めるための重要な概念を学びました。
Sub: 処理を実行する手順書。単独で実行できる。Function: 計算などを行い、結果の値を返す部品。他のプロシージャから呼び出して使う。- 引数: プロシージャに外部から情報を与え、汎用性を高める仕組み。
- エラー処理:
On Error GoToで予期せぬエラーに対応し、プログラムの安定性を高める。
これらの概念を使いこなすことで、あなたのVBAプロジェクトは格段に管理しやすく、そして頑健になります。次回は、いよいよ外部のCSVファイルなどからデータを取り込み、分析の準備をする方法について解説します。
コメント