残業を減らす!Officeテクニック

「ChatGPT」がExcelに入力された数式の意味を教えてくれるコマンドを作ってみた

ExcelからChatGPTを呼び出して数式の意味を教えてもらう

 Excelと対話型AI「ChatGPT」を組み合わせたテクニックが話題ですよね。自動生成した関数式やVBAのコードを手直しして利用するといったExcelの使い方も常識になりそうです。組み込み用のアドインを試した人もいると思います。

 「ChatGPT」のWebページを開いて、Excelの画面と並べて使うのも便利ですが、Excelだけで完結するならそれに越したことはありませんよね。

 今回は、ファイルに含まれる「数式の意味」を「ChatGPT」に教えてもらうマクロ&ショートカットキーを作成したいと思います。動作のイメージは以下の通り。独自のショートカットキー[Alt]+[G]キーを押して、[はい]をクリックすると、「ChatGPT」の回答する数式の意味がコメントに表示されます。

独自に割り当てたショートカットキー[Alt]+[G]を押してメッセージボックスを表示。[はい]をクリックすると、「ChatGPT」の回答がコメントに表示される

 以降で紹介する「Visual Basic for Application」(以下VBA)のコードをコピペすればOK。[個人用マクロブック]に保存するため、「マクロ有効ブック(.xlsm)」として保存する必要はありません。自分のパソコンに保存してあるどのExcelファイルでも利用可能になります。さっそく組み込んでいきましょう。

APIキーは用意しておく

 VBAから「ChatGPT」のAPIを呼び出すため、API KeysのWebページからAPIキーを取得しておきます。詳しくは以前の記事を参考にしてください。

APIキーはAPI KeysのWebページから取得する。生成されたAPIキーをコピーしてメモ帳などにコピー&ペーストしておこう

[個人用マクロブック]の準備

 これから紹介するVBAのコードは[個人用マクロブック]に記述するため、操作するExcelファイルは新規ファイルでも既存のファイルでも構いません。いつも使っている「Excelブック(.xlsx)」で問題ないということです。

 なお、以前に掲載した Excelでよく間違える[F1]キーの無効化方法の記事を試すなどして[個人用マクロブック]が生成済みであれば、以下の操作は不要です。

[開発]タブにある[マクロの記録]をクリックする。[開発]タブが表示されていない場合は[ファイル]タブにある[オプション]をクリックして[Excelのオプション]を呼び出して、[リボンのユーザー設定]画面を表示し、[開発]にチェックを付けておこう
[マクロの記録]ダイアログボックスが表示される。[個人用マクロブック]を選択して[OK]をクリックする
マクロの記録が開始されるが、何も操作する必要はない。[開発]タブに表示されている[記録終了]をクリックする

 以上の操作で[個人用マクロブック]が生成されます。何も操作せずにマクロの記録を終了したので、処理は何も記録されていませんが、以降の操作でVBEの画面を表示すると「PERSONAL.XLSB」のモジュールが表示されます。

独自のショートカットキーの登録

 [開発]タブからVBAの画面を表示して、これから作成するマクロを呼び出す独自のショートカットキーを登録します。ただし、[Ctrl]+[S]キーなどの既存のショートカットキーはNG。ここでは「GPT」にちなんで[G]キーを使いましょう。[Ctrl]+[G]キーは[ジャンプ]ダイアログボックスが割り当て済みなので、[Alt]+[G]キーとしました。

 [Alt]キーを表す識別子は「%」です。以下のコードは『[Alt]+[G]キーが押された時に「Info_formula」という処理を呼び出す』という意味になります。「Sub auto_open()」は「Excel起動時に自動的に実行される処理」の決まり文句です。

Sub auto_open()
    Application.OnKey "%{g}", "Info_formula"
End Sub
[開発]タブにある[Visual Basic]をクリックする
VBAの画面が表示されて「PERSONAL.XLSB」のモジュールのウィンドウが表示される。表示されない場合は、「PERSONAL.XLSB」の「Module 1」をダブルクリック。上記のコードをコピー&ペーストする。こまめに[上書き保存]をクリックしよう。追記するのでこの画面は開いたままにしておく

 もし、[F1]キーの無効化方法のコードなどが記述済みであれば、以下のように追記してください。

Sub auto_open()
    Application.OnKey "{F1}", ""
    Application.OnKey "%{g}", "Info_formula"
End Sub

確認用メッセージボックスの作成

 ショートカットキーが押された時の処理「Info_formula」を記述します。名称は任意で構いませんが、変更する場合は「Application.OnKey "%{g}", "Info_formula"」の処理名をあわせて修正します。

 処理内容はメッセージボックスの表示と以降の処理の分岐です。[はい][いいえ]ボタンの並んだメッセージボックスを表示し、[はい]がクリックされた時に次の処理(Exp_formula)に進み、[いいえ]がクリックされた時に処理を終了します。

ここで記述するコードの実行時に表示されるメッセージボックスの例。セルの数式を取得して表示している。「!」のアイコンや[はい][いいえ]のボタンを指定する
Sub Info_formula()

    Dim rc As Integer

    rc = MsgBox("セルの数式は" & vbLf & ActiveCell.Formula & vbLf & _
        "です。分析しますか?", vbYesNo + vbQuestion + vbDefaultButton2)

    If rc = vbYes Then
        Exp_formula
    Else
        Exit Sub
    End If

End Sub

 「Dim~」は変数の宣言。「MsBox~」でメッセージボックスのあしらいを指定します。「vbLf」は改行、「ActiveCell.Formula」は「アクティブセルの数式を取得する」の意味です。「vbYesNo + vbQuestion + vbDefaultButton2」は[はい][いいえ]ボタン(デフォルトは[いいえ])、「!」のアイコンを表示する指定となります。以降のif文で処理を分岐しています。コードを貼り付けると以下のような状態になります。

上記のコードをコピー&ペーストした状態

「ChatGPT」への問い合わせと回答の表示

 最後に「ChatGPT」への問い合わせと回答を表示する「コメント」を追加する処理(Exp_formula)を追記します。コピペでOKですが「(ここに取得したAPIキーを入力します)」の部分を用意しておいたAPIキーに書き換えてください。前後の「"」を消去しないように注意。

Sub Exp_formula()

    Dim strFormula As String

    Dim strURL As String
    Dim strAPIKey As String

    Dim objHTTP As Object

    Dim strRequest As String
    Dim strResponse As String
    Dim strAnswer As String

    Dim Len1 As Long
    Dim Len2 As Long

    'セルの数式をセット
    strFormula = ActiveCell.Formula & "の処理について教えてください。"

    '数式中の「"」を「'」に置換
    strFormula = Replace(strFormula, Chr(34), Chr(39))

    'ChatGPTの情報
    strURL = "https://api.openai.com/v1/chat/completions"
    strAPIKey = "(ここに取得したAPIキーを入力します)"


    'HTMLリクエスト
    Set objHTTP = CreateObject("MSXML2.XMLHTTP")

    With objHTTP

        'ヘッダーの設定
        .Open "POST", strURL, False
        .SetRequestHeader "Content-Type", "application/json"
        .SetRequestHeader "Authorization", "Bearer " & strAPIKey

        'ChatGPTへのリクエスト
        strRequest = "{ ""model"":""gpt-3.5-turbo"", ""messages"":[{""role"":""user"", ""content"":""" & strFormula & """}]}"
       .Send strRequest

        '応答のチェック
        Debug.Print strRequest
        Debug.Print .ResponseText

        '応答を変数にセット
        strResponse = .ResponseText

    End With

    '応答テキストを整形
    Len1 = InStr(strResponse, "content"":") + 10
    Len2 = InStr(Len1, strResponse, "},") - Len1 - 1

    '回答の本文を取り出す
    strAnswer = Mid(strResponse, Len1, Len2)

    '回答中の改行をvbLfに変換
    strAnswer = Replace(Replace(strAnswer, "\n\n", vbLf), "\n", vbLf)

    'アクティブセルにコメントを追加
    ActiveCell.AddComment strAnswer
    ActiveCell.Comment.Visible = True

End Sub

 コードの意味を簡単に説明します。「Dim~」は変数の宣言。「'セルの数式をセット」にて「ChatGPT」への質問を作成しています。「 & "の処理について教えてください。"」の部分を書き換えると、回答の傾向が変わってきます。ここではコード中にベタ書きしていますが、応答型のダイアログボックスなどを用意して質問文を変更できるような工夫をしても面白いかもしれません。

 「'数式中の「"」を「'」に置換」は、「ChatGPT」への問い合わせ時のエラー回避の処理。「'HTMLリクエスト」の「Set objHTTP = CreateObject("MSXML2.XMLHTTP")」は、VBAでHTMLページを参照する際の定型句と考えてください。

 「'ヘッダーの設定」と「'ChatGPTへのリクエスト」は、ChatGPTのAPIのリファレンスに沿って指定しています。

 問い合わせと回答の内容は「'応答のチェック」の下2行で確認可能。実行後にVBEの画面で[表示]-[イミディエイトウィンドウ]を選択して、イミディエイトウィンドウを表示すると、以下のような表示を確認できます。

{ "model":"gpt-3.5-turbo", "messages":[{"role":"user", "content":"=COUNTIF(C2:C41,H2)の処理について教えてください。"}]}

 「'応答テキストを整形」「'回答の本文を取り出す」「'回答中の改行をvbLfに変換」にて、以下のような「ChatGPT」からの回答を整えています。

{"id":"chatcmpl-76xvXX3OK8P1Cq7IZVWYoHxqdih2V","object":"chat.completion","created":1681894683,"model":"gpt-3.5-turbo-0301","usage":{"prompt_tokens":32,"completion_tokens":96,"total_tokens":128},"choices":[{"message":{"role":"assistant","content":"この処理は、C2からC41までの範囲で、H2と一致するセルの数を数えます。つまり、C2からC41までの範囲でH2と同じ値を持つセルの数を数えます。数えられた値は、関数の戻り値として返されます。"},"finish_reason":"stop","index":0}]}

 「'アクティブセルにコメントを追加」は、整形済みの回答をセルのコメントとしてセットして表示する処理です。上書き保存してVBEの画面を閉じておいてください。

上記のコードをコピー&ペーストして「(ここに取得したAPIキーを入力します)」の部分を用意しておいたAPIキーに書き換えて上書き保存する。VBEの画面は閉じて構わない

「ChatGPT」へ数式の意味を問い合わせる

 実際に動かしてみます。数式が入力されたセルを選択して、独自に割り当てたショートカットキー[Alt]+[G]キーを押すとメッセージボックスが表示されます。[はい]をクリックすると「ChatGPT」への問い合わせが発生して、アクティブセルにコメントが表示されます。

数式の入力されているセルを選択して[Alt]+[G]キーを押すと入力された数式を分析するかどうかのメッセージボックスが表示される。[はい]をクリックする
アクティブセルに「ChatGPT」からの回答がコメントとして追加される。コメントの位置やサイズは任意で調整する。実行するごとに回答は変わる
「"」で囲んだ文字列が含まれるCOUNTIFS関数の回答例
VLOOKUP関数の回答例
ネストしている数式でも回答してくれるのが便利

 実行時にエラーが発生する場合は、APIの無料枠上限に達している、もしくは有効期限が切れているかもしれません。usageのページを確認してみましょう。

APIの無料枠が期限切れになっている場合はエラーが発生する