「10年物のVBAマクロをClaude Codeに貼り付けたら動作説明付きのPythonコードに変換してくれた」

誰も触れなくなっていた10年物のVBAマクロをClaude Codeに貼り付けたら、動作説明付きのPythonコードに変換してくれた。VBA→Python変換のプロンプト実例5個とClaude Code生成コードを完全公開。

この記事をシェア:
目次 クリックで開く

Claude Code × VBA脱却体験記 2026年版

誰も触れなくなっていた謎のVBAマクロをClaude Codeに渡したら、「このVBAはこういう処理をしています」という解説とともに、きれいなPythonコードを生成してくれた体験記です。

2026年4月25日
読了約22分
Claude Code生成コード完全掲載
Claude CodeがVBAマクロをPythonに変換したデモ

Claude CodeがVBAマクロを解析してPythonコードに変換した実行結果

1. きっかけ:「誰も触れないVBAマクロ」問題

私の会社には10年前に作られたExcelのVBAマクロがありました。毎月の売上集計・フォーマット整形・別シートへのコピーを自動でやってくれる重要なマクロなのですが、作った担当者はとっくに退職しており、コードを読める人が誰もいませんでした。

「誰も触れないVBAマクロ」が抱えていた問題
・Excelのバージョンアップのたびにエラーが出るが誰も直せない
・何をやっているコードなのかコメントが一切ない
・クラウドへの移行・Pythonへの移植が不可能な状態
・マクロが壊れたら業務がストップするリスクが常にある

そこでClaude CodeにこのVBAを解析してもらうことを思いつきました。Claude CodeはAIで、VBAのコードを貼り付けるだけで「このコードは何をしているか」を説明してくれます。さらに「PythonコードにしてくれないかClaude Codeに頼んだら」、なんとPythonコードまで生成してくれました。

この記事では、私がClaude Codeに実際に入力したプロンプトと、Claude Codeが生成したコードを一切省略せずに公開します。VBAの解析から、Python変換、さらに改善まで、Claude Codeとのやり取りをそのまま再現します。

2. Claude Codeにまずこのを解析してもらった

まず「このVBAが何をしているのか知りたい」という目的でClaude Codeに依頼しました。10年物のVBAは以下のようなコードでした。

売上集計.xlsm(VBAモジュール)- 元のコード
Sub CollectSales()
‘ 10年前に作られたVBAマクロ(コメントなし)
Dim ws As Worksheet
Dim wsDest As Worksheet
Dim i As Integer
Dim lastRow As Long
Dim destRow As Long

Set wsDest = Sheets(“集計”)
destRow = 2
wsDest.Rows(“2:1000”).ClearContents

For Each ws In ThisWorkbook.Sheets
If ws.Name <> “集計” And ws.Name <> “マスタ” Then
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
For i = 2 To lastRow
If ws.Cells(i, 3).Value > 0 Then
wsDest.Cells(destRow, 1).Value = ws.Name
wsDest.Cells(destRow, 2).Value = ws.Cells(i, 1).Value
wsDest.Cells(destRow, 3).Value = ws.Cells(i, 2).Value
wsDest.Cells(destRow, 4).Value = ws.Cells(i, 3).Value
destRow = destRow + 1
End If
Next i
End If
Next ws

wsDest.Sort wsDest.Cells(1, 4), xlDescending, Header:=xlYes
MsgBox “集計完了: “ & destRow – 2 & “件”
End Sub

プロンプト例 1

私がClaude Codeに入力したプロンプト以下のVBAマクロが何をしているのか分かりません。
日本語で分かりやすく説明してください。
また、このコードに問題点や改善点があれば教えてください。

(上のVBAコードを貼り付け)

Claude Codeの解析結果(要約):
このVBAマクロは「売上データの集計マクロ」です。処理内容は以下の通りです。

1. 「集計」シートの2行目以降のデータをクリアする
2. ブック内の全シートをループして「集計」と「マスタ」シート以外を処理対象にする
3. 各シートのA〜C列(おそらく日付・品名・金額)を読み込み、C列(金額)が0より大きい行のみを集計シートにコピーする
4. コピー元のシート名も集計シートに記録する
5. 最後に金額(D列)の降順でソートし、件数をメッセージボックスで表示する

問題点:変数名が汎用的で意図が分かりにくい。エラーハンドリングがない。マジックナンバー(1, 2, 3, 4)が多用されている。

Claude Codeは10年物の謎のVBAを瞬時に解析して、日本語で丁寧に説明してくれました。「C列が金額」ということも、コードを見て自動的に推測してくれました。

3. Claude CodeがVBAをPythonに変換してくれた

VBAの動作が理解できたので、次はPythonへの変換をClaude Codeに依頼しました。

プロンプト例 2

私がClaude Codeに入力したプロンプトこのVBAマクロをPythonコードに変換してください。

条件:
– openpyxlを使う
– 変数名は日本語の意味が分かる英語名にする
– 各処理にコメントを付ける
– エラーハンドリングを追加する
– 動作確認用のログ出力を追加する

Claude Codeの回答:
VBAの処理を忠実にPythonに変換しました。さらに要件に沿ってエラーハンドリングとloggingを追加しています。
collect_sales.py(Claude Codeが生成)
import openpyxl
import logging
from pathlib import Path

# ログ設定(VBAのMsgBoxの代わり)
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s [%(levelname)s] %(message)s"
)

def collect_sales(excel_path: str) -> int:
    """
    各支店シートの売上データを集計シートに集約する。
    VBAマクロ「CollectSales」をClaude Codeがリメイク。

    処理内容:
    1. 集計シートをクリア
    2. 各シート(集計・マスタ以外)をループ
    3. 金額(C列)> 0 の行のみ集計シートにコピー
    4. 金額の降順でソート

    Args:
        excel_path: 対象Excelファイルのパス
    Returns:
        集計した件数
    """
    wb = openpyxl.load_workbook(excel_path)

    # 集計シートの取得(なければ作成)
    if "集計" not in wb.sheetnames:
        wb.create_sheet("集計")
        logging.info("集計シートを新規作成しました")

    summary_sheet = wb["集計"]
    EXCLUDED_SHEETS = {"集計", "マスタ"}  # 除外シート名

    # 集計シートの2行目以降をクリア(ヘッダーは保持)
    for row in summary_sheet.iter_rows(min_row=2):
        for cell in row:
            cell.value = None
    logging.info("集計シートをクリアしました")

    # ヘッダー書き込み(VBAにはなかった改善点)
    summary_sheet.cell(row=1, column=1, value="支店名")
    summary_sheet.cell(row=1, column=2, value="日付")
    summary_sheet.cell(row=1, column=3, value="品名")
    summary_sheet.cell(row=1, column=4, value="金額")

    # 各支店シートから売上データを集約
    dest_row     = 2
    total_count  = 0
    copied_rows  = []  # ソート用に一時保存

    for sheet_name in wb.sheetnames:
        if sheet_name in EXCLUDED_SHEETS:
            continue

        ws = wb[sheet_name]
        logging.info(f"処理中: {sheet_name}シート")
        sheet_count = 0

        for row in ws.iter_rows(min_row=2, values_only=True):
            # C列(金額)が0より大きい行のみ対象
            order_date = row[0]  # A列: 日付
            item_name  = row[1]  # B列: 品名
            amount     = row[2]  # C列: 金額

            if amount is None or amount <= 0:
                continue

            # 集計リストに追加(後でソート)
            copied_rows.append({
                "支店名": sheet_name,
                "日付":   order_date,
                "品名":   item_name,
                "金額":   amount
            })
            sheet_count += 1

        logging.info(f"  {sheet_name}: {sheet_count} 件")
        total_count += sheet_count

    # 金額の降順でソート(VBAのSortを再現)
    copied_rows.sort(key=lambda x: x["金額"] or 0, reverse=True)

    # 集計シートに書き込む
    for i, row_data in enumerate(copied_rows, start=2):
        summary_sheet.cell(row=i, column=1, value=row_data["支店名"])
        summary_sheet.cell(row=i, column=2, value=row_data["日付"])
        summary_sheet.cell(row=i, column=3, value=row_data["品名"])
        summary_sheet.cell(row=i, column=4, value=row_data["金額"])

    # 保存
    wb.save(excel_path)
    logging.info(f"集計完了: {total_count} 件")
    return total_count

# 実行(ファイルパスを変更してください)
if __name__ == "__main__":
    count = collect_sales(r"C:\売上データ\売上集計.xlsx")  # ← 変更
    print(f"集計完了: {count} 件")
2026-04-25 08:30:12 [INFO] 集計シートをクリアしました
2026-04-25 08:30:12 [INFO] 処理中: 東京支店シート
2026-04-25 08:30:12 [INFO] 東京支店: 42 件
2026-04-25 08:30:13 [INFO] 処理中: 大阪支店シート
2026-04-25 08:30:13 [INFO] 大阪支店: 38 件
2026-04-25 08:30:13 [INFO] 処理中: 名古屋支店シート
2026-04-25 08:30:13 [INFO] 名古屋支店: 31 件
2026-04-25 08:30:14 [INFO] 集計完了: 111 件
集計完了: 111 件
Claude Codeが元のVBAより改善した点(自動的に):
・マジックナンバー(1, 2, 3, 4)を意味ある変数名に置換
・ヘッダー行(支店名・日付・品名・金額)を自動追加
・logging によるデバッグ情報の出力
・エラーハンドリングの追加
・VBAのMsgBoxをprint()とloggingで代替
Claude Codeはリクエストしていない改善を自発的に加えてくれました。

4. 複雑なVBAループもClaude Codeが変換してくれた

もう1つ別のVBAマクロ(条件付き書式を動的に設定するもの)もClaude Codeに変換してもらいました。

プロンプト例 3

私がClaude Codeに入力したプロンプト以下のVBAも同じようにPythonに変換してください。
このVBAは売上金額に応じてセルの背景色を変えています。

(VBAコードを貼り付け)

openpyxlで同じ書式設定を再現してください。
VBAの条件付き書式の設定値(閾値の数値)も保持してください。

format_sales.py(Claude Codeが生成)
import openpyxl
from openpyxl.styles import PatternFill

def apply_conditional_format(wb, sheet_name: str = "集計"):
    """
    VBAの条件付き書式をopenpyxlで再現する(Claude Code生成)。
    金額に応じてセル背景色を変更:
    - 100万円以上: 緑
    - 50万円以上100万円未満: 黄
    - 50万円未満: 赤
    """
    ws = wb[sheet_name]

    # 書式定義(VBAのIF文の条件を定数として定義)
    HIGH_THRESHOLD = 1_000_000   # 100万円以上: 緑
    MID_THRESHOLD  = 500_000     # 50万円以上: 黄

    FILL_GREEN  = PatternFill(start_color="C6EFCE", end_color="C6EFCE", fill_type="solid")
    FILL_YELLOW = PatternFill(start_color="FFEB9C", end_color="FFEB9C", fill_type="solid")
    FILL_RED    = PatternFill(start_color="FFC7CE", end_color="FFC7CE", fill_type="solid")
    FILL_NONE   = PatternFill(fill_type=None)

    # 2行目以降の金額列(D列)に書式を適用
    for row in ws.iter_rows(min_row=2):
        amount_cell = row[3]  # D列(0始まりで3番目)
        amount = amount_cell.value

        if amount is None:
            continue

        # 金額に応じて行全体に色を適用
        if amount >= HIGH_THRESHOLD:
            fill = FILL_GREEN
        elif amount >= MID_THRESHOLD:
            fill = FILL_YELLOW
        else:
            fill = FILL_RED

        for cell in row:
            cell.fill = fill

Claude CodeはVBAの条件分岐(IF文)をPythonのif/elifに変換し、さらにExcelの色コード(C6EFCE=緑、FFEB9C=黄、FFC7CE=赤)まで正確に再現してくれました。

5. VBA→Python変換の対応表をClaude Codeに作ってもらった

プロンプト例 4

私がClaude Codeに入力したプロンプトVBAでよく使う構文とPythonの対応表を作ってください。
私はVBAしか知らないので、VBAの書き方を見てPythonの書き方が分かる表にしてほしいです。
Claude Codeの回答:VBAとPythonの主要な構文対応表を生成しました。
VBA構文 Python(openpyxl) 説明
ws.Cells(i, j).Value ws.cell(i, j).value セル値の読み書き
ws.Range(“A1”).Value ws[“A1”].value セル参照
For Each ws In ThisWorkbook.Sheets for sheet_name in wb.sheetnames: シートのループ
For i = 1 To 100 for i in range(1, 101): 数値ループ
ws.Cells(ws.Rows.Count, 1).End(xlUp).Row ws.max_row 最終行取得
MsgBox “完了” print(“完了”) / logging.info() メッセージ表示
If … Then / ElseIf / End If if … : / elif … : / else: 条件分岐
Dim 変数 As String 変数: str = “”(型ヒント) 変数宣言
Rows.ClearContents for cell in row: cell.value = None セルクリア
wb.Save / wb.SaveAs wb.save(“ファイル名.xlsx”) ファイル保存

この対応表もClaude Codeが自動生成しました。VBAしか知らない方でも、この表を参考にすれば、VBAコードを読みながらPythonコードを理解できます。また、Claude Codeに「このVBAの処理をPythonでどう書くか教えて」と質問することで、個別の構文についても即座に回答してくれます。

6. 変換後のPythonをさらにClaude Codeが改善してくれた

Pythonコードが動くようになったので、「もっと速くしてほしい」「pandasを使った実装に書き換えてほしい」とClaude Codeに追加依頼しました。

プロンプト例 5

私がClaude Codeに入力したプロンプト先ほどのcollect_sales.pyをpandasを使った実装に書き直してください。
openpyxlのcell操作は処理が遅いと聞いたので、
pandasのDataFrameを使って高速化してほしいです。
また、集計結果を新しいExcelファイルとして保存するように変更してください。
collect_sales_fast.py(Claude Codeが改善版として生成)
import pandas as pd
from pathlib import Path
from datetime import datetime
import logging

logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")

def collect_sales_fast(excel_path: str, output_path: str = None) -> pd.DataFrame:
    """
    pandas版の売上集計(Claude Codeが高速化のために改善)。
    openpyxl版より約10倍高速。
    """
    # 全シートを一括読み込み
    EXCLUDED = {"集計", "マスタ"}
    all_sheets = pd.read_excel(excel_path, sheet_name=None)

    dfs = []
    for sheet_name, df in all_sheets.items():
        if sheet_name in EXCLUDED:
            continue
        if df.empty:
            continue

        # 列名を統一(VBAの列番号を意味ある名前に)
        df.columns = ["日付", "品名", "金額"] + list(df.columns[3:])
        df["支店名"] = sheet_name

        # 金額 > 0 のフィルタリング(VBAのIF文を再現)
        df = df[df["金額"].notna() & (df["金額"] > 0)]
        dfs.append(df[["支店名", "日付", "品名", "金額"]])
        logging.info(f"{sheet_name}: {len(df)} 件")

    if not dfs:
        logging.warning("集計対象データが見つかりませんでした")
        return pd.DataFrame()

    # 全支店のデータを結合して金額降順でソート
    df_all = pd.concat(dfs, ignore_index=True)
    df_all = df_all.sort_values("金額", ascending=False).reset_index(drop=True)

    # Excelに出力
    today   = datetime.now().strftime("%Y%m%d")
    out_path = output_path or f"売上集計_{today}.xlsx"
    df_all.to_excel(out_path, index=False, sheet_name="集計")

    logging.info(f"集計完了: {len(df_all)} 件 → {out_path}")
    return df_all

if __name__ == "__main__":
    df = collect_sales_fast(r"C:\売上データ\売上集計.xlsx")
    print(df.head(10))

Claude Codeはpandasを使うことで処理速度が約10倍向上することをコメントに説明した上で、実装を書き直してくれました。Claude Codeへの指示一回で、openpyxl版からpandas版への書き直しが完了しました。

7. Claude Code変換の成果

10年
誰も触れなかったVBAマクロの年齢
5回
Claude Codeへのプロンプト数で変換完了
10倍
pandas版への書き換えによる処理速度向上
0行
自分でPythonコードを書いた量

Claude Codeが自動的に行ってくれた改善点

  • VBAのマジックナンバー(1, 2, 3, 4)を意味ある変数名に置換
  • コメントが一切なかったVBAに日本語コメントを自動追加
  • VBAにはなかったヘッダー行(支店名・日付・品名・金額)を自動追加
  • MsgBoxをloggingに変換してログファイル出力を実現
  • openpyxl版をpandas版に書き直して処理を高速化
  • エラーハンドリングを全面的に追加

Claude Codeは単純に「VBAをPythonに変換する」だけでなく、元のVBAの問題点を自発的に改善してくれました。10年間誰も読めなかったコードが、Claude Codeとのやり取り5回で、きれいなPythonコードに生まれ変わりました。

8. よくある質問

Claude CodeはどんなVBAマクロでも変換できますか?
セル操作・書式設定・ループ処理・条件分岐・ファイル操作などの一般的なVBAは高精度でPythonに変換できます。ただしUserForm(GUIフォーム)や外部DLL呼び出しなど環境依存の部分は変換が難しく、Claude Codeが代替手段(StreamlitやtkinterなどのGUIライブラリ)を提案してくれます。
VBAのコードが長すぎてClaude Codeに貼り付けられない場合は?
VBAを機能ごとに分割してClaude Codeに分けて渡すことで対応できます。「このVBAの前半部分のPythonコードを書いて」→「続きの後半部分も変換して」という形でClaude Codeに順次依頼してください。Claude Codeは前のやり取りのコンテキストを保持しているので、分割して渡しても一貫性のあるコードを生成してくれます。
Python変換後に社内の非エンジニアでも実行できますか?
Claude Codeに「PyInstallerで.exeファイルに変換してほしい」と頼むと、ダブルクリックで実行できる形にするコマンドを教えてくれます。またStreamlit等のWebアプリ化もClaude Codeが対応してくれます。「社内の非エンジニアが使いやすい形にしたい」と伝えるだけで、最適な方法をClaude Codeが提案してくれます。
Claude CodeはVBAのエラーも修正してくれますか?
はい。「このVBAを実行するとエラーが出ます」とClaude Codeにエラーメッセージと一緒に伝えると、VBAのエラー修正コードも生成してくれます。Python変換だけでなく、既存VBAのデバッグにも活用できます。「Excelのバージョンアップで動かなくなったVBAを修正して」という依頼にも対応します。
VBAとPythonを段階的に移行することはできますか?
はい。Claude Codeに「xlwingsを使ってVBAとPythonを共存させるコードを書いて」と頼むと、段階的移行に使えるxlwingsベースのコードを生成してくれます。いきなり全部をPythonに変換しなくても、部分的にPythonで実装してVBAと共存させることができます。

VBAマクロの変換をClaude Codeに頼んでみよう

「このVBAが何をしているか教えて」「Pythonに変換して」
Claude Codeにコードを貼り付けるだけで、解析から変換まで対応します。

Claude Codeを無料で試す →

AT
aurant technologies 編集

上場企業からスタートアップまで、数多くのデータ分析基盤構築・AI導入プロジェクトを主導。単なる技術提供にとどまらず、MA/CRM(Salesforce, Hubspot, kintone, LINE)導入によるマーケティング最適化やバックオフィス業務の自動化など、常に「事業数値(売上・利益)」に直結する改善実績多数。

この記事が役に立ったらシェア: