基本のおさらい:Function プロシージャって何?
- Function プロシージャは「値を返すプロシージャ(関数)」です。
- 「ある入力を受け取って処理を行い、結果(戻り値)を返す」ものです。
- 書き方(最小形)は次の通り:
Function 関数名(引数1 As 型, 引数2 As 型, ...) As 戻り値の型
' 処理
関数名 = 戻り値 ' ←ここで関数の結果をセットする
End Function
VB- 呼び出す側は
結果 = 関数名(引数...)のように書きます。 - Sub は「処理するだけ」、Function は「処理して値を返す」と覚えればOK。
Step1 — 最短で動かしてみる(実行手順)
- Excel を開く → Alt + F11 で VBA エディタを開く。
- メニューで「挿入」→「標準モジュール」を追加。
- 下のコードをコピペして、F5(またはSubから実行)で動かすか、Immediate ウィンドウやセルから呼び出す。
例題1:点数から合否を返す関数(基本例)
目的:整数の得点を入れると "合格" / "不合格" を返す。
Function Hantei(ByVal tokuten As Integer) As String
If tokuten >= 80 Then
Hantei = "合格"
Else
Hantei = "不合格"
End If
End Function
Sub TestHantei()
Dim res As String
res = Hantei(75) ' "不合格"
Debug.Print res ' Immediate ウィンドウに出力
Debug.Print Hantei(92) ' "合格"
End Sub
VBポイント:
ByValは「値渡し(コピー)」です(詳しくは後述)。Hantei = ...で戻り値をセットします。関数名自体に代入するのが VBA の戻り値の書き方。
例題2:複数引数の関数(合計を返す)
目的:2つの数値の合計を返す関数。
Function AddTwo(a As Double, b As Double) As Double
AddTwo = a + b
End Function
Sub TestAddTwo()
Debug.Print AddTwo(1.5, 2.3) ' 3.8
End Sub
VBポイント:
- 戻り値や引数に
Double(小数点対応)を使うと小数も扱えます。 Integerは範囲が狭いので、大きな数や小数を扱うならLongやDoubleを使いましょう。
例題3:セル(ワークシート)から使えるユーザー定義関数(UDF)
Module に Public な Function を置くと、Excel のセルで =MyFunc(A1) として使えます。
' 標準モジュールに置く(Sheet モジュールではなく Module)
Public Function CelsiusToF(c As Double) As Double
CelsiusToF = c * 9 / 5 + 32
End Function
VBセルに =CelsiusToF(0) と入れると 32 が返ります。セル参照も使えます:=CelsiusToF(A1)。
注意:
- ワークシートから呼ぶ UDF は 実行が速くないので大量セルで使うと遅くなることがあります。
- UDF からセルを直接書き換える(
Range("A1").Value = ...)のは避けるべき(副作用でエラーや再計算問題が起きやすい)。
引数の渡し方:ByVal と ByRef の違い(初心者向け)
ByVal(バイバリュー):値のコピーを渡す。関数内で引数を書き換えても呼び出し元の変数は変わらない。ByRef(バイリファレンス):引数の参照を渡す。関数内で引数を書き換えると呼び出し元の変数も変わる(既定は ByRef)。
例:
Sub DemoByVal()
Dim x As Integer: x = 5
IncByVal x
Debug.Print x ' 5 のまま
x = 5
IncByRef x
Debug.Print x ' 6 に変わる
End Sub
Sub IncByVal(ByVal n As Integer)
n = n + 1
End Sub
Sub IncByRef(ByRef n As Integer)
n = n + 1
End Sub
VBFunction でも同じルールです。副作用を避けたい場合は ByVal を使うのが安全です。
Optional 引数・デフォルト値(便利テク)
引数を省略可能にするには Optional を使います。省略されたらデフォルトを使う処理を入れます。
Function Greet(Optional name As String = "ゲスト") As String
Greet = "こんにちは、" & name & "さん"
End Function
Sub TestGreet()
Debug.Print Greet() ' "こんにちは、ゲストさん"
Debug.Print Greet("太郎") ' "こんにちは、太郎さん"
End Sub
VB注意:Optional の既定値は引数の型に依ります(Variant 以外は既定値を明示するか、IsMissing を使う)。
戻り値の型について(よく使う型)
String:文字列Integer、Long:整数(Longを使う方が安全)Double:小数点を含む数値(計算用に一般的)Boolean:True/FalseVariant:何でも入る(柔軟だが型の安全性が落ちる)
例:真偽を返す関数
Function IsEven(n As Long) As Boolean
IsEven = (n Mod 2 = 0)
End Function
VBワンポイント:関数内で Exit Function を使う
早めに結果を返したいとき、Exit Function を使えます。
Function SafeDivide(a As Double, b As Double) As Variant
If b = 0 Then
SafeDivide = CVErr(xlErrDiv0) ' Excel の #DIV/0! を返す
Exit Function
End If
SafeDivide = a / b
End Function
VBこのように、エラーハンドリングに使えます。
よくあるミス & 対処法(初心者が躓きやすい)
- 関数名に戻り値を代入していない
→Function X(...) As Longと書いているのにX = ...を忘れると 0 が返るだけ。必ず代入する。 - 型の不一致でエラー
→Integerに大きな数を入れようとしてオーバーフローすることがある。大きい数はLong、小数はDouble。 - UDF でワークシートを直接変更する
→ 再計算や副作用の原因になる。関数は基本「入力→計算→出力」のみが望ましい。 - Option Explicit を使わない
→ 変数名のタイポでバグが生まれる。Option Explicitをモジュールの先頭に書いて、必ず宣言する習慣をつけましょう。
練習問題(手を動かして学ぶ)
各問題は標準モジュールにコードを作って試してみてください。最後に模範解答を載せます。
問題1
得点(0〜100)を渡すと "A" / "B" / "C" / "D" を返す関数を作れ。
基準:90 以上 A、80〜89 B、70〜79 C、それ以外 D。
問題2
文字列を渡すと、先頭1文字を大文字にして返す関数 Capitalize(s As String) As String を作れ。
例:"hello" → "Hello"。
問題3
温度リスト(複数セル)を受け取り、平均を返す関数を作れ(引数は rng As Range)。
ヒント:Range の各セルを For Each で回して合計→平均。
模範解答
問題1
Function Grade(score As Integer) As String
If score >= 90 Then
Grade = "A"
ElseIf score >= 80 Then
Grade = "B"
ElseIf score >= 70 Then
Grade = "C"
Else
Grade = "D"
End If
End Function
VB問題2
Function Capitalize(s As String) As String
If Len(s) = 0 Then
Capitalize = ""
Exit Function
End If
Capitalize = UCase(Left(s, 1)) & Mid(s, 2)
End Function
VB問題3
Function RangeAverage(rng As Range) As Variant
Dim cell As Range
Dim sum As Double
Dim count As Long
sum = 0
count = 0
For Each cell In rng
If IsNumeric(cell.Value) Then
sum = sum + cell.Value
count = count + 1
End If
Next
If count = 0 Then
RangeAverage = CVErr(xlErrDiv0)
Else
RangeAverage = sum / count
End If
End Function
VBセルで =RangeAverage(A1:A10) のように使えます。
まとめ(初心者がまず覚えるべきこと)
- Function = 値を返す。戻り値は
関数名 = 値でセット。 - 引数と戻り値の型を明示する(
Option Explicitを使う)。 - ByVal を基本にし、必要なら ByRef を使う(副作用に注意)。
- UDF(ワークシート関数)としても使えるが、副作用(セル書き換え)は避ける。
- 小さな関数を作ってテスト→動いたら組み合わせる、を繰り返すと早く身につく。
