Excel VBA | 戻り値のある Function(関数)プロシージャの書き方

VBA
スポンサーリンク

Excel VBAの function(関数)プロシージャの基本

最初に押さえるポイントは「Subは命令を実行するもの」「Functionは“計算して値を返す”もの」。Functionは“入力→処理→出力(戻り値)”の流れで考えると理解しやすいです。


function と sub の違い

  • 役割:
    Sub: 何かを実行する(メッセージ表示やセル操作など)。戻り値はない。
    Function: 計算して“値”を返す。式やセルの中で使える。
  • 使いどころ:
    Sub: ボタンから動かす作業系の処理。
    Function: 値を作り出す処理(合計、判定、書式生成など)。

基本の書き方(戻り値の作り方)

  • 構文の型:
    Functionの戻り値は「関数名に代入」して決まります。
Function AddTwo(ByVal a As Long, ByVal b As Long) As Long
    AddTwo = a + b  ' ← 戻り値を設定
End Function
VB
  • 呼び出し方(VBA側):
Sub Test_AddTwo()
    Dim s As Long
    s = AddTwo(10, 25)
    MsgBox "合計は " & s
End Sub
VB
  • ワークシートで使う:
    標準モジュールに置いたPublic関数なら、セルで
    =AddTwo(10,25)
    と書けば結果が出ます(UDF: ユーザー定義関数)。

よく使う戻り値の型と例

  • 数値(Long/Double):
Function CalculateTax(ByVal amount As Double, ByVal rate As Double) As Double
    CalculateTax = amount * rate
End Function
VB
  • 真偽値(Boolean):
Function IsEven(ByVal n As Long) As Boolean
    IsEven = (n Mod 2 = 0)
End Function
VB
  • 文字列(String):
Function FormatFullName(ByVal lastName As String, ByVal firstName As String) As String
    FormatFullName = lastName & " " & firstName
End Function
VB
  • 日付(Date):
Function DaysBetween(ByVal startDate As Date, ByVal endDate As Date) As Long
    DaysBetween = endDate - startDate
End Function
VB

引数の渡し方とオプション引数

  • 基本は ByVal(値渡し):
    安全重視: 呼び出し元の変数が書き換わらない。
Function DoubleSafe(ByVal n As Long) As Long
    DoubleSafe = n * 2
End Function
VB
  • ByRef(参照渡し)は例外的に:
    主に“戻り値+副作用”が必要なときだけ。ただし、初心者はまずByValで十分。
  • Optional(省略可能)と既定値:
    使いやすさが上がります。
Function RoundFlexible(ByVal value As Double, Optional ByVal digits As Long = 0) As Double
    RoundFlexible = WorksheetFunction.Round(value, digits)
End Function
VB

例題で身につける

例題1:安全な割り算(ゼロ除算対策)

Function SafeDivide(ByVal numerator As Double, ByVal denominator As Double) As Variant
    If denominator = 0 Then
        SafeDivide = CVErr(xlErrDiv0)  ' ワークシート関数で #DIV/0! を返す
    Else
        SafeDivide = numerator / denominator
    End If
End Function
VB
  • ポイント: Worksheetでエラー表現が必要ならVariant+CVErrが便利。

例題2:範囲の合計(UDF)

Public Function RangeSum(ByVal target As Range) As Double
    Dim cell As Range
    Dim total As Double
    For Each cell In target.Cells
        If IsNumeric(cell.Value) Then
            total = total + cell.Value
        End If
    Next
    RangeSum = total
End Function
VB
  • 使い方: セルに =RangeSum(A1:A10) と入力。

例題3:採点の判定(合否)

Function PassOrFail(ByVal score As Long, Optional ByVal passLine As Long = 60) As String
    If score >= passLine Then
        PassOrFail = "合格"
    Else
        PassOrFail = "不合格"
    End If
End Function
VB

例題4:テキストの整形(見出し化)

Function MakeTitle(ByVal text As String, Optional ByVal width As Long = 20) As String
    Dim t As String
    t = Trim(text)
    If Len(t) = 0 Then
        MakeTitle = String(width, "-")
    Else
        MakeTitle = t & " " & String(Application.Max(width - Len(t) - 1, 0), "-")
    End If
End Function
VB

よくあるつまずきと回避策

  • 戻り値の設定忘れ:
    関数名に代入しないと既定値(数値なら0、文字列なら空文字など)になる。
    → 処理の最後で必ず「関数名 = 結果」を入れる。
  • 型不一致(Type mismatch):
    引数や戻り値の型が合わないとエラー。
    → 宣言を明確に、必要なら型変換(CLng、CDbl、CStr)。
  • ワークシートから呼べない:
    標準モジュールにPublic Functionとして置く。シート/ThisWorkbookのモジュールだと見えないことがある。
    → 「挿入→標準モジュール」に関数を作成。
  • 副作用が強すぎる関数:
    UDFはセルから呼ばれる前提なら“純粋関数(入力に対して同じ出力)”が望ましい。
    → セル変更やMsgBoxはSub側へ分離。

練習問題

  • 練習1:税込計算
    • 目標: 金額と税率を渡して税込金額を返す。
    • ヒント: 税額を足してDoubleで返す。
Function WithTax(ByVal amount As Double, Optional ByVal taxRate As Double = 0.1) As Double
    WithTax = amount * (1 + taxRate)
End Function
VB
  • 練習2:文字の出現回数
    • 目標: 文字列中の特定文字の回数を返す。
    • ヒント: ループまたはReplaceで差分を取る。
Function CountChar(ByVal text As String, ByVal ch As String) As Long
    If Len(ch) <> 1 Then
        CountChar = 0
        Exit Function
    End If
    CountChar = Len(text) - Len(Replace(text, ch, ""))
End Function
VB
  • 練習3:範囲の平均(空白除外)
    • 目標: 数字セルだけ平均を返す。数字がなければエラー返却。
Function AverageNumbers(ByVal target As Range) As Variant
    Dim cell As Range, total As Double, count As Long
    For Each cell In target.Cells
        If IsNumeric(cell.Value) Then
            total = total + cell.Value
            count = count + 1
        End If
    Next
    If count = 0 Then
        AverageNumbers = CVErr(xlErrNA)
    Else
        AverageNumbers = total / count
    End If
End Function
VB

まとめのチェックリスト

  • 戻り値: 関数名に代入して“必ず”設定する。
  • 型選択: Long/Double/String/Boolean/Dateを目的に合わせて。
  • ByVal中心: 変更が必要な場合のみByRef。
  • UDFの場所: 標準モジュール+Public。
  • 副作用なし: UDFは値を返すことに集中、画面操作はSubへ。

「Functionは“値を作る工場”」——入力(材料)を渡して、ルール(処理)で整え、出荷(戻り値)する。この感覚で書けると、VBAが一気に扱いやすくなります。どれか一つ、まずは自分の業務に合わせて作ってみましょう。

タイトルとURLをコピーしました