1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

VBAと生成AIを連携させてExcel文書の自動校正ツールを作ってみた①初級

Last updated at Posted at 2026-01-18

はじめに

ビジネス文書を作成する際、こんな悩みはありませんか?

  • メールの敬語が正しいか不安
  • 報告書の表現が冗長になっている気がする
  • 文章のトーンが統一できていない
  • 話し言葉になってしまっている

など。
こうした課題を解決するため、ExcelのVBAとOpenAI APIを連携させた自動校正ツールを作成しました。

本記事では、VBAから生成AIを呼び出す基本的な方法と、実用的な校正ツールの実装方法を解説します。

Microsoft Copilotとの違いは?

「それ、Word CopilotやPowerPoint Copilotでできるのでは?」と思われるかもしれません。確かにその通りですが、このツールには以下の差別化ポイントがあります。

主な違い

項目 Microsoft Copilot このVBAツール
処理対象 各アプリ内の文書(1文書ずつ) Excel上の複数テキストを一括処理
カスタマイズ プロンプトの詳細制御は限定的 プロンプトを自由にカスタマイズ可能
費用 Microsoft 365 Copilotライセンス必要(ユーザーあたり月額約$30) OpenAI API従量課金(使った分だけ、通常数円〜数十円/月)
データの扱い Microsoftのサービス経由 自社管理のAPI経由(ポリシーで制御しやすい)
利用シーン Office文書の作成・編集作業 Excelで管理している大量のテキストデータ処理

このツールが特に有効なケース

  1. Excelで文書を一元管理している場合

    • 例:メールテンプレート集、議事録一覧、お知らせ文案リストなど
    • 複数行を一度に処理できる(次回記事で解説予定)
  2. プロンプトをカスタマイズしたい場合

    • 例:「弊社の文書ルールに従って校正」「特定の用語は必ず使う」など
    • 会社独自の表現ルールに対応
  3. API料金を抑えたい場合

    • Copilotライセンスより低コスト
    • 使用量が少ない部署でも導入しやすい
  4. セキュリティポリシーで管理したい場合

    • 自社のAzure OpenAI ServiceやAWS Bedrockに接続可能
    • データの流れを完全に把握・制御できる

システム構成

┌─────────────┐
│   Excel     │
│   (VBA)     │
└──────┬──────┘
       │ HTTP通信
       ▼
┌─────────────┐
│  OpenAI API │
│(gpt-4o-mini)│
└──────┬──────┘
       │ JSON
       ▼
┌─────────────┐
│   校正結果  │
│ →隣セルへ   │
└─────────────┘

準備するもの

  1. OpenAI APIキー

    • OpenAI Platformでアカウント作成
    • API Keysから新しいキーを発行
  2. Excel (2016以降推奨)

    • VBAマクロが使える環境

実装コード

全体コード

以下のコードをExcelの標準モジュールに貼り付けてください。

Option Explicit

' ===================================
' Excel業務文書 自動校正・改善アシスタント
' 基本版
' ===================================

' API設定(ここにご自身のAPIキーを設定してください)
Private Const API_KEY As String = "YOUR_OPENAI_API_KEY"
Private Const API_ENDPOINT As String = "https://api.openai.com/v1/chat/completions"

' メイン処理:選択したセルの文章を校正
Sub 文章を校正する()
    Dim selectedText As String
    Dim improvedText As String
    
    ' 選択セルのテキストを取得
    If Selection.Count > 1 Then
        MsgBox "複数セルが選択されています。1つのセルを選択してください。", vbExclamation
        Exit Sub
    End If
    
    selectedText = ActiveCell.Value
    
    If Len(Trim(selectedText)) = 0 Then
        MsgBox "セルにテキストが入力されていません。", vbExclamation
        Exit Sub
    End If
    
    ' 校正中メッセージ
    Application.StatusBar = "AIで校正中..."
    Application.ScreenUpdating = False
    
    ' OpenAI APIを呼び出して校正
    improvedText = CallOpenAI(selectedText, "校正")
    
    ' 結果を隣のセルに出力
    If improvedText <> "" Then
        ActiveCell.Offset(0, 1).Value = improvedText
        MsgBox "校正が完了しました!", vbInformation
    Else
        MsgBox "校正に失敗しました。APIキーや通信環境を確認してください。", vbCritical
    End If
    
    Application.StatusBar = False
    Application.ScreenUpdating = True
End Sub

' メイン処理:選択したセルの文章を要約
Sub 文章を要約する()
    Dim selectedText As String
    Dim summaryText As String
    
    selectedText = ActiveCell.Value
    
    If Len(Trim(selectedText)) = 0 Then
        MsgBox "セルにテキストが入力されていません。", vbExclamation
        Exit Sub
    End If
    
    Application.StatusBar = "AIで要約中..."
    Application.ScreenUpdating = False
    
    summaryText = CallOpenAI(selectedText, "要約")
    
    If summaryText <> "" Then
        ActiveCell.Offset(0, 1).Value = summaryText
        MsgBox "要約が完了しました!", vbInformation
    Else
        MsgBox "要約に失敗しました。APIキーや通信環境を確認してください。", vbCritical
    End If
    
    Application.StatusBar = False
    Application.ScreenUpdating = True
End Sub

' OpenAI APIを呼び出す関数
Private Function CallOpenAI(inputText As String, taskType As String) As String
    Dim http As Object
    Dim jsonRequest As String
    Dim response As String
    Dim prompt As String
    
    On Error GoTo ErrorHandler
    
    ' タスクに応じたプロンプトを作成
    Select Case taskType
        Case "校正"
            prompt = "以下のビジネス文書を校正・改善してください。" & vbCrLf & _
                    "・敬語の誤りを修正" & vbCrLf & _
                    "・冗長な表現を簡潔に" & vbCrLf & _
                    "・ビジネス文書として適切な表現に" & vbCrLf & _
                    "・改善した文章のみを出力(説明不要)" & vbCrLf & vbCrLf & _
                    "【元の文章】" & vbCrLf & inputText
        Case "要約"
            prompt = "以下の文章を3行程度で要約してください。" & vbCrLf & vbCrLf & _
                    "【元の文章】" & vbCrLf & inputText
        Case Else
            prompt = inputText
    End Select
    
    ' HTTPリクエストオブジェクトを作成
    Set http = CreateObject("MSXML2.XMLHTTP")
    
    ' JSONリクエストボディを作成
    jsonRequest = "{" & _
        """model"": ""gpt-4o-mini""," & _
        """messages"": [{""role"": ""user"", ""content"": """ & EscapeJson(prompt) & """}]," & _
        """temperature"": 0.3" & _
        "}"
    
    ' APIリクエストを送信
    http.Open "POST", API_ENDPOINT, False
    http.setRequestHeader "Content-Type", "application/json"
    http.setRequestHeader "Authorization", "Bearer " & API_KEY
    http.send jsonRequest
    
    ' レスポンスを取得
    response = http.responseText
    
    ' ステータスコードをチェック
    If http.Status <> 200 Then
        CallOpenAI = ""
        Exit Function
    End If
    
    ' JSONレスポンスから結果を抽出
    CallOpenAI = ParseJsonResponse(response)
    
    Exit Function
    
ErrorHandler:
    CallOpenAI = ""
End Function

' JSON文字列をエスケープする関数
Private Function EscapeJson(text As String) As String
    Dim result As String
    result = text
    result = Replace(result, "\", "\\")
    result = Replace(result, """", "\""")
    result = Replace(result, vbCrLf, "\n")
    result = Replace(result, vbCr, "\n")
    result = Replace(result, vbLf, "\n")
    result = Replace(result, vbTab, "\t")
    EscapeJson = result
End Function

' JSONレスポンスを解析する関数
Private Function ParseJsonResponse(jsonText As String) As String
    On Error GoTo ErrorHandler
    
    ' 方法1: ScriptControlを使用(推奨)
    Dim result As String
    result = ParseJsonWithScriptControl(jsonText)
    
    If result <> "" Then
        ParseJsonResponse = result
        Exit Function
    End If
    
    ' 方法2: ScriptControlが使えない場合は文字列処理(フォールバック)
    result = ParseJsonWithStringMethod(jsonText)
    ParseJsonResponse = result
    
    Exit Function
    
ErrorHandler:
    ' フォールバック
    ParseJsonResponse = ParseJsonWithStringMethod(jsonText)
End Function

' ScriptControlを使ったJSON解析(方法1)
Private Function ParseJsonWithScriptControl(jsonText As String) As String
    On Error GoTo ErrorHandler
    
    Dim sc As Object
    Dim jsonObj As Object
    Dim content As String
    
    ' ScriptControlオブジェクトを作成
    Set sc = CreateObject("MSScriptControl.ScriptControl")
    sc.Language = "JScript"
    
    ' JavaScriptでJSONをパース
    sc.AddCode "function parseJson(jsonStr) { return JSON.parse(jsonStr); }"
    Set jsonObj = sc.Run("parseJson", jsonText)
    
    ' choices[0].message.content を取得
    content = jsonObj.Choices(0).Message.content
    
    ParseJsonWithScriptControl = content
    
    Exit Function
    
ErrorHandler:
    ParseJsonWithScriptControl = ""
End Function

' 文字列処理を使ったJSON解析(方法2 - フォールバック)
Private Function ParseJsonWithStringMethod(jsonText As String) As String
    Dim startPos As Long
    Dim endPos As Long
    Dim content As String
    Dim i As Long
    Dim char As String
    Dim escaped As Boolean
    
    ' "content":" を探す
    startPos = InStr(jsonText, """content"":""")
    If startPos = 0 Then
        ' スペース付きパターンを試す
        startPos = InStr(jsonText, """content"": """)
        If startPos = 0 Then
            ParseJsonWithStringMethod = ""
            Exit Function
        End If
        startPos = startPos + Len("""content"": """)
    Else
        startPos = startPos + Len("""content"":""")
    End If
    
    ' エスケープを考慮して終了位置を探す
    i = startPos
    escaped = False
    
    Do While i <= Len(jsonText)
        char = Mid(jsonText, i, 1)
        
        If escaped Then
            ' 前の文字がバックスラッシュの場合はスキップ
            escaped = False
        ElseIf char = "\" Then
            escaped = True
        ElseIf char = """" Then
            ' エスケープされていない引用符が見つかった
            endPos = i
            Exit Do
        End If
        
        i = i + 1
    Loop
    
    If endPos = 0 Then
        ParseJsonWithStringMethod = ""
        Exit Function
    End If
    
    ' コンテンツを抽出
    content = Mid(jsonText, startPos, endPos - startPos)
    
    ' エスケープを解除
    content = Replace(content, "\n", vbCrLf)
    content = Replace(content, "\r", "")
    content = Replace(content, "\t", vbTab)
    content = Replace(content, "\""", """")
    content = Replace(content, "\\", "\")
    
    ParseJsonWithStringMethod = content
End Function


コードのポイント解説

1. API設定部分

Private Const API_KEY As String = "YOUR_OPENAI_API_KEY"
  • ここにOpenAIで取得したAPIキーを設定します
  • sk-proj-... または sk-... のような形式のキーです

2. HTTP通信部分

Set http = CreateObject("MSXML2.XMLHTTP")
http.Open "POST", API_ENDPOINT, False
http.setRequestHeader "Content-Type", "application/json"
http.setRequestHeader "Authorization", "Bearer " & API_KEY
  • VBAから外部APIを呼び出す標準的な方法です
  • MSXML2.XMLHTTP オブジェクトでHTTP通信を実現

3. プロンプト設計部分

prompt = "以下のビジネス文書を校正・改善してください。" & vbCrLf & _
        "・敬語の誤りを修正" & vbCrLf & _
        "・冗長な表現を簡潔に" & vbCrLf & _
        "・ビジネス文書として適切な表現に"
  • ここを変更すれば、用途に応じたカスタマイズが可能
  • 例:「社内向けカジュアルに」「お客様向けに丁寧に」など

4. JSON解析部分

  • 方法1: ScriptControl(JavaScriptエンジン)を使った確実な解析
  • 方法2: 文字列処理によるフォールバック
  • 2段階方式で環境の違いに対応

使い方

1. 初期設定

  1. Excelを開き、Alt + F11 でVBAエディタを起動

  2. 「挿入」→「標準モジュール」で新しいモジュールを追加
    image.png

  3. 上記コードを貼り付け

  4. API_KEY の部分を自分のAPIキーに書き換え(””は消さないで)

image.png

  1. 保存(マクロ有効ブック .xlsm 形式で保存)

2. 実行方法

①まず、A1セルにサンプル文章を入れていく
※今回は以下の文を貼り付けてみる

こんにちは。今日の天気は晴れです。明日は雨の気配です。
明日の雨は風が強く横殴りの雨になりそうです。
通勤には気を付けて、在宅可能な人はなるべく在宅にしてください。
夜は19時以降から雨が止み、気温が下がる気配です。
夜は分厚いコートを着るなど対処してください。

②A1セルを選択した状態で、「Alt」+「F8」を押す
②マクロ画面が出てくるので、「文章を校正する」もしくは「文章を要約する」を選択し「実行」ボタンを押す
image.png

「文章を校正する」を選択した時

  1. 文章を校正する を実行
  2. 隣のセルに校正結果が出力される

image.png

「文章を要約する」を選択した時

  1. 文章を要約する を実行
  2. 隣のセルに要約結果が出力される

image.png

3. その他、実行例

例1:メール文の校正

元の文章(A列):

お世話になります。先日の件につきまして、ご報告させて頂きます。
資料の方を添付させて頂いておりますので、ご確認の程、宜しくお願い致します。

校正後(B列):

お世話になっております。先日の件についてご報告いたします。
資料を添付いたしましたので、ご確認をお願いいたします。

改善点:

  • 「お世話になります」→「お世話になっております」(より丁寧)
  • 「〜の方」「〜させて頂く」などの冗長表現を削除
  • 「宜しく」→「お願いいたします」(正しい表記)

例2:報告書の簡潔化

元の文章(A列):

本プロジェクトにおきましては、当初の予定通りに進捗しておりまして、
特段の問題点等は発生していない状況となっております。
今後とも引き続き、鋭意努力して参る所存でございます。

校正後(B列):

本プロジェクトは予定通り進捗しており、問題は発生していません。
引き続き取り組んでまいります。

改善点:

  • 冗長な表現を大幅に削減
  • 簡潔でわかりやすい文章に
  • ビジネス文書として適切なトーンを維持

例3:長文の要約

元の文章(A列):

昨日開催された営業会議において、第3四半期の売上目標達成に向けた
具体的なアクションプランについて議論が行われました。特に新規顧客の
獲得に関しては、従来のテレアポだけでなく、SNSマーケティングや
ウェビナー開催など、デジタル施策を強化していく方針が確認されました。

要約後(B列):

第3四半期の売上達成に向け、新規顧客獲得の施策を強化する方針を確認。
従来のテレアポに加え、SNSマーケティングやウェビナー開催などの
デジタル施策を推進する。

ボタン配置で使いやすく

よく使う機能はExcelシート上にボタンとして配置すると便利です:

配置方法

  1. 「開発」タブ→「挿入」→「ボタン(フォームコントロール)」

image.png

  1. シート上にドラッグしてボタンを配置
  2. マクロ「文章を校正する」もしくは「文章を要約する」を割り当て

image.png

  1. ボタンの名前を「校正」もしくは「要約」に変更
    image.png

カスタマイズのアイデア

1. プロンプトのカスタマイズ

社内向けカジュアルトーン:

prompt = "以下の文章を社内向けのカジュアルで親しみやすいトーンに書き換えてください。"

お客様向け超丁寧トーン:

prompt = "以下の文章をお客様向けの最高レベルに丁寧な表現に書き換えてください。"

2. 新しい機能の追加

プロンプトを変更することで、様々な用途に対応できます:

  • 翻訳機能
  • 文体変換(です・ます調⇔だ・である調)
  • 敬語レベル調整
  • 箇条書き化

このようにVBA内で指定したプロンフトをカスタマイズすることで結果を変えることも可能です。

料金について

OpenAI APIの料金は従量課金です(2025年1月時点):

モデル 入力 出力
gpt-4o-mini $0.150 / 1M tokens $0.600 / 1M tokens

実際の使用例:

  • 200文字程度の文章を校正:約0.0002〜0.001ドル(約0.03〜0.15円)
  • 月100回使用しても:約3〜15円

Microsoft 365 Copilot(月額約$30/ユーザー)と比較すると、使用量が少ない場合は大幅にコストを抑えられます。

セキュリティ上の注意点

1. APIキーの管理

  • コード内に直接APIキーを書くのは開発・検証用
  • 本番運用では環境変数や設定ファイルから読み込む方が安全

2. データの取り扱い

  • OpenAI APIに送信したデータは、OpenAIのデータ保持ポリシーに従います
  • 機密情報を含む文書を処理する場合は、Azure OpenAI Serviceの利用を推奨
    • Azure OpenAI: データは30日間保持後自動削除、学習には使用されない

3. 社内導入時の確認事項

  • 情報システム部門の承認を得る
  • 個人情報保護法や社内規程に抵触しないか確認
  • 必要に応じてAzure OpenAI ServiceやAWS Bedrockなど、企業向けサービスを利用

まとめ

VBAとOpenAI APIを組み合わせることで、Excel上で手軽に業務文書の校正・改善ができるツールを作成しました。

このツールの強み:

  • Excelの使い慣れた環境で動作
  • プロンプトを自由にカスタマイズできる
  • 使った分だけの従量課金で低コスト
  • VBAの知識があれば自由に拡張できる

Microsoft Copilotとの使い分け:

  • Copilot: Office文書の作成・編集作業全般に
  • このツール: Excelで管理しているテキストデータの処理に

次回予告

本記事では単一セルの処理を中心に解説しましたが、実務ではもっと便利な使い方があります。

次回「シンプル拡張版」では以下の機能を追加します:

  • 選択範囲の一括処理 - 10件、20件をまとめて処理
  • 用途別の添削機能 - 報告書、メール、プレゼン、議事録など
  • 進捗表示機能 - 大量処理でも安心
  • 実務での活用例 - プレゼン資料の一括改善、議事録の整形など

例えば、こんなことができるようになります:

プレゼン資料10枚分の箇条書きを選択
→ ボタン1つで一括改善
→ B列に改善版が出力される

続編記事もぜひご覧ください。記事がアップされたら、こちらも読んでいただけると嬉しいです!


この記事が役に立ったら、ぜひ LGTM をお願いします!
ご質問やフィードバックもお気軽にコメント欄へどうぞ。

参考資料

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?