excel 嵌套的VBA内联函数

amrnrhlw  于 2023-05-08  发布在  其他
关注(0)|答案(1)|浏览(155)

我试图创建一个“GPT填充”功能,其工作原理如下。
1.用户定义包含提示和补全的两列的参考范围
1.然后,用户提供他/她想要完成的一组附加提示
1.用户使用正确选择的训练对和包含待完成项目的范围调用GPTFill(TrainingRange,FillRange)
1.宏遍历示例并创建一个“提示/完成”对的字符串
1.宏然后修改提示与其他例子,它希望GPT完成。
1.宏向GPT提交提示,要求返回分隔的答案
1.宏将答案拆分为数组并尝试填充FillRange旁边的单元格。
目视检查见下文

我遇到的问题是,第一个项目的填充工作正常,但当我试图循环通过其余项目时,我似乎重新触发了GPTFill函数,即使我禁用了事件和自动计算。有人知道我的代码有什么问题吗?

Function GPTFill(TrainingRange As Range, FillRange As Range) As String
Application.Calculation = xlCalculationManual
Application.EnableEvents = False

'Create compounded prompt from Training Range
strPrompt = "I'll give you a few examples of prompts and completions. "

'Iterate through training range to collect examples into prompt
For Each trainingRow In TrainingRange.Rows
 strPrompt = strPrompt & "Prompt: " & trainingRow.Cells(1, 1).Value & vbCrLf & "Completion: " & trainingRow.Cells(1, 2).Value & vbCrLf
Next trainingRow

'Concatenate all prompt completions into a single input to see if we can get efficiency gains
strPrompt = strPrompt & vbCrLf & "Now complete the following items given the pattern above. Return just the completion but not the input prompt" & _
                                 "text and separate the text with line returns: " & vbCrLf
For Each fillRow In FillRange.Rows
 strPrompt = strPrompt & fillRow.Cells(1, 1).Value & vbCrLf
Next fillRow

outString = GPT(strPrompt)
'Split into array
GPTOutArray = Split(outString, vbCrLf)

'Populate the other cells
Call PopulateRange(FillRange, GPTOutArray, 1)
GPTFill = GPTOutArray(0)
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True
Exit Function

End Function

Function PopulateRange(tmpRange As Range, tmpArray, intOffset As Integer)

Application.Calculation = xlCalculationManual
Application.EnableEvents = False
For i = 1 To UBound(tmpArray)
  tmpRange.Cells(i + 1, 1).Offset(0, intOffset).Value = tmpArray(i)
Next i

Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True
End Function

我已经尝试将application.calculation设置为manual,将application.enableevents设置为false,但是任何循环遍历这些值并填充需要填充的剩余项的尝试都会重新触发原始的GPTFill宏

shyt4zoc

shyt4zoc1#

我想通了...完整的解决方案是下面包括GPT API调用函数。请注意,电子表格在名为“配置”的选项卡上具有API密钥和温度设置的相应范围。您需要为这两个值创建命名范围,并从OpenAI获取API密钥,以便调用MSXML2.XMLHTTP请求正常工作。

Function GPT(strInPrompt)
  
  Dim request As Object
  Dim text, response, API, api_key, DisplayText, GPTModel As String
  Dim GPTTemp As Double
  Dim startPos As Long
  Dim rng As Range
  Dim httpRequest As Object

  
  'On Error GoTo ErrHandler:
  'API Info
  API = "https://api.openai.com/v1/chat/completions"
  api_key = Trim(Range("API_Key").Value)
  GPTModel = "gpt-3.5-turbo"
  

  If api_key = "" Then
    MsgBox "Error: API cannot be blank! Please go to 'Config' tab and enter a valid OpenAI API key", vbExclamation, "Excel for ChatGPT"
    Exit Function
  End If
    
  'Clean input text and make JSON safe
  text = CleanInput(strInPrompt)
  
  'Create request object
  Set httpRequest = CreateObject("MSXML2.XMLHTTP")

  GPTTemp = Range("GPT_temperature").Value
  
  
  Dim requestBody As String

  requestBody = "{" & _
              """model"": """ & GPTModel & """," & _
              """temperature"": " & GPTTemp & "," & _
              """messages"": [{""content"":""" & text & """,""role"":""user""}]" & _
              "}"

  With httpRequest
     .Open "POST", API, False
     .setRequestHeader "Content-Type", "application/json"
     .setRequestHeader "Authorization", "Bearer " & api_key
     .send (requestBody)
  End With

  
 ' Open and send the HTTP request
  If httpRequest.Status = 200 Then 'Successfully called OpenAI API

   response = httpRequest.responsetext

    'Extract content
    Result = Split(response, """,""")
    For i = LBound(Result) To UBound(Result)
      If InStr(Result(i), "content") > 0 Then
            startPos = i
            Exit For
      End If
    Next i
  
    DisplayText = Mid(Result(startPos), InStr(Result(startPos), ":") + 2, InStr(Result(startPos), """},"))
    DisplayText = Mid(DisplayText, 1, InStr(DisplayText, """},") - 1)
  
    DisplayText = Replace(DisplayText, "\n", vbCrLf)
    Set request = Nothing
    GPT = DisplayText
   Exit Function
  Else 'something went wrong with OpenAI call
    MsgBox "Request failed with status " & httpRequest.Status & vbCrLf & vbCrLf & "Error:" & vbCrLf & httpRequest.responsetext, vbCritical, "OpenAI API Request Failed"
  End If
  
  Exit Function
  
End Function

Function CleanInput(strProcess)
  strProcess = Replace(strProcess, Chr(34), Chr(39))
  strProcess = Replace(strProcess, "/", " ")
  strProcess = Replace(strProcess, "\", " ")
  strProcess = Replace(strProcess, vbCrLf, "\n")
  strProcess = Replace(strProcess, vbLf, "\n")
  strProcess = Replace(strProcess, vbCr, "\n")
  strProcess = Replace(strProcess, vbTab, "\t")
  CleanInput = strProcess
End Function

Function GPTFill(TrainingRange As Range, FillRange As Range) As Variant

'Create compounded prompt from Training Range
strPrompt = "I'll give you a few examples of prompts and completions. "

'Iterate through training range to collect examples into prompt
For Each trainingRow In TrainingRange.Rows
  strPrompt = strPrompt & "User: " & trainingRow.Cells(1, 1).Value & vbCrLf & "System: " & trainingRow.Cells(1, 2).Value & vbCrLf
Next trainingRow

'Concatenate all prompt completions into a single input to see if we can get efficiency gains
strPrompt = strPrompt & vbCrLf & "Repeat for the following rows. Return only the completion portion of the text separated by paragraph returns: " & vbCrLf
For Each fillRow In FillRange.Rows
 strPrompt = strPrompt & fillRow.Cells(1, 1).Value & vbCrLf
Next fillRow

outString = GPT(strPrompt)
'Split into array
GPTOutArray = Split(outString, vbCrLf)

'Populate the cells with return values
 GPTFill = Application.Transpose(GPTOutArray)

End Function

相关问题