【2026年7月最新】VBA Function完全ガイド|定義・引数・戻り値・ByVal/ByRef・実務活用まで徹底解説
この記事の内容
「VBAでFunctionってどう使うの?」「SubとFunctionの違いがよく分からない」——この記事を読んでいるあなたは、おそらくExcelマクロを作り始めて、そろそろ処理を整理したいと感じているのではないでしょうか。
VBAのFunctionは、一言でいうと「処理の部品化ツール」です。同じ計算や文字列操作を何度も書くのをやめて、1箇所にまとめておき、どこからでも呼び出せるようにする仕組みです。使いこなせると、コードが圧倒的に読みやすく・保守しやすく・エラーが減るようになります。
この記事では、VBA Functionの基本から、引数・戻り値・ByVal/ByRef・配列戻り値・エラーハンドリングまでを、コードサンプルとともに段階的に解説します。また、最後のセクションでは、弊社GENAIが実際に業務で運用している実例と、AIにVBAコードを書かせる方法もお伝えします。
この記事を最後まで読むと、次の7つが身につきます。
01 WHAT IS FUNCTION VBA Functionとは何か(SubとFunctionの違い) まずSubとの違いを理解しないと、Functionは使いこなせない
VBAには2種類の「処理のまとまり」があります。Sub(サブルーチン)とFunction(関数)です。どちらも「複数の命令をひとまとめにして、名前をつけて呼び出せる仕組み」ですが、決定的に異なる点が1つあります。
Functionは「値を返せる」、Subは「値を返せない」——この違いだけ最初に押さえてください。あとの細かい文法は、この違いから自然に導かれます。
📚 用語解説
Sub(サブルーチン):VBAで「処理のまとまり」に名前をつけたもの。「セルを色で塗る」「データを並べ替える」など、実行して終わりの命令セットに使う。戻り値を返す機能はない。マクロとしてボタンに登録して実行する場合にも使われる。
📚 用語解説
Function(関数):処理のまとまりに名前をつけつつ、処理の結果を「値として返す」ことができる仕組み。呼び出し元に数値・文字列・配列などを返せる。Excelのシート関数(SUM、IFなど)に近いイメージで作る自作の処理部品。
1-1. SubとFunctionを使い分ける判断基準
「SubとFunctionのどちらを書くべきか」は、以下の1つの問いで決まります。
「この処理の結果を、別の場所で値として使いたいか?」
YES → Function NO → Sub
この判断が一瞬でできるようになれば、VBAの設計力は格段に上がります。
| 用途 | 使うべき | 例 |
|---|---|---|
| セルを色で塗る・データを移動する | Sub | FormatCells、MoveData など |
| 計算結果を別のセルに入れたい | Function | CalcTax、GetFullName など |
| 文字列を加工して返したい | Function | CleanSpaces、ExtractCode など |
| ボタンを押してマクロを実行したい | Sub | ボタンに登録できるのはSubのみ |
| 他のFunctionやSubから値を受け取りたい | Function | 戻り値で呼び出し元に返す |
1-2. Functionが「なぜ必要か」——コードの部品化という考え方
Functionを使う最大の目的は「コードの部品化」です。同じ処理を複数のSubで書き直すのではなく、1つのFunctionにまとめて「それを呼び出す」形にします。
例えば、消費税を計算する処理を考えてみます。税率が変わったとき、同じ計算式が10箇所に書かれていたら全部修正が必要です。しかし、Function CalcTax(price As Long) As LongというFunctionに1箇所だけ書いておけば、修正は1箇所で済みます。これが部品化の本質です。
1つのFunctionは「1つのことだけ」をするよう設計しましょう。「消費税計算+セルへの書き込み+色の変更」を1つのFunctionに詰め込まないこと。処理が1つだと、テストが楽になり、別の場所での再利用も簡単になります。
02 BASIC SYNTAX Functionの基本構文と書き場所 ExcelとAccessの共通事項、モジュールの選び方まで
VBA Functionの基本構文は以下の形です。まずは全体像を掴みましょう。
Function 関数名(引数1 As データ型, 引数2 As データ型) As 戻り値のデータ型
'処理内容
関数名 = 戻り値 '★ここで関数名に値を代入するのが「戻り値を返す」構文
End Function
ポイントは「関数名 = 戻り値」という代入構文で値を返すことです。他の言語ではreturnキーワードを使いますが、VBAでは「自分自身の名前に値を代入する」という独特の書き方をします。最初は戸惑いますが、すぐ慣れます。
📚 用語解説
データ型(As 〜):変数や引数・戻り値が扱う値の種類を指定するキーワード。Long(整数)、String(文字列)、Double(小数)、Boolean(True/False)、Variant(何でも可)などがある。型を明示すると処理が速くなり、型の不一致によるバグも防げる。
2-1. Functionを書く場所——標準モジュールの使い方
VBA Functionは標準モジュール(Module1 など)に書くのが基本です。シートモジュール(Sheet1 など)やThisWorkbookにも書けますが、どのシートからでも呼び出したい汎用Functionは標準モジュールに集約するのがベストプラクティスです。
Alt+F11で
エディタ開く
挿入→
標準モジュール
ここに
Function〜End
Sub・他Function
・シート関数から
📚 用語解説
VBE(Visual Basic Editor):ExcelやAccessでVBAコードを書くための専用エディタ。Alt+F11で起動する。左側のプロジェクトツリーでシート・モジュール・フォームを選択し、右側のコード画面でVBAを記述する。
2-2. ExcelのシートからFunctionを呼び出す3つの方法
標準モジュールに書いたFunctionは、以下の3つの方法で呼び出せます。
| 呼び出し方 | 具体例 | 使いどころ |
|---|---|---|
| 別のSubやFunctionから呼ぶ | result = CalcTax(10000) | 最も一般的。処理の組み合わせに使う |
| Excelシートの数式として使う | =CalcTax(A2) | ユーザー定義関数(UDF)として使う |
| イミディエイトウィンドウで呼ぶ | ?CalcTax(5000) | デバッグ・テスト用途 |
ExcelシートからFunctionを直接呼ぶ(UDF)場合、そのFunctionの中でセルの値を変更したり、ActiveSheetを操作する処理は書けません(エラーになります)。UDFは「計算して値を返すだけ」の純粋な関数として設計してください。
03 MINIMAL PATTERN 引数なし・戻り値なしの最小パターン まずここから始めて、Functionの動きを体感する
「引数なし・戻り値なし」のFunctionは、Subとほぼ同じ動作をします。Functionの基本動作を体感するための最小パターンとして使います。
Function SayHello()
MsgBox "こんにちは!"
End Function
'呼び出し側
Sub TestHello()
Call SayHello 'Callキーワードで呼ぶ
'または
SayHello 'Callなしでも呼べる
End Sub
この例ではSayHelloはメッセージを表示するだけで、値を返しません。この場合は実はSubの方が適切ですが、「Functionとして書いて、Subから呼ぶ」という最小パターンを確認する目的で使います。
戻り値なしのFunctionを「Function名()=値」を書かずに使うのは技術的には動きますが、SubとFunctionの設計思想が混在してコードが読みにくくなります。「値を返さないならSub」「値を返すならFunction」を徹底することで、チームでのコードレビューが楽になります。
3-1. 最小Functionをイミディエイトウィンドウでテストする
VBEのイミディエイトウィンドウ(Ctrl+G で開く)で?SayHello()と入力してEnterを押すと、Functionが直接実行されます。テスト段階では、いちいちSubを経由せずにイミディエイトで動作確認するのが最速です。
'イミディエイトウィンドウに入力 ?SayHello() '→ メッセージボックスが表示される '戻り値ありのFunctionなら結果が表示される ?CalcTax(10000) '→ 1000 (10%の場合) が表示される
04 ARGS & RETURN 引数あり・戻り値ありの定義と呼び出し ここがFunctionの本領。値を渡して・受け取る基本パターン
VBA Functionの真価は「引数を受け取って、処理して、結果を返す」ところにあります。消費税計算を例に、基本パターンを確認しましょう。
'消費税計算Function(税抜価格を受け取り、税込価格を返す)
Function CalcTax(price As Long) As Long
CalcTax = price + (price * 0.1) '税込価格を関数名に代入=戻り値
End Function
'呼び出し側
Sub TestCalcTax()
Dim taxIncluded As Long
taxIncluded = CalcTax(10000) '10000を渡す
MsgBox "税込価格: " & taxIncluded & "円" '→ 11000円
End Sub
ポイントを整理します。引数 price As Long は「Long型(整数)の値を受け取る」宣言です。戻り値型 As Long は「このFunctionはLong型の値を返す」宣言です。そしてCalcTax = 計算結果 で「この値を返す」という動作になります。
4-1. 戻り値の型を正しく選ぶ
| 型 | VBAの型名 | 使いどころ |
|---|---|---|
| 整数(小数なし) | Long | 件数・金額・行番号など。Integer(±32767)は上限に注意 |
| 小数ありの数値 | Double | 税率・割合・統計計算など |
| 文字列 | String | 名前・コード・メッセージなど |
| True/False | Boolean | 条件チェック・フラグ管理など |
| 日付 | Date | 日付計算・期限チェックなど |
| なんでも(遅い) | Variant | 型が不定の場合。速度が必要なら避ける |
📚 用語解説
Long型とInteger型の違い:IntegerはVBAで±32,767までの整数を扱う型。一見コンパクトに見えるが、現代の64ビットPC環境ではLong(±2,147,483,647)の方が処理が速い。Excelの行数は最大104万行なので、行番号を扱う変数はLongを使うのが安全。
4-2. 文字列を返すFunctionの実例
次に、文字列操作のFunctionを見てみます。姓と名を引数で受け取り、フルネーム(姓 名)を返す例です。
'フルネームを返すFunction
Function GetFullName(lastName As String, firstName As String) As String
GetFullName = lastName & " " & firstName '全角スペースで結合
End Function
'呼び出し側
Sub TestGetFullName()
Dim fullName As String
fullName = GetFullName("菅澤", "孝平")
MsgBox fullName '→ 「菅澤 孝平」と表示
End Sub
4-3. Boolean(True/False)を返すFunctionの実例
条件チェックにはBoolean型を返すFunctionが便利です。「この値が有効かどうか」を判定する処理を1箇所にまとめられます。
'メールアドレスの簡易バリデーション
Function IsValidEmail(email As String) As Boolean
If InStr(email, "@") > 0 And InStr(email, ".") > 0 Then
IsValidEmail = True
Else
IsValidEmail = False
End If
End Function
'呼び出し側
Sub CheckEmails()
Dim i As Long
For i = 2 To 100
If IsValidEmail(Cells(i, 1).Value) Then
Cells(i, 2).Value = "有効"
Else
Cells(i, 2).Value = "無効"
End If
Next i
End Sub
Boolean型を返すFunctionは「Is〜」「Has〜」「Can〜」という名前にするのが慣習です。IsValidEmail、HasData、CanProcessのように命名すると、呼び出し元でIf IsValidEmail(email) Thenと読みやすいコードになります。
05 MULTIPLE ARGS 複数引数とOptional・デフォルト値の使い方 引数を柔軟に扱う実務的なテクニック
VBA Functionには複数の引数を設定できます。またOptional(省略可能引数)を使うと、引数を省略した場合のデフォルト値を設定できます。
5-1. 複数引数のFunctionの書き方
'複数引数の例:割引後の価格を計算する
Function CalcDiscountPrice(price As Long, discountRate As Double) As Long
CalcDiscountPrice = CLng(price * (1 - discountRate))
End Function
'呼び出し側
Sub TestDiscount()
Dim result As Long
result = CalcDiscountPrice(10000, 0.2) '10000円、20%オフ
MsgBox "割引後: " & result & "円" '→ 8000円
End Sub
📚 用語解説
CLng関数:VBAの変換関数の1つ。Doubleなどの小数を含む値をLong(整数)に変換する際に使う。四捨五入ではなく「銀行型丸め(最近偶数丸め)」が適用されるため、厳密な金額計算には独自の丸め処理が必要な場合もある。
5-2. Optional引数でデフォルト値を設定する
Optionalキーワードを使うと、その引数を省略できるようになります。省略されたときのデフォルト値はOptional 引数名 As 型 = デフォルト値の形で指定します。
'消費税計算(税率を省略した場合は10%をデフォルト)
Function CalcTaxCustom(price As Long, Optional taxRate As Double = 0.1) As Long
CalcTaxCustom = CLng(price * (1 + taxRate))
End Function
'呼び出し側
Sub TestCalcTaxCustom()
MsgBox CalcTaxCustom(10000) '→ 11000(税率省略→10%)
MsgBox CalcTaxCustom(10000, 0.08) '→ 10800(8%を明示)
End Sub
Optionalを使うときの重要なルールが1つあります。Optional引数は必ず引数リストの末尾に置くことです。必須引数の前にOptionalを置くと構文エラーになります。
Optional引数は必ず引数リストの後ろに置いてください。Function Test(Optional a As Long, b As Long)のように必須引数(b)をOptional(a)の後に置くとコンパイルエラーになります。Function Test(b As Long, Optional a As Long = 0)が正しい順序です。
5-3. IsMissing関数でオプション引数の省略を判定する
Variant型のOptional引数を使うと、IsMissing関数で「引数が省略されたかどうか」を判定できます。デフォルト値では対応できない複雑な分岐処理に使います。
Function CalcWithCheck(price As Long, Optional discountRate As Variant) As Long
If IsMissing(discountRate) Then
'引数が省略された場合の処理
CalcWithCheck = price
Else
'引数が渡された場合の処理
CalcWithCheck = CLng(price * (1 - discountRate))
End If
End Function
06 BYVAL VS BYREF ByVal(値渡し)とByRef(参照渡し)の違い 理解しないとバグの原因になる、VBA設計の核心
VBAの引数にはByVal(値渡し)とByRef(参照渡し)という2つの渡し方があります。どちらを使うかによって、呼び出し元の変数が変わるかどうかが決まります。ここを理解していないと、予期せずデータが書き変わるバグを生みます。
📚 用語解説
ByVal(値渡し):引数として渡す変数の「値のコピー」をFunctionに渡す。Function内で引数を書き換えても、呼び出し元の変数には影響しない。安全だが、大きなデータを扱う場合はメモリを余分に消費する。
📚 用語解説
ByRef(参照渡し):引数として渡す変数の「メモリアドレス(参照先)」をFunctionに渡す。Function内で引数を書き換えると、呼び出し元の変数も同時に書き変わる。VBAのデフォルトの挙動。
6-1. ByValとByRefの動作の違いをコードで確認する
'ByVal の例(呼び出し元の変数は変わらない)
Function DoubleByVal(ByVal n As Long) As Long
n = n * 2 'ローカルコピーを変更(呼び出し元には影響なし)
DoubleByVal = n
End Function
'ByRef の例(呼び出し元の変数が変わる)
Function DoubleByRef(ByRef n As Long) As Long
n = n * 2 '参照先(呼び出し元の変数)を変更
DoubleByRef = n
End Function
'比較テスト
Sub TestByValByRef()
Dim x As Long
x = 10
Debug.Print DoubleByVal(x) '→ 20 が返る
Debug.Print x '→ 10(変わらない!)
x = 10
Debug.Print DoubleByRef(x) '→ 20 が返る
Debug.Print x '→ 20(変わってしまった!)
End Sub
6-2. ByValとByRefの使い分けルール
実務での使い分けは以下のシンプルなルールで判断できます。
| 状況 | 使うべき | 理由 |
|---|---|---|
| 呼び出し元の変数を変えたくない(通常) | ByVal | 安全。副作用がなく、バグを防げる |
| Functionから複数の値を返したい | ByRef | ByRef引数に値を代入すると、複数の「返値」として使える |
| 大きな配列・オブジェクトを渡す | ByRef | コピーせずアドレスだけ渡すのでメモリ効率が良い |
| プリミティブな数値・文字列の通常引数 | ByVal | デフォルト推奨。明示的にByValを書く習慣をつける |
VBAのデフォルトはByRefです。引数に何も書かないとByRefとして動きます。コードの意図を明確にするため、「この引数は変更しない」場合は明示的にByValと書く習慣をつけましょう。他の人がコードを読んだとき、意図が伝わりやすくなります。
6-3. ByRefを使って複数の値を「返す」テクニック
VBAのFunctionは戻り値を1つしか返せません。しかし、ByRef引数を使うと、実質的に複数の値を呼び出し元に返せます。
'最大値と最小値を同時に返すFunction(ByRefを使って2値を返す)
Function GetMinMax(arr() As Long, ByRef minVal As Long, ByRef maxVal As Long) As Boolean
If UBound(arr) < LBound(arr) Then
GetMinMax = False '空配列エラー
Exit Function
End If
minVal = arr(LBound(arr))
maxVal = arr(LBound(arr))
Dim i As Long
For i = LBound(arr) + 1 To UBound(arr)
If arr(i) < minVal Then minVal = arr(i)
If arr(i) > maxVal Then maxVal = arr(i)
Next i
GetMinMax = True '正常終了
End Function
'呼び出し側
Sub TestMinMax()
Dim data(4) As Long
data(0) = 50: data(1) = 10: data(2) = 80: data(3) = 30: data(4) = 60
Dim mn As Long, mx As Long
If GetMinMax(data, mn, mx) Then
MsgBox "最小: " & mn & " / 最大: " & mx '→ 最小: 10 / 最大: 80
End If
End Sub
07 ARRAY RETURN 配列を戻り値として返すパターン 複数の値を一括で返したいときの高度な手法
VBAのFunctionは、配列(Array)を戻り値として返すことができます。複数のデータをまとめて返したい場合に使います。戻り値型をVariantにするのが最も手軽な方法です。
'文字列配列を返すFunction(スペース区切りで分割)
Function SplitText(text As String) As Variant
SplitText = Split(text, " ") 'スペースで分割した配列を返す
End Function
'呼び出し側
Sub TestSplitText()
Dim result As Variant
result = SplitText("VBA Function 完全ガイド")
Dim i As Long
For i = LBound(result) To UBound(result)
Debug.Print result(i) '→ VBA / Function / 完全ガイド
Next i
End Sub
7-1. 数値配列を生成して返すFunction
より実務的な例として、指定した行数のシートデータを配列として返すFunctionを見てみます。
'シートの指定列のデータを配列で返すFunction
Function GetColumnData(ws As Worksheet, col As Long, startRow As Long, endRow As Long) As Variant
Dim arr() As Variant
Dim rowCount As Long
rowCount = endRow - startRow + 1
ReDim arr(1 To rowCount)
Dim i As Long
For i = 1 To rowCount
arr(i) = ws.Cells(startRow + i - 1, col).Value
Next i
GetColumnData = arr
End Function
'呼び出し側
Sub TestGetColumnData()
Dim data As Variant
data = GetColumnData(Sheet1, 1, 2, 10) 'Sheet1のA列、2行目から10行目
Dim i As Long
For i = LBound(data) To UBound(data)
Debug.Print data(i)
Next i
End Sub
📚 用語解説
ReDim(配列の再定義):VBAで動的配列のサイズを実行時に変更するキーワード。事前に要素数が分からない場合に使う。ReDim arr(1 To 10)で1〜10の要素を持つ配列を作成。既存のデータを保持しながらサイズを変えたい場合はReDim Preserveを使う。
VBAでは配列型(Long()やString())を戻り値型として直接指定しても動作しますが、呼び出し元での受け取りが複雑になります。As Variantで受け取る方が柔軟で、LBound/UBoundでのサイズ確認もそのまま使えるため実務では推奨されます。
08 ERROR HANDLING エラーハンドリング(On Error GoTo) 本番で使えるFunctionはエラー処理がセットになっている
実務で使うVBA Functionは、エラー処理が必須です。引数に不正な値が渡された・ファイルが見つからない・ゼロ除算が発生した——こういったケースでVBAがクラッシュしないようにするのがOn Error GoTo構文です。
'ゼロ除算エラーを安全に処理するFunction
Function SafeDivide(numerator As Double, denominator As Double) As Variant
On Error GoTo ErrorHandler
If denominator = 0 Then
SafeDivide = "ERROR: ゼロ除算"
Exit Function
End If
SafeDivide = numerator / denominator
Exit Function '★ 正常終了時はここでExitしてErrorHandlerを飛ばす
ErrorHandler:
SafeDivide = "ERROR: " & Err.Number & " - " & Err.Description
End Function
'呼び出し側
Sub TestSafeDivide()
Debug.Print SafeDivide(10, 3) '→ 3.33...
Debug.Print SafeDivide(10, 0) '→ ERROR: ゼロ除算
End Sub
📚 用語解説
On Error GoTo ラベル:VBAのエラーハンドリング構文。エラーが発生したとき、指定したラベル(ErrorHandler:など)の行にジャンプして処理を続ける。On Error Resume Next(エラーを無視)は使わないのが原則——バグを隠蔽して後から大きな問題になることが多い。
8-1. エラーハンドリングの標準テンプレート
実務でのFunctionエラー処理は、以下のテンプレートに沿って書くと抜け漏れが防げます。
Function YourFunction(arg1 As String) As Variant
On Error GoTo ErrorHandler '1. 先頭でエラーハンドラを設定
'2. 引数チェック(事前条件)
If arg1 = "" Then
YourFunction = Null 'または False / "" など
Exit Function
End If
'3. 本処理
YourFunction = DoSomething(arg1)
Exit Function '4. 正常終了(ErrorHandlerをスキップ)
ErrorHandler: '5. エラー発生時のみここに来る
Debug.Print "エラー in YourFunction: " & Err.Number & " " & Err.Description
YourFunction = Null 'エラー時の戻り値を明示
End Function
8-2. エラーの種類と対処パターン
| エラーの種類 | Err.Number | 対処方法 |
|---|---|---|
| 型の不一致(文字列に数値計算) | 13 | 引数をチェックして事前に弾く |
| インデックスが配列範囲外 | 9 | LBound/UBoundで範囲確認してから処理 |
| オブジェクト変数がNot Set | 91 | Is Nothingでチェックしてから使う |
| ゼロ除算 | 11 | 分母が0でないかを処理前に確認 |
| ファイルが見つからない | 53 | Dir()関数でファイル存在確認してから開く |
On Error Resume Nextはエラーを無視して次の行に進むため、問題のある行が何の表示もなくスキップされてしまいます。デバッグが非常に困難になり、データ破損のリスクもあります。特別な理由がない限りOn Error GoToを使い、エラーは必ず検知・記録してください。
09 PRACTICAL EXAMPLES Functionを組み合わせた実務Excel自動化 請求書・売上集計・在庫管理での実践パターン
ここまで学んだFunctionの知識を組み合わせた、実務で使える自動化の例を3つ紹介します。
9-1. 請求書の税込金額計算と書式設定を自動化する
請求書の明細行(商品名・単価・数量・税率)を読んで、税込金額を計算してセルに書き込む処理です。複数のFunctionを組み合わせて使います。
'税込金額計算Function
Function CalcTaxIncluded(unitPrice As Long, qty As Long, taxRate As Double) As Long
CalcTaxIncluded = CLng(unitPrice * qty * (1 + taxRate))
End Function
'金額を「¥1,000」形式にフォーマットするFunction
Function FormatYen(amount As Long) As String
FormatYen = "¥" & Format(amount, "#,##0")
End Function
'請求書の明細を一括処理するSub(Functionを呼び出す)
Sub ProcessInvoice()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("請求書")
Dim i As Long
For i = 5 To 20 '5行目〜20行目を処理
Dim unitPrice As Long
Dim qty As Long
unitPrice = ws.Cells(i, 3).Value 'C列: 単価
qty = ws.Cells(i, 4).Value 'D列: 数量
If unitPrice > 0 And qty > 0 Then
Dim taxIncluded As Long
taxIncluded = CalcTaxIncluded(unitPrice, qty, 0.1)
ws.Cells(i, 5).Value = FormatYen(taxIncluded) 'E列に書き込み
End If
Next i
MsgBox "請求書の計算が完了しました。"
End Sub
9-2. 売上データの月別集計を自動化する
売上記録シートから特定月のデータだけを抽出・合計するFunctionを作り、月次レポートの自動生成に使います。
'指定月の売上合計を返すFunction
Function SumSalesByMonth(ws As Worksheet, targetYear As Integer, targetMonth As Integer) As Long
On Error GoTo ErrorHandler
Dim total As Long
total = 0
Dim lastRow As Long
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
Dim i As Long
For i = 2 To lastRow
Dim cellDate As Date
cellDate = CDate(ws.Cells(i, 1).Value) 'A列: 日付
If Year(cellDate) = targetYear And Month(cellDate) = targetMonth Then
total = total + ws.Cells(i, 3).Value 'C列: 売上金額
End If
Next i
SumSalesByMonth = total
Exit Function
ErrorHandler:
Debug.Print "SumSalesByMonth エラー: " & Err.Description
SumSalesByMonth = -1 'エラー時は-1を返す
End Function
'月次レポートシートに集計結果を書き込むSub
Sub GenerateMonthlyReport()
Dim salesWs As Worksheet
Dim reportWs As Worksheet
Set salesWs = ThisWorkbook.Sheets("売上記録")
Set reportWs = ThisWorkbook.Sheets("月次レポート")
Dim m As Integer
For m = 1 To 12
Dim total As Long
total = SumSalesByMonth(salesWs, 2026, m)
reportWs.Cells(m + 1, 2).Value = IIf(total >= 0, total, "エラー")
Next m
MsgBox "月次レポートを作成しました。"
End Sub
9-3. 在庫アラート判定を自動化する
在庫数が発注点を下回ったとき、アラートフラグを立てて色を変える処理です。判定ロジックをFunctionに切り出すことで、判定基準の変更が1箇所で完結します。
'在庫アラート判定Function
Function IsLowStock(currentStock As Long, reorderPoint As Long) As Boolean
IsLowStock = (currentStock <= reorderPoint)
End Function
'在庫シートの全行にアラート色を適用するSub
Sub ApplyStockAlert()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("在庫管理")
Dim lastRow As Long
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
Dim i As Long
For i = 2 To lastRow
Dim stock As Long
Dim reorder As Long
stock = ws.Cells(i, 3).Value 'C列: 現在庫数
reorder = ws.Cells(i, 4).Value 'D列: 発注点
If IsLowStock(stock, reorder) Then
ws.Rows(i).Interior.Color = RGB(255, 200, 200) '赤背景
ws.Cells(i, 5).Value = "要発注"
Else
ws.Rows(i).Interior.ColorIndex = xlNone '色なし
ws.Cells(i, 5).Value = ""
End If
Next i
MsgBox "在庫チェック完了 (" & (lastRow - 1) & "件処理)"
End Sub
IsLowStockというFunctionに判定ロジックを分離することで、「発注点の計算方法が変わった」「安全在庫係数を加味したい」という仕様変更も、Functionだけを修正すれば完結します。Subに判定ロジックを直書きしていたら、複数の場所を探して直す必要があります。
10 GENAI CASE STUDY 【独自データ】GENAI実運用での業務自動化効果 VBAとAIを組み合わせた弊社の実務データを公開
ここでは、弊社(株式会社GENAI)で実際にVBAを活用している業務自動化の状況と、AIと組み合わせた効果について実データを公開します。
10-1. 弊社でVBAを活用している業務一覧
| 業務 | VBAでの自動化内容 | 削減工数(月) |
|---|---|---|
| 経費精算 | 経費データ→仕訳フォーマット変換→freeeインポート用CSV生成 | 月8時間 → 月30分 |
| 売上集計 | 複数シートの売上を月次・担当者別に自動集計 | 月4時間 → 月5分 |
| 在庫管理 | 発注点アラート・発注書自動生成・仕入先メール草案 | 週3時間 → 週20分 |
| 顧客リスト整備 | 重複除去・電話番号正規化・都道府県コード付与 | 月6時間 → 月10分 |
| 請求書処理 | 明細入力→税込計算→PDF出力→ファイル命名の一括処理 | 月10時間 → 月1時間 |
これらの自動化では、Functionで処理を部品化したことが保守性向上に大きく貢献しました。例えば消費税率の変更(軽減税率の対応など)も、CalcTax系のFunctionを修正するだけで全てのシートに反映できる設計になっています。
10-2. VBAとAI(Claude Code)の組み合わせ効果
人間が
要件整理
Claude Codeが
コードを書く
人間がレビュー
バグ修正依頼
VBAが
自動実行
弊社では「VBAのコーディング作業そのもの」をClaude Codeに任せることで、VBAの開発コストをさらに8割削減しています。以前は「VBAが書ける社員」がボトルネックでしたが、AIにコード生成を任せることで、VBAの知識がなくてもマクロを作れる体制が整いました。
| 項目 | 導入前(VBA手書き) | 導入後(AI+VBA) |
|---|---|---|
| 新規マクロ作成時間 | 1本あたり4〜8時間 | 1本あたり30〜60分 |
| 修正・保守コスト | VBAが分かる人しか触れない | 要件を日本語で伝えれば修正できる |
| ドキュメント作成 | 後回しになりがち | AIがコードと同時にコメント・説明を生成 |
| エラーハンドリング | 手動で追加(忘れることも多い) | AIが最初からテンプレートで組み込む |
11 AI CODE GENERATION Claude CodeにVBA Functionを書かせる方法 非エンジニアでも翌日には動くマクロが手に入る
ここまでVBA Functionの知識を詳しく解説してきましたが、最後に「その知識を持った上で、AIにコードを書かせる方法」をお伝えします。これが2026年現在の最速の実務活用法です。
Claude CodeはAnthropicが提供するAIエージェントで、ターミナル(コマンドライン)上でコードを書いて・テストして・修正することを自律的に実行します。VBAのコード生成も得意としており、「こういう処理をVBAで書いて」という日本語の指示だけで、動くコードを出力できます。
11-1. Claude CodeへのVBAプロンプトの書き方
AIにVBAを書かせる際のポイントは、「どのシートの・どの列の・何を・どう処理するか」を具体的に伝えることです。以下のプロンプトテンプレートを参考にしてください。
【シート名・構造】シート「売上記録」のA列に日付、B列に担当者名、C列に売上金額が入っています(2行目からデータ)。
【やりたいこと】特定の月(例: 2026年7月)の売上合計を担当者別に集計して、「月次集計」シートのB列に書き込みたい。
【条件】エラーハンドリング付き・処理完了後にメッセージボックス表示・コメント多めで。
【スタイル】Functionで集計ロジックを切り出して、SubからFunctionを呼ぶ設計で。
このように「構造・目的・条件・設計方針」を揃えると、Claude Codeは即座に動くVBAコードを生成します。さらに「これを修正して・エラーを直して・コメントを追加して」という追加指示にも自然に対応します。
11-2. AIが生成したVBAコードを自分でレビューするポイント
AIが生成したコードをそのまま本番に使う前に、以下の点を確認してください。
本番データに適用する前に、必ずコピーシートやテスト用ブックで動作確認してください。VBAは元に戻せない破壊的操作(セルの上書き・シートの削除など)もできてしまうため、「テストで完全に動くことを確認してから本番」が鉄則です。
11-3. VBAをAIに任せるべき業務と、自分で書くべき業務
| 業務 | AIに任せる | 自分で書く |
|---|---|---|
| 繰り返しの定型処理(集計・変換・整形) | ◎ 任せる | △ 時間の無駄 |
| 業務固有のロジック(判定ルール・フラグ管理) | ○ プロンプトに条件を詳細に書く | ○ どちらでも |
| 既存VBAの読解・デバッグ | ◎ エラー原因を貼り付けるだけ | △ 時間がかかる |
| セキュリティ・認証関連の処理 | △ 確認が必要 | ○ 自分でレビュー推奨 |
| 小さな1行の修正 | △ プロンプトを書く方が遅い | ◎ 自分で直接修正 |
11-4. AI鬼管理で業務自動化を加速する
「VBAは理解できた。でも実際に自社の業務にどう適用すればいいか分からない」——そういった方には、弊社のAI鬼管理サービスをご活用ください。
AI鬼管理では、Claude CodeとVBAを組み合わせた業務自動化の設計から実装・運用まで伴走支援しています。「この業務をどこから自動化すればいいか」という相談から始められます。まずは無料相談から、自社の業務で最もインパクトが大きい自動化ポイントを一緒に見つけましょう。
VBAとClaude Codeを組み合わせた業務自動化、AI鬼管理が設計します
ExcelマクロのVBA設計から、Claude Codeによるコード生成・テスト・運用まで、実務ベースで伴走します。
「まず1つの業務を自動化したい」というご相談から承ります。
NEXT STEP
この記事の内容を、あなたのビジネスで
実践してみませんか?
AI活用を自社で回せるようになりたい方へ
AI鬼管理
Claude Code・Cowork導入支援から業務設計・社内浸透まで実践ベースで伴走。「自社で回せる組織」を90日で作る経営者向けトレーニング。
よくある質問
Q. VBA FunctionとSubはどちらを先に覚えるべきですか?
A. まずSubを覚えて、マクロの基本動作(セル操作・繰り返し・条件分岐)に慣れてから、Functionを覚えるのが自然な順番です。コードが増えてきて「同じ処理を何度も書いている」と感じたタイミングがFunctionの学習適期です。
Q. FunctionはExcelのシート上の数式からも呼べますか?
A. はい、標準モジュールに書いたFunctionは、Excelのシートで「=関数名(引数)」の形式で呼び出せます(ユーザー定義関数・UDF)。ただし、シートのセルを変更する操作をFunctionの中に書くとエラーになるため、「計算して値を返すだけ」の純粋な関数として設計する必要があります。
Q. ByValとByRefはどちらを使う場面が多いですか?
A. ByValの方が圧倒的に多いです。「引数に渡した変数を関数内で変えてしまう」という副作用はバグの温床になるため、特別な理由がない限りByValを使います。VBAはデフォルトがByRefなので、意識的にByValを明示する習慣をつけることを推奨します。
Q. FunctionはFunction内から他のFunctionを呼び出せますか?
A. はい、Functionの中から別のFunctionを呼び出すことができます(再帰呼び出し自身を呼ぶことも可能)。呼び出す順番は、呼ばれるFunctionが先に定義されている必要はなく、同じモジュール内・別モジュールにあるFunctionも呼べます。
Q. Functionから配列を返すとき、データ型は何を使えばよいですか?
A. Variant型を推奨します。Long()やString()など具体的な配列型で宣言することも技術的には可能ですが、Variantで受け取る方が柔軟でLBound/UBoundなどの配列操作関数がそのまま使えます。大量データ処理でパフォーマンスを重視する場合は型付き配列も検討してください。
Q. エラーハンドリングでOn Error Resume Nextを使ってはいけないのですか?
A. 絶対NG、ではありませんが極力避けてください。On Error Resume Nextはエラーを無視して次の行に進むため、データが壊れていても気づかずに処理が続いてしまいます。デバッグも困難になります。どうしても使う場合は、使った直後にErr.Numberでエラー確認し、On Error GoTo 0でリセットするのが最低限のルールです。
Q. Claude CodeはVBAコードを書く精度はどのくらいですか?
A. 2026年現在、Claude CodeはExcelの標準的なVBA処理であれば高精度でコードを生成できます。「シートのデータを集計する」「条件に合う行を色分けする」「CSVをインポートして整形する」といった定型処理は、プロンプトを正確に書けば1〜2回のやり取りで動くコードが出てきます。ただし、必ずテスト環境で動作確認してから本番適用してください。
Claude Codeで業務自動化を90日で叩き込む
経営者向けの伴走型パーソナルトレーニング
Claude Code を業務に落とし込む
専門研修コース一覧
受講者本人の業務を題材に、「使いこなせる」状態になるまで伴走する研修プログラム。1対1特化型・ハンズオン・法人講座の3コースを展開中。業務特化・実装まで踏み込むタイプのClaude Code研修です。
研修コース一覧を見る →AI鬼管理へのお問い合わせ
この記事を読んで気になった方へ。
AI鬼管理の専門スタッフが、御社に最適な
業務自動化プランを無料でご提案します。




