Excel VBA | Functionプロシージャ

VBA
スポンサーリンク

基本のおさらい:Function プロシージャって何?

  • Function プロシージャは「値を返すプロシージャ(関数)」です。
  • 「ある入力を受け取って処理を行い、結果(戻り値)を返す」ものです。
  • 書き方(最小形)は次の通り:
Function 関数名(引数1 As 型, 引数2 As 型, ...) As 戻り値の型
    ' 処理
    関数名 = 戻り値   ' ←ここで関数の結果をセットする
End Function
VB
  • 呼び出す側は 結果 = 関数名(引数...) のように書きます。
  • Sub は「処理するだけ」、Function は「処理して値を返す」と覚えればOK。

Step1 — 最短で動かしてみる(実行手順)

  1. Excel を開く → Alt + F11 で VBA エディタを開く。
  2. メニューで「挿入」→「標準モジュール」を追加。
  3. 下のコードをコピペして、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 は範囲が狭いので、大きな数や小数を扱うなら LongDouble を使いましょう。

例題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
VB

Function でも同じルールです。副作用を避けたい場合は 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:文字列
  • IntegerLong:整数(Long を使う方が安全)
  • Double:小数点を含む数値(計算用に一般的)
  • Boolean:True/False
  • Variant:何でも入る(柔軟だが型の安全性が落ちる)

例:真偽を返す関数

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

このように、エラーハンドリングに使えます。


よくあるミス & 対処法(初心者が躓きやすい)

  1. 関数名に戻り値を代入していない
    Function X(...) As Long と書いているのに X = ... を忘れると 0 が返るだけ。必ず代入する。
  2. 型の不一致でエラー
    Integer に大きな数を入れようとしてオーバーフローすることがある。大きい数は Long、小数は Double
  3. UDF でワークシートを直接変更する
    → 再計算や副作用の原因になる。関数は基本「入力→計算→出力」のみが望ましい。
  4. 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) のように使えます。


まとめ(初心者がまず覚えるべきこと)

  1. Function = 値を返す。戻り値は 関数名 = 値 でセット。
  2. 引数と戻り値の型を明示する(Option Explicit を使う)。
  3. ByVal を基本にし、必要なら ByRef を使う(副作用に注意)。
  4. UDF(ワークシート関数)としても使えるが、副作用(セル書き換え)は避ける。
  5. 小さな関数を作ってテスト→動いたら組み合わせる、を繰り返すと早く身につく。
VBA
スポンサーリンク
シェアする
@lifehackerをフォローする
スポンサーリンク
タイトルとURLをコピーしました