「VBAを書ける人が社内にいない」「ネットでコードを拾ってきて動かしているけど、意味はよく分かっていない」——そんなことは少なくないと思います。プログラミング経験がなくても大丈夫です。
最近はAIチャットに日本語でやりたいことを伝えるだけで、そこそこ動くVBAコードが返ってくるようになりました。私も正直なところ、ここ1年くらいはVBAを自力で1から書く機会が激減しています。
この記事では、AnthropicのAIチャット「Claude」を使って、実務で使えるExcel VBAを効率的に書かせる方法を紹介します。プロンプト(指示文)の書き方にはコツがあるので、「型」として整理しました。
Claude(AI)でVBAを書く準備
ClaudeはAnthropic社が開発したAIアシスタントです。ChatGPTの競合にあたるサービスで、無料プランでも利用できます。特にコード生成の精度が高く、VBAのような業務系コードとの相性が良いです。
本記事ではClaude(claude.ai)のチャット画面を使う前提で進めます。アカウント作成は無料で、メールアドレスまたはGoogleアカウントですぐに始められます。

良いVBAを書かせるプロンプトの型
Claudeに限らず、AIにコードを書かせるときは「何を伝えるか」で出力の質が大きく変わります。以下の3点を押さえれば、実用レベルのVBAが返ってくる確率がかなり上がります。
① やりたいことを日本語で具体的に書く
一番多い失敗は、指示が曖昧すぎることです。
悪い例:
Excelで売上を集計するVBAを書いて
これだと、どのシートの、どの範囲の、何を基準に集計するのかが分かりません。Claudeは「それっぽいコード」を返してくれますが、そのまま使えることはまずないです。
良い例:
シート「売上データ」のA列〜E列に、以下の形式でデータが入っています。
A列:日付(yyyy/mm/dd)
B列:顧客名
C列:商品名
D列:数量
E列:金額
このデータを月別に集計し、新しいシート「月別集計」に
A列:年月(yyyy/mm)、B列:合計金額
の形式で出力するVBAを書いてください。
「何が」「どこに」「どんな形で」あるかを書くだけで、出力の質が劇的に変わります。
② データの形を伝える
VBAはExcelのシート構造に強く依存します。そのため、シート名・列構成・ヘッダ行の有無・データの開始行などを伝えることが重要です。
可能であれば、サンプルデータを数行そのまま貼り付けるのが最も確実です。
データのサンプル(2行目〜がデータ、1行目はヘッダ):
日付 | 顧客名 | 商品名 | 数量 | 金額
2025/01/05 | 山田商事 | 部品A | 10 | 50000
2025/01/12 | 鈴木工業 | 部品B | 5 | 30000
2025/02/03 | 山田商事 | 部品A | 20 | 100000
③ 出力形式を指定する
何も言わないと、Claudeは最低限のコードだけを返すことがあります。以下のような指定を付け加えると、実務で使いやすいコードになります。
- 「コードには日本語でコメントを付けてください」
- 「エラー処理(On Error)を含めてください」
- 「処理完了後にメッセージボックスを表示してください」
- 「既存の集計シートがあれば一度クリアしてから書き込んでください」
実例:請求書シートから月別売上集計VBAを作る
ここからは、実際にClaudeとやり取りして1本のVBAマクロを完成させる流れを見ていきます。
プロンプト全文
以下のプロンプトをClaudeに送ります。そのままコピペして使えます。

Excel VBAを書いてください。
【やりたいこと】
シート「売上データ」にある売上明細を、月ごとに集計して
新しいシート「月別集計」に出力したい。
【売上データの構造】
- 1行目:ヘッダ行
- A列:日付(yyyy/mm/dd形式)
- B列:顧客名(テキスト)
- C列:商品名(テキスト)
- D列:数量(整数)
- E列:金額(整数)
- データは2行目から、最終行まで可変
【出力の形式】
- シート「月別集計」に出力(なければ新規作成、あれば中身をクリアして再作成)
- A列:年月(yyyy/mm)
- B列:合計金額
- 1行目はヘッダ、2行目からデータ
- 年月の昇順で並べる
【その他の要件】
- 日本語でコメントを付けてください
- エラー処理を含めてください
- 処理完了後に「集計が完了しました」とメッセージボックスを表示してください
- 画面更新を一時停止して処理速度を上げてください
Claudeの回答(生成コード)
上記のプロンプトを送ると、Claudeは以下のようなコードを返してくれました。

Option Explicit
Sub 月別集計()
' -------------------------------------------------------
' 定数・変数の宣言
' -------------------------------------------------------
Const SRC_SHEET As String = "売上データ"
Const DEST_SHEET As String = "月別集計"
Dim wsSource As Worksheet
Dim wsDest As Worksheet
Dim lastRow As Long
Dim i As Long
Dim dateVal As Date
Dim yearMonth As String
Dim amount As Long
' 年月をキー、合計金額を値として保持するコレクション
Dim dictKeys() As String ' 年月一覧
Dim dictVals() As Long ' 対応する合計金額
Dim dictCount As Long
Dim found As Boolean
Dim j As Long
' -------------------------------------------------------
' 画面更新・自動計算を一時停止(処理高速化)
' -------------------------------------------------------
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
' -------------------------------------------------------
' エラーハンドラの設定
' -------------------------------------------------------
On Error GoTo ErrorHandler
' -------------------------------------------------------
' ソースシートの存在確認
' -------------------------------------------------------
Dim wsCheck As Worksheet
Dim srcExists As Boolean
srcExists = False
For Each wsCheck In ThisWorkbook.Worksheets
If wsCheck.Name = SRC_SHEET Then
srcExists = True
Exit For
End If
Next wsCheck
If Not srcExists Then
MsgBox "シート「" & SRC_SHEET & "」が見つかりません。", vbExclamation
GoTo CleanUp
End If
Set wsSource = ThisWorkbook.Worksheets(SRC_SHEET)
' -------------------------------------------------------
' ソースシートの最終行を取得
' -------------------------------------------------------
lastRow = wsSource.Cells(wsSource.Rows.Count, "A").End(xlUp).Row
If lastRow < 2 Then
MsgBox "「" & SRC_SHEET & "」にデータがありません。", vbExclamation
GoTo CleanUp
End If
' -------------------------------------------------------
' 出力先シートの準備
' (存在すれば中身をクリア、なければ新規作成)
' -------------------------------------------------------
Dim destExists As Boolean
destExists = False
For Each wsCheck In ThisWorkbook.Worksheets
If wsCheck.Name = DEST_SHEET Then
destExists = True
Exit For
End If
Next wsCheck
If destExists Then
Set wsDest = ThisWorkbook.Worksheets(DEST_SHEET)
wsDest.Cells.Clear ' 既存データをすべてクリア
Else
' シートを末尾に追加
Set wsDest = ThisWorkbook.Worksheets.Add(After:=ThisWorkbook.Worksheets(ThisWorkbook.Worksheets.Count))
wsDest.Name = DEST_SHEET
End If
' -------------------------------------------------------
' 配列の初期化(最大行数分を確保)
' -------------------------------------------------------
dictCount = 0
ReDim dictKeys(1 To lastRow)
ReDim dictVals(1 To lastRow)
' -------------------------------------------------------
' 売上データを1行ずつ読み込み、月ごとに集計
' -------------------------------------------------------
For i = 2 To lastRow
' 日付セルが空の行はスキップ
If IsEmpty(wsSource.Cells(i, "A").Value) Then GoTo NextRow
' 日付として読み取れない値はスキップ
If Not IsDate(wsSource.Cells(i, "A").Value) Then GoTo NextRow
' 金額が数値でない行はスキップ
If Not IsNumeric(wsSource.Cells(i, "E").Value) Then GoTo NextRow
dateVal = CDate(wsSource.Cells(i, "A").Value)
yearMonth = Format(dateVal, "yyyy/mm") ' 例:"2024/03"
amount = CLng(wsSource.Cells(i, "E").Value)
' 既存の年月キーを検索
found = False
For j = 1 To dictCount
If dictKeys(j) = yearMonth Then
dictVals(j) = dictVals(j) + amount ' 同じ月に加算
found = True
Exit For
End If
Next j
' 新しい年月の場合は追加
If Not found Then
dictCount = dictCount + 1
dictKeys(dictCount) = yearMonth
dictVals(dictCount) = amount
End If
NextRow:
Next i
' -------------------------------------------------------
' 年月の昇順バブルソート
' -------------------------------------------------------
Dim tempKey As String
Dim tempVal As Long
Dim k As Long
For i = 1 To dictCount - 1
For k = 1 To dictCount - i
If dictKeys(k) > dictKeys(k + 1) Then
' キーの入れ替え
tempKey = dictKeys(k)
dictKeys(k) = dictKeys(k + 1)
dictKeys(k + 1) = tempKey
' 値の入れ替え
tempVal = dictVals(k)
dictVals(k) = dictVals(k + 1)
dictVals(k + 1) = tempVal
End If
Next k
Next i
' -------------------------------------------------------
' 出力先シートへ書き込み
' -------------------------------------------------------
' ヘッダ行
With wsDest
.Cells(1, "A").Value = "年月"
.Cells(1, "B").Value = "合計金額"
' ヘッダの書式設定
.Range("A1:B1").Font.Bold = True
.Range("A1:B1").Interior.Color = RGB(68, 114, 196) ' 青系の背景
.Range("A1:B1").Font.Color = RGB(255, 255, 255) ' 白文字
' データ行の出力
For i = 1 To dictCount
.Cells(i + 1, "A").Value = dictKeys(i)
.Cells(i + 1, "B").Value = dictVals(i)
' 金額列に通貨書式を適用
.Cells(i + 1, "B").NumberFormat = "#,##0"
Next i
' 列幅を自動調整
.Columns("A:B").AutoFit
End With
' -------------------------------------------------------
' 完了メッセージ
' -------------------------------------------------------
MsgBox "集計が完了しました。" & vbCrLf & _
"集計月数:" & dictCount & " ヶ月", vbInformation
CleanUp:
' -------------------------------------------------------
' 画面更新・自動計算を元に戻す
' -------------------------------------------------------
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Exit Sub
ErrorHandler:
' -------------------------------------------------------
' エラー発生時の処理
' -------------------------------------------------------
MsgBox "エラーが発生しました。" & vbCrLf & _
"エラー番号:" & Err.Number & vbCrLf & _
"内容:" & Err.Description, vbCritical
Resume CleanUp
End Sub
こちらの指示に対して、かなりしっかりしたコードが返ってきました。ポイントを補足します。
- Option Explicitが先頭にあります。変数の宣言漏れをコンパイル時に検出してくれるので、VBAでは基本的に付けるべき宣言です。
- Constでシート名を定数化しています。シート名を変更したい場合、コード冒頭の2行を変えるだけで済みます。
- ソースシートの存在確認が入っています。シート名が間違っていた場合でも「実行時エラー」ではなくメッセージボックスで知らせてくれます。
- バリデーションが3段階(空セル・非日付・非数値)で入っています。実務データにありがちな不備があってもエラーで止まりません。
- 外部ライブラリ(Scripting.Dictionary等)を使わず、配列だけで集計しています。環境を選ばずどのPCでも動きます。
- ヘッダに書式設定(太字・青背景・白文字)まで入っています。見た目も整った状態で出力されます。
- On Error GoTo + CleanUpパターンで、エラー時にも画面更新の復元が確実に行われます。
プロンプトで「日本語コメント」「エラー処理」「メッセージボックス」「画面更新の停止」を指定したとおりに、すべて反映されていることが分かります。
実行結果と微調整



コードをVBE(Alt+F11で開きます)の標準モジュールに貼り付けて実行すると、「月別集計」シートが作成され、年月ごとの合計金額が出力されます。ヘッダ行には青背景・白文字の書式も自動で適用されます。
もし「顧客別にも集計したい」となった場合は、追加のプロンプトを送るだけで対応できます。
ありがとうございます。追加の要件です。
先ほどのコードをベースに、以下の変更を加えてください。
- 集計軸を「年月」×「顧客名」のクロス集計に変更
- 月別集計シートのA列:年月、B列:顧客名、C列:合計金額
- 年月→顧客名の順で昇順ソート

このように、最初のコードをベースに段階的に要件を追加していくのが、Claudeとの効率的な作業の進め方です。一度に全部を伝えようとするより、まず基本形を作って→動作確認→追加要件、という流れのほうが精度が高くなります。
うまくいかない時の対処法
Claudeが返すコードが期待通りに動かないこともあります。その場合は以下の手順で対処します。
1. エラーメッセージをそのまま貼る
VBEに表示されるエラー番号とメッセージをそのままClaudeに送ります。
実行したら以下のエラーが出ました。修正してください。
実行時エラー '9':
インデックスが有効範囲にありません。
2. どの行でエラーが出たか伝える
デバッグで黄色くハイライトされた行を伝えると、原因の特定が早くなります。
以下の行で止まりました。
Set wsSource = ThisWorkbook.Worksheets(SRC_SHEET)
シート名は「売上データ一覧」でした。
ちなみに今回のコードでは、ソースシートが見つからない場合はエラーで止まらず「シート『売上データ』が見つかりません。」とメッセージが出る設計になっています。こういった防御的なコードをAIが自動で入れてくれるのも、大きなメリットです。
3. 要件が大きすぎたら分割する
一つのプロンプトに盛り込みすぎると、コードが複雑になってエラーも増えます。「まず集計だけ」「次に書式設定」「最後にグラフ作成」のように分割するのがコツです。
Claudeに聞く vs 自力で書く、使い分けの目安
万能ではないので、正直に使い分けの目安を書いておきます。
Claudeが得意なこと
- 定型的なデータ処理(集計、転記、整形、CSV出力など)
- 既存コードの解説・リファクタリング
- エラーの原因調査
- 「こういうことがしたいけど、どの関数を使えばいいか分からない」系の相談
自力のほうが良いケース
- 社内独自のブック構成に強く依存する処理(説明コストが高い)
- UIフォーム(UserForm)の細かいレイアウト調整
- 既に動いているコードの小さな修正(自分で直したほうが早い)
- 機密データを含むシートの構造を外部に伝えられない場合
特に最後の点は重要です。Claudeに送った情報はAnthropicのサーバーを経由します。機密性の高いデータそのものは送らず、構造やダミーデータで伝えるようにしましょう。
まとめ
- ClaudeにVBAを書かせるコツは「①やりたいこと」「②データの形」「③出力形式」の3点を具体的に伝えることです
- 一度に完璧を目指さず、基本形を作って→動確→追加要件の流れが効率的です
- エラーが出たらメッセージをそのまま貼れば、大抵は修正コードが返ってきます
- 機密データそのものは送らないこと。構造とダミーデータで伝えましょう
VBAを書ける人が社内にいなくても、AIに「何がしたいか」を伝えるスキルがあれば、かなりの範囲をカバーできる時代になりました。まずは簡単な集計処理あたりから試してみてください。
※本記事のコードはExcel 2016以降(Microsoft 365含む)で動作確認しています。
以上、ご参考になれば幸いです。


コメント