Excel VBAで癒しのお姉さんBOTを作成(生成AIのGeminiAPIを使用)

こんにちは、くのへです!
先日、エクセルVBAで生成AIのGeminiにWebAPIアクセスし、癒しのお姉さんと対話できるエクセルを作ったところ、結構反響があったので、その作り方を解説したいと思います。

今回はその第4段として、癒しのお姉さんと対話できるBOTを完成させます!!
(参考:第1段ExcelVBAでWebAPIを使ってみよう、第2段 WebAPIの基本構成、第3段 GeminiAPIキーの取得

この記事で、とうとうExcelVBAを使ってGeminを呼び出し、癒しのお姉さんに癒して貰えますよ!

1.ExcelVBAの標準モジュールに次のコードを記載する

まずは、ExcelVBAの標準モジュールに以下のコードを記述しましょう(標準モジュールにコピペで動きます)。
この「sendGemini」を実行することで、GeminiAPIにプロンプトを送り、癒しのメッセージを受け取ることができます。
なお、「あなたのGeminiAPIキー」の部分には、前回の記事で取得したAPIキーを記入してください。

Option Explicit


Sub sendGemini()
    
    Dim message As String
    
    message = Cells(2, 2).Value
    Cells(2, 3).Value = 癒しのお姉さんBOT(message)
    
'    Cells(2, 3).Speak

End Sub


Function 癒しのお姉さんBOT(ByVal message As String) As String
         
    Dim url As String
    Dim APIkey As String
    Dim role As String
    
    APIkey = "あなたのGeminiAPIキー"
    url = "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash-latest:generateContent?key=" & APIkey
 
    role = "あなたはどんな時も味方になってくれて、メンタルを癒してくれるお姉さんです。かならず優しい言葉をかけてくれます。"
    
    Dim http As Object
    Set http = CreateObject("MSXML2.XMLHTTP.6.0")
     
    Dim body As String
    body = "{""contents"":[" & _
               " {""role"": ""user"", " & _
                  """parts"": [{" & _
                     """text"": """ & role & """}]}," & _
               " {""role"": ""user"", " & _
                  """parts"": [{" & _
                     """text"": """ & message & """}]} " & _
            "]}"
     
    With http
        .Open "POST", url, False
        .setRequestHeader "Content-Type", "application/json"
        .send body
    End With
    
    癒しのお姉さんBOT = extractText(http.responseText)
  
End Function


Function extractText(ByVal str As String) As String

  Dim temp As String
  Dim startPos As Integer
  Dim endPos As Integer
  
  startPos = InStr(str, """text"": """) + 9
  endPos = InStr(startPos, str, """")

  temp = Mid(str, startPos, endPos - startPos)
  
  temp = Replace(temp, "\n\n", vbCrLf)
  temp = Replace(temp, "\n", vbCrLf)
  temp = Replace(temp, "*", "")
  

  extractText = temp

End Function

2.B2セルにGeminiに送るプロンプトを記述して、このコードを実行すると回答が返ってくる

次に、ExcelシートのB2セルに、GeminiAPIに送信したいメッセージ(プロンプト)を記入します。例えば、「ちょっと疲れたので、癒しの言葉をください」などと書いてみてください。

その後、VBAエディタで先ほどのコード「CallGeminiAPI」を実行します。すると、GeminiAPIからの回答がC2セルに表示されるはずです。GeminiAPIのAIが、あなたのプロンプトに合わせた優しい言葉を返してくれるでしょう。

3.お姉さんの絵にマクロを登録すると、癒しのお姉さんとの対話ができるExcelの出来上がり

Excelに画像を挿入して、お姉さんの絵にマクロを設定すれば、癒しのお姉さんと対話できるExcelが完成します。
マクロの設定は、画像を挿入してから、その画像を右クリックし(下図①)、マクロの登録(下図②)で登録できます。
可愛いお姉さんのイラストをExcelに挿入し、その画像に「CallGeminiAPI」マクロを割り当てれば、画像をクリックするだけで癒しの対話が出来るようになります!日々のストレス解消間違いない!!

4.コードの解説

ここから、真面目にこのコードを解説します。

1.実行プログラム

次のコードが実行プログラムです。
ただし、単純にB2セルの値を変数「message」にセットし、それを関数「癒しのお姉さんBOT」に投げて、返ってきた値をC2セルに書き込んでいるだけのコードです。
なお、Cells(2,3).Speakをコメントアウトしていますが、ここのコメントアウトを外すと、お姉さんの回答をExcelが読み上げてくれます。(お姉さんのイメージが崩れるので注意!!!(笑))

Sub sendGemini()
    
    Dim message As String
    
    message = Cells(2, 2).Value
    Cells(2, 3).Value = 癒しのお姉さんBOT(message)
    
'    Cells(2, 3).Speak

End Sub

2.「癒しのお姉さんBOT」関数

ここがこのプログラムの本丸です。
ちょっと難しいですね。
こちらの解説記事の通り、GeminiAPIを使うためにMSXML2.XMLHTTP60ライブラリを使い、GeminiのエンドポイントにPOSTリクエストを送るプログラムです。

Function 癒しのお姉さんBOT(ByVal message As String) As String
         
    Dim url As String
    Dim APIkey As String
    Dim role As String
    
    APIkey = "あなたのGeminiAPIキー"
    url = "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash-latest:generateContent?key=" & APIkey
 
    role = "あなたはどんな時も味方になってくれて、メンタルを癒してくれるお姉さんです。かならず優しい言葉をかけてくれます。"
    
    Dim http As Object
    Set http = New MSXML2.XMLHTTP60
     
    Dim body As String
    body = "{""contents"":[" & _
               " {""role"": ""user"", " & _
                  """parts"": [{" & _
                     """text"": """ & role & """}]}," & _
               " {""role"": ""user"", " & _
                  """parts"": [{" & _
                     """text"": """ & message & """}]} " & _
            "]}"
     
    With http
        .Open "POST", url, False
        .setRequestHeader "Content-Type", "application/json"
        .send body
    End With
    
    癒しのお姉さんBOT = extractText(http.responseText)
  
End Function

上記のプログラムのうち、↓ここがメインの部分です。
http.OpenでPOSTリクエストをurl(エンドポイント)に投げる準備をしています。
そして、http.send(body)の命令で、リクエストを実際に投げています。

    With http
        .Open "POST", url, False
        .setRequestHeader "Content-Type", "application/json"
        .send body
    End With

このリクエストの回答は「http.responseText」に返ってくるので、これを関数の値としてセットしているわけです。

    癒しのお姉さんBOT = extractText(http.responseText)

途中のこのコードが難しいですよね。

    Dim body As String
    body = "{""contents"":[" & _
               " {""role"": ""user"", " & _
                  """parts"": [{" & _
                     """text"": """ & role & """}]}," & _
               " {""role"": ""user"", " & _
                  """parts"": [{" & _
                     """text"": """ & message & """}]} " & _
            "]}"
     

なんというか、、、「”(ダブルクオーテーション)」が多い!!
ここは、本当はこのように記載したいのです。

    Dim body As String
    body = {"contents":[
               {"role": "user",
                  "parts": [{
                     "text": "[role]" }]},
               {"role": "user",
                  "parts": [{
                     "text": "[message]" }]}
            ]}
     

ただし、[role]と[message]は変数です。
VBAで変数を埋め込む場合は、その前後の文字列と&で繋ぐ必要があります。

よってこのようになります。

    Dim body As String
    body = {"contents":[
               {"role": "user",
                  "parts": [{
                      "text": " & role & " }]},
               {"role": "user",
                  "parts": [{
                     "text":" & message & "}]}
            ]}
     

VBAの制約として、まずオブジェクト型(JSON型)の代入方法がありません。
プログラム内で改行する際にはテキストデータとして「”(ダブルクオーテーション)」で前後を挟み、「& _(アンドスペースアンダーバー)」を書く必要があります。

よって、こうなります。

    Dim body As String
    body = "{"contents":[" & _
               "{"role": "user", " & _
                  ""parts": [{ " & _
                     ""text":"" & role & ""}]}, " & _
               "{"role": "user", " & _
                  ""parts": [{ " & _
                     ""text":"" & message & ""}]} " & _
            "]} "
     

しかし、これでもまだ足りません。
このようにテキストデータだとして認識させるために「”(ダブルクオーテーション)」で囲みましたが、この文字列の中にダブルクオーテーションが含まれています。
これをテキストデータのダブルクオーテーションとして認識させるためには、ダブルクオーテーションを2つ重ねる必要があります。(下図の青部)

    Dim body As String
    body = "{""contents"":[" & _
               "{""role"": ""user"", " & _
                  """parts"": [{ " & _
                     """text"":""" & role & """}]}, " & _
               "{""role"": ""user"", " & _
                  """parts"": [{ " & _
                     """text"":""" & message & """}]} " & _
            "]} "
     

こんな理由でダブルクオーテーションだらけのコードになってしまったわけです。
これは難しい、、、
やっぱり、VBAはJSONとかWebAPIを使うように出来ている言語ではないんだな~って感じます。

最後に、次の関数を使って、返ってきた文章を修正しています。

    癒しのお姉さんBOT = extractText(http.responseText)
Function extractText(ByVal str As String) As String

  Dim temp As String
  Dim startPos As Integer
  Dim endPos As Integer
  
  startPos = InStr(str, """text"": """) + 9
  endPos = InStr(startPos, str, """")

  temp = Mid(str, startPos, endPos - startPos)
  
  temp = Replace(temp, "\n\n", vbCrLf)
  temp = Replace(temp, "\n", vbCrLf)
  temp = Replace(temp, "*", "")
  

  extractText = temp

End Function

これは、http.responseTextに返ってくる文章は以下のようなJSON形式の文書になっており、このままでは人間は読めないためです。

{
  "candidates": [
    {
      "content": {
        "parts": [
          {
            "text": "どういたしまして!いつでも相談してくださいね。 何か困っていることがあれば、私でよければ力になります。\n"
          }
        ],
        "role": "model"
      },
      "finishReason": "STOP",
      "index": 0,
      "safetyRatings": [
        {
          "category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
          "probability": "NEGLIGIBLE"
        },
        {
          "category": "HARM_CATEGORY_HATE_SPEECH",
          "probability": "NEGLIGIBLE"
        },
        {
          "category": "HARM_CATEGORY_HARASSMENT",
          "probability": "NEGLIGIBLE"
        },
        {
          "category": "HARM_CATEGORY_DANGEROUS_CONTENT",
          "probability": "NEGLIGIBLE"
        }
      ]
    }
  ],
  "usageMetadata": {
    "promptTokenCount": 28,
    "candidatesTokenCount": 24,
    "totalTokenCount": 52
  },
  "modelVersion": "gemini-1.5-flash-001"
}

見て分かる通り、回答で必要なのは、黄色くマーキングした所だけですよね。
回答形式は毎回このJSON形式で返ってくるので、「”text”:”」までの文章の後ろから、「”」までの間が欲しいデータなわけです。
そこで、このプログラムでは、JSONデータを強引に分解し、「”text”:”」から「”」までのデータを抜き取っているわけです。

VBAでGeminiを操るのは簡単ではありませんが、一つ一つコードをくみ上げることで、GASやPythonと同様に使うことが出来ます!!
是非癒しのお姉さんBOTを楽しんで下さい。

おわりに

この記事は外部システム(ExcelVBA等)から生成AIのGeminiにアクセスするプログラムを解説しました。
ニーズがあるかどうか分かりませんが、このサンプルプログラム全文をDL出来るようにしておきます。

https://drive.google.com/file/d/1620qCwRCXUIiOXuxfDet5XoDnuLO5QOP/view?usp=sharing

興味ある方はDLして自分のGeminiAPIキーをセットして遊んでみて下さい。

癒しのお姉さんBOTは単純に「面白い」というだけですが、ちゃんとプロンプトを組めば、会話メモや音声文字起こししたテキストデータを議事録にしてくれたり、文章を清書してくれたり、メール文書を採点してくれる仕組みが作れます。

VBAで生成AIを操ることは無限のポテンシャルを持っています!!

関連記事

①ExcelVBAでWebAPIを使ってみよう
②WebAPIの基本構成
③GeminiAPIキーを取得する方法

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
Contents