ClaudeでExcel VBAを書かせる実践ガイド — プロンプトの型と実例

EXCEL
この記事は約18分で読めます。
スポンサーリンク

「VBAを書ける人が社内にいない」「ネットでコードを拾ってきて動かしているけど、意味はよく分かっていない」——そんなことは少なくないと思います。プログラミング経験がなくても大丈夫です。

最近はAIチャットに日本語でやりたいことを伝えるだけで、そこそこ動くVBAコードが返ってくるようになりました。私も正直なところ、ここ1年くらいはVBAを自力で1から書く機会が激減しています。

この記事では、AnthropicのAIチャット「Claude」を使って、実務で使えるExcel VBAを効率的に書かせる方法を紹介します。プロンプト(指示文)の書き方にはコツがあるので、「型」として整理しました。

スポンサーリンク

Claude(AI)でVBAを書く準備

ClaudeはAnthropic社が開発したAIアシスタントです。ChatGPTの競合にあたるサービスで、無料プランでも利用できます。特にコード生成の精度が高く、VBAのような業務系コードとの相性が良いです。

本記事ではClaude(claude.ai)のチャット画面を使う前提で進めます。アカウント作成は無料で、メールアドレスまたはGoogleアカウントですぐに始められます。

Claudeトップ画面

良いVBAを書かせるプロンプトの型

Claudeに限らず、AIにコードを書かせるときは「何を伝えるか」で出力の質が大きく変わります。以下の3点を押さえれば、実用レベルのVBAが返ってくる確率がかなり上がります。

① やりたいことを日本語で具体的に書く

一番多い失敗は、指示が曖昧すぎることです。

悪い例:

Claude
Excelで売上を集計するVBAを書いて

これだと、どのシートの、どの範囲の、何を基準に集計するのかが分かりません。Claudeは「それっぽいコード」を返してくれますが、そのまま使えることはまずないです。

良い例:

Claude
シート「売上データ」のA列〜E列に、以下の形式でデータが入っています。
A列:日付(yyyy/mm/dd)
B列:顧客名
C列:商品名
D列:数量
E列:金額

このデータを月別に集計し、新しいシート「月別集計」に
A列:年月(yyyy/mm)、B列:合計金額
の形式で出力するVBAを書いてください。

「何が」「どこに」「どんな形で」あるかを書くだけで、出力の質が劇的に変わります。

② データの形を伝える

VBAはExcelのシート構造に強く依存します。そのため、シート名・列構成・ヘッダ行の有無・データの開始行などを伝えることが重要です。

可能であれば、サンプルデータを数行そのまま貼り付けるのが最も確実です。

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に送ります。そのままコピペして使えます。

Claudeプロンプト入力

Claude
Excel VBAを書いてください。

【やりたいこと】
シート「売上データ」にある売上明細を、月ごとに集計して
新しいシート「月別集計」に出力したい。

【売上データの構造】
- 1行目:ヘッダ行
- A列:日付(yyyy/mm/dd形式)
- B列:顧客名(テキスト)
- C列:商品名(テキスト)
- D列:数量(整数)
- E列:金額(整数)
- データは2行目から、最終行まで可変

【出力の形式】
- シート「月別集計」に出力(なければ新規作成、あれば中身をクリアして再作成)
- A列:年月(yyyy/mm)
- B列:合計金額
- 1行目はヘッダ、2行目からデータ
- 年月の昇順で並べる

【その他の要件】
- 日本語でコメントを付けてください
- エラー処理を含めてください
- 処理完了後に「集計が完了しました」とメッセージボックスを表示してください
- 画面更新を一時停止して処理速度を上げてください

Claudeの回答(生成コード)

上記のプロンプトを送ると、Claudeは以下のようなコードを返してくれました。

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パターンで、エラー時にも画面更新の復元が確実に行われます。

プロンプトで「日本語コメント」「エラー処理」「メッセージボックス」「画面更新の停止」を指定したとおりに、すべて反映されていることが分かります。

実行結果と微調整

Claude生成コードをVBEに貼り付け

Excel売上データシート

Excel月別集計シート

コードをVBE(Alt+F11で開きます)の標準モジュールに貼り付けて実行すると、「月別集計」シートが作成され、年月ごとの合計金額が出力されます。ヘッダ行には青背景・白文字の書式も自動で適用されます。

もし「顧客別にも集計したい」となった場合は、追加のプロンプトを送るだけで対応できます。

Claude
ありがとうございます。追加の要件です。

先ほどのコードをベースに、以下の変更を加えてください。
- 集計軸を「年月」×「顧客名」のクロス集計に変更
- 月別集計シートのA列:年月、B列:顧客名、C列:合計金額
- 年月→顧客名の順で昇順ソート

Claude追加プロンプト

このように、最初のコードをベースに段階的に要件を追加していくのが、Claudeとの効率的な作業の進め方です。一度に全部を伝えようとするより、まず基本形を作って→動作確認→追加要件、という流れのほうが精度が高くなります。

うまくいかない時の対処法

Claudeが返すコードが期待通りに動かないこともあります。その場合は以下の手順で対処します。

1. エラーメッセージをそのまま貼る

VBEに表示されるエラー番号とメッセージをそのままClaudeに送ります。

Claude
実行したら以下のエラーが出ました。修正してください。

実行時エラー '9':
インデックスが有効範囲にありません。

2. どの行でエラーが出たか伝える

デバッグで黄色くハイライトされた行を伝えると、原因の特定が早くなります。

Claude
以下の行で止まりました。
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含む)で動作確認しています。

以上、ご参考になれば幸いです。

コメント

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