業務効率化

登録プロンプトによるChatgptAPI返答取得関数

登録したプロンプトを使用しChatGPTの返答取得するマクロです。質問を直接入力することに加え、プロンプトを数値として指定することで特定のプロンプトを迅速に送信することができます。公式からCopilot関数が導入されるまで、その安定性もあって優位性があります(はず)。

記事の内容

・挙動

・コード

・ポイント機能

挙動

例えば下記のようなプロンプトを登録しているとします。

第二引数に番号を指定することでプロンプトを呼び出すことが可能です。下記に箇条書き等呼び出した場合の3事例です。もちろん質問を直接記載することも可能ですが、テンプレを一から記載せずに済ませることができます。

コード

➤コードはこちら
Option Explicit


Function UseChatGPTAndGetRes(Inputs As Range, Optional QorRequestKeyNo As Variant) As String


Dim Temp As String

    If IsMissing(QorRequestKeyNo) Then
        UseChatGPTAndGetRes = "第二引数を入力してください。例:(A1.""数か質問"")"
        Exit Function
    End If


If IsError(QorRequestKeyNo) Then
    UseChatGPTAndGetRes = "エラー: 第二引数はダブルクォーテーションで囲んで入力してください。例:(""数or質問"")"
    Exit Function
End If

Debug.Print QorRequestKeyNo
If Len(QorRequestKeyNo) <= 2 And IsNumeric(QorRequestKeyNo) Or Len(QorRequestKeyNo) <= 1 And Not IsNumeric(QorRequestKeyNo) Then
    
    Temp = "テンプレ"
    
    If VarType(QorRequestKeyNo) <> vbString Then
        UseChatGPTAndGetRes = "エラー: 第二引数は質問か数字を入力してください。例:(""数or質問"")"
        
        Exit Function
    End If

    If Not IsNumeric(QorRequestKeyNo) Then
        UseChatGPTAndGetRes = "エラー: 第二引数には数値のみ入力してください"
        Exit Function
    End If
    
ElseIf Not IsNumeric(QorRequestKeyNo) Then

End If


Dim cell As Range
    Dim combinedText As String

    ' 各セルの値を改行で結合
    For Each cell In Inputs.Cells
        If Not IsEmpty(cell.Value) Then
            combinedText = combinedText & cell.Value & "<br>"
        End If
    Next cell

    ' 最後の改行を削除(任意)
        combinedText = Left(combinedText, Len(combinedText) - 4)

'Inputs = combinedText

Debug.Print combinedText

    'UseChatGPTtoGetRes1 = "正常: " & Vals.Cells(1, 1).Value & "/KeyNo: " & RequestKeyNo
  

Dim ReqKeyNoi, PromptWs As Worksheet, FullPrompts As String
Dim Wants As String, Prompts As String
Set PromptWs = ThisWorkbook.Worksheets(1)


Debug.Print ReqKeyNoi

If Temp <> "" Then
    
    ReqKeyNoi = CLng(StrConv(QorRequestKeyNo, vbNarrow))
    ReqKeyNoi = WorksheetFunction.Match(ReqKeyNoi, PromptWs.Range("B:B"), 0)

    Wants = PromptWs.Cells(ReqKeyNoi, 3).Value
    Prompts = PromptWs.Cells(ReqKeyNoi, 4).Value
    FullPrompts = PromptWs.Range("C4")

    Dim TargetArr As Variant, InputArr As Variant
    TargetArr = Array("#Wants#", "#Prompts#", "#Inputs#")
    InputArr = Array(Wants, Prompts, combinedText)
    Dim i As Long

    For i = LBound(TargetArr) To UBound(TargetArr)
        
        FullPrompts = Replace(FullPrompts, TargetArr(i), InputArr(i))
    
    Next


Else
     
     FullPrompts = QorRequestKeyNo & "-- " & combinedText

End If



UseChatGPTAndGetRes = GetGPTresp(Replace(Replace(FullPrompts, vbLf, ""), vbCrLf, ""))


End Function

Private Function GetGPTresp(strQuestion As Variant) As Variant
 
    Dim APIKey As String
    Dim strModel As String
    
    Dim Url As String
    Dim http As Object
    Dim strMessages  As String
    Dim strResponse As String
 
    '*** 初期値設定 *****
    APIKey = ThisWorkbook.Worksheets(1).Range("C3").Value '"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"
    strModel = ThisWorkbook.Worksheets(1).Range("C2").Value ' "gpt-3.5-turbo"  'モデル名
    
    'strQuestion = Application.InputBox("質問")  '**質問を変数にセット
    
    If strQuestion = False Or strQuestion = "" Then
    Exit Function
    End If

    
    '*** API処理 ****
    Url = "https://api.openai.com/v1/chat/completions"
    
    Set http = CreateObject("MSXML2.XMLHTTP")

    'リクエストヘッダー
    http.Open "POST", Url, False
    http.setRequestHeader "Content-Type", "application/json"
    http.setRequestHeader "Authorization", "Bearer " & APIKey
    
    'メッセージ作成
    strMessages = "{""model"": """ & strModel & """," & _
                  """messages"": [{""role"": ""user"", ""content"": """ & strQuestion & """}]}"

    'リクエスト送信
    http.Send strMessages
    
    strResponse = http.responseText         '結果を変数に代入
    
    'Range("B3") = strResponse
    'MsgBox strResponse
    
    Dim JSON As Object
    Set JSON = JsonConverter.ParseJson(strResponse)

    ' contentを取得
    On Error Resume Next ' エラーを無視して処理を続ける
    strResponse = JSON("choices")(1)("message")("content")
    On Error GoTo 0 ' エラー無視を解除
    GetGPTresp = strResponse
    
End Function





APIによる返答取得をするにあたり、JSONConverterが必要になります。下記GitHubから最新版のbatファイルをダウンロードし、ファイルにインポートか新しく作ったモジュールに内容をコピーしてください。

GitHub - VBA-tools/VBA-JSON: JSON conversion and parsing for VBA

下記が必要なファイルになります。

ポイント機能

・登録プロンプトの数値での指定

・数値以外の質問直接指定とエラー処理

・ChatGPTAPI使用関数

登録プロンプトの数値での指定

関数ではワークシート上にある登録したプロンプトを即座に使用するため、第二引数に数値を指定することで利用ができます。プロンプトの指示は毎回同じだったり、複雑なプロンプトのために位置から入力が必要だったりすることで手間になることがあります。そこでシート上にプロンプトを登録することですぐに指示を作成できるようにしています。

例えば下記のプロンプトを登録しているとし、和訳をしたい場合には、引数には(対象のセル番地、"1")と入力します。

ワークシートからキーNoを探し、やりたい事概要と、プロンプト詳細をそれぞれ取得します。取得したそれぞれの値は、下記のプロンプトの#Wants#と#Pronpts#に置き換えられます。#Inputs#は選択したセルの値に置き換えられ、指定のプロンプトが即座に送れるようになっています。

プロンプトによっては返答が指示したプロンプト+返答という形で、返答のみ取得ができない場合があります。純粋な返答を得たい場合は、プロンプトに「返答のみ返信ください」など指示を調整してください。

数値以外の質問直接指定とエラー処理

登録プロンプトを数値で呼び出せますが、登録していない場合の指示をする場合もあります。その際も直接指示を渡すことが可能です。その場合はダブルクォーテーションで二文字以上で入力してください。

また、入力時に引数がエラーの場合にはエラー処理を入れています。第二引数はまずダブルクオーテーションで囲む必要がありますが、関数について使用法が分からない人のためにエラー文字として、入力法を戻り値としています。

今回引数には質問の他、登録プロンプト番号入力でも実行できるようにしています。よって数値であり、2文字以下である場合、1文字以下で数値ではない場合を条件としてエラー処理を実施しています。これは登録プロンプトが3桁いかないことと、質問が一文字以上の前提です。

質問が1文字以上なのは、英訳などで二文字の指示の場合がある場合を想定しています。

ChatGPTAPI使用関数

ChatGPTAPIの返答取得は下記関数で戻り値を得ています。今回ワークシートで関数使用されないようにPrivate Functionで設定しています。Privateを付けるとその関数はそのプロシージャ内でしか使用できません。

ChatGPTAPI関数のスクリプトについては下記をご覧ください。

-業務効率化