はじめに
第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ファイルなどからデータを取り込み、分析の準備をする方法について解説します。
コメント