从VBA访问SurveyMonkey API

马特·奥尔森(Mats Olsson)

我打算建立一个Excel VBA项目,以将单个调查响应读出到Excel中的表格中进行一些计算,然后进行PDF报告。

但是,我很难部署.NET库(SurveyMonkeyApi)以便在VBA中提供参考。

我已经建立了一个VisualStudio项目来测试这种方式,并且可以为该特定的VS项目安装它(通过NuGet PM)。但是该库不适用于该计算机上的Excel。

我已经通过独立的NuGet下载(在另一台计算机上)这些库,并且它们都下载了OK,但是随后我对如何注册Excel VBA访问一无所知。最重要的是,它也依赖于NewtonsoftJson库(两次都会自动下载)。

好的建议表示赞赏!

系统管理员

我现在才看到这一点-添加评论或回答问题时,StackOverflow是否具有提醒我的功能,所以我知道回头吗?

这是开始代码:

Option Explicit
Public Const gACCESS_TOKEN As String = "xxxxxxxxxxxxxxxxxxxxxx"
Declare Function GetTickCount Lib "kernel32" () As Long
Declare Sub Sleep Lib "kernel32" (ByVal lngMilliSeconds As Long)
' for a JSON parser see https://code.google.com/p/vba-json/

Public Sub test()
Dim vRequestBody  As Variant, sResponse As String, sSurveyID As String
sSurveyID = "1234567890"

vRequestBody = "{""survey_id"":" & """" & sSurveyID & """" _
              & ", ""fields"":[""collector_id"", ""url"", ""open"", ""type"", ""name"", ""date_created"", ""date_modified""]" _
              & "}"
sResponse = SMAPIRequest("get_collector_list", vRequestBody)

End Sub
Function SMAPIRequest(sRequest As String, vRequestBody As Variant) As String
Const SM_API_URI As String = "https://api.surveymonkey.net/v2/surveys/"
Const SM_API_KEY As String = "yyyyyyyyyyyyyyyyyyyyyyyy"
Dim bDone As Boolean, sMsg As String, sUrl As String, oHttp As Object ' object MSXML2.XMLHTTP
Static lsTickCount As Long

If Len(gACCESS_TOKEN) = 0 Then
   Err.Raise 9999, "No Access token"
End If
On Error GoTo OnError

sUrl = SM_API_URI & URLEncode(sRequest) & "?api_key=" & SM_API_KEY
   'Debug.Print Now() & " " & sUrl
Application.StatusBar = Now() & " " & sRequest & " " & Left$(vRequestBody, 127)
Set oHttp = CreateObject("MSXML2.XMLHTTP") ' or "MSXML2.ServerXMLHTTP"

Do While Not bDone ' 4.33 offer retry
   If GetTickCount() - lsTickCount < 1000 Then ' if less than 1 sec since last call, throttle to avoid sResponse = "<h1>Developer Over Qps</h1>"
      Sleep 1000 ' wait 1 second so we don't exceed limit of 2 qps (queries per second)
   End If
   lsTickCount = GetTickCount()
   'Status  Retrieves the HTTP status code of the request.
   'statusText Retrieves the friendly HTTP status of the request.
   'Note   The timeout property has a default value of 0.
   'If the time-out period expires, the responseText property will be null.
   'You should set a time-out value that is slightly longer than the expected response time of the request.
   'The timeout property may be set only in the time interval between a call to the open method and the first call to the send method.
RetryPost:  ' need to do all these to retry, can't just retry .Send apparently
   oHttp.Open "POST", sUrl, False   ' False=not async
   oHttp.setRequestHeader "Authorization", "bearer " & gACCESS_TOKEN
   oHttp.setRequestHeader "Content-Type", "application/json"

   oHttp.send CVar(vRequestBody)     ' request body needs brackets EVEN around Variant type
   '-2146697211   The system cannot locate the resource specified. => no Internet connection
   '-2147024809   The parameter is incorrect.
   'String would return {"status": 3, "errmsg": "No oJson object could be decoded: line 1 column 0 (char 0)"} ??
   'A Workaround would be to use parentheses oHttp.send (str)
   '"GET" err  -2147024891   Access is denied.
   '"POST" Unspecified error = needs URLEncode body? it works with it but

   SMAPIRequest = oHttp.ResponseText
   'Debug.Print Now() & " " & Len(SMAPIRequest) & " bytes returned"
   sMsg = Len(SMAPIRequest) & " bytes returned in " & (GetTickCount() - lsTickCount) / 1000 & " seconds: " & sRequest & " " & Left$(vRequestBody, 127)

   If Len(SMAPIRequest) = 0 Then
      bDone = MsgBox("No data returned - do you wish to retry?" _
            & vbLf & sMsg, vbYesNo, "Retry?") = vbNo
   Else
      bDone = True ' got reply.
   End If
Loop ' Until bdone

   Set oHttp = Nothing
   GoTo ExitProc

OnError:   ' Pass True to ask the user what to do, False to raise to caller
   Select Case MsgBox(Err.Description, vbYesNoCancel, "SMAPIRequest")
   Case vbYes

      Resume RetryPost
   Case vbRetry
      Resume RetryPost
   Case vbNo, vbIgnore
      Resume Next
   Case vbAbort
      End
   Case Else
      Resume ExitProc ' vbCancel
   End Select
ExitProc:
End Function


Public Function URLEncode(StringVal As String, Optional SpaceAsPlus As Boolean = False) As String
Dim StringLen As Long
 StringLen = Len(StringVal)
 If StringLen > 0 Then
   ReDim result(StringLen) As String
   Dim i As Long, CharCode As Integer
   Dim Char As String, Space As String
   If SpaceAsPlus Then Space = "+" Else Space = "%20"
   For i = 1 To StringLen
      Char = Mid$(StringVal, i, 1)
      CharCode = Asc(Char)
      Select Case CharCode
      Case 97 To 122, 65 To 90, 48 To 57, 45, 46, 95, 126
      result(i) = Char
      Case 32
      result(i) = Space
      Case 0 To 15
      result(i) = "%0" & Hex(CharCode)
      Case Else
      result(i) = "%" & Hex(CharCode)
      End Select
   Next i
   URLEncode = Join(result, "")
End If
End Function

编辑4月23日添加更多代码。

主题。来自用户表单中的代码。

Set jLib = New JSONLib
vRequestBody = "{"
If Me.txtDaysCreated > "" Then
   vRequestBody = vRequestBody & JKeyValue("start_date", Format$(Now() - CDbl(Me.txtDaysCreated), "yyyy-mm-dd")) & ","
End If
If Me.txtTitleContains > "" Then
' title contains "text", case insensitive
vRequestBody = vRequestBody & JKeyValue("title", Me.txtTitleContains) & ","
End If
vRequestBody = vRequestBody _
   & JKeyValue("fields", Array("title", "date_created", "date_modified", "num_responses", _
      "language_id", "question_count", "preview_url", "analysis_url")) & "}"


'returns in this order: 0=date_modified  1=title  2=num_responses  3=date_created   4=survey_id
' and in date_created descending
sResponse = GetSMAPIResponse("get_survey_list", vRequestBody)

------------------------------------------
Function JKeyValue(sKey As String, vValues As Variant) As String
      Dim jLib As New JSONLib
 JKeyValue = jLib.toString(sKey) & ":" & jLib.toString(vValues)
 Set jLib = Nothing
End Function

编辑VBA代码的4月25日概述以获取数据

SM文档中对此进行了介绍,但我将概述其在VBA中的外观。对get_survey_details的响应将为您提供所有测量设置数据。使用Set oJson = jLib.parse(Replace(sResponse,“ \ r \ n”,“”))获得一个json对象。
设置dictSurvey = oJson(“ data”)
会提供字典,因此您可以获取像dictSurvey(“ num_responses”)之类的数据。我认为您知道如何索引字典对象以获得字段值。

Set collPages = dictSurvey("pages") 

给您页面的集合。未记录的字段“位置”为您提供调查UI中页面的顺序。

For lPage = 1 To collPages.Count
   Set dictPage = collPages(lPage) 
Set collPageQuestions = dictPage("questions") ' gets you the Qs on this page
For lPageQuestion = 1 To collPageQuestions.Count
     Set dictQuestion = collPageQuestions(lPageQuestion) ' gets you one Q
Set collAnswers = dictQuestion("answers") ' gets the QuestionOptions for this Q
        For lAnswer = 1 To collAnswers.Count
           Set dictAnswer = collAnswers(lAnswer) ' gets you one Question Option

等等

然后,根据上面给出的响应数量,一次遍历受访者100-再次查看SM文档,以了解有关如何指定开始和结束日期以随时间进行增量下载的详细信息。从响应到“ get_respondent_list”的响应中创建一个json对象。收集每个响应者的字段并累积最多100个响应者ID的列表。然后为该列表“ get_responses”。

Set collResponsesData = oJson("data")
For lResponse = 1 To collResponsesData.Count

If not IsNull(collResponsesData(lResponse)) then 
... get fields...
Set collQuestionsAnswered = collResponsesData(lResponse)("questions")
  For lQuestion = 1 To collQuestionsAnswered.Count
     Set dictQuestion = collQuestionsAnswered(lQuestion)
        nQuestion_ID = CDbl(dictQuestion("question_id"))
        Set collAnswers = dictQuestion("answers") ' this is a collection of dictionaries
        For lAnswer = 1 To collAnswers.Count

           On Error Resume Next ' only some of these may be present
           nRow = 0: nRow = CDbl(collAnswers(lAnswer)("row"))
           nCol = 0: nCol = CDbl(collAnswers(lAnswer)("col"))
           nCol_choice = 0: nCol_choice = CDbl(collAnswers(lAnswer)("col_choice"))
           sText = "": sText = collAnswers(lAnswer)("text")
           nValue = 0: nValue = Val(sText)  
           On Error GoTo 0

并将所有这些值保存在记录集或工作表或任何有帮助的希望中。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

从AngularJS访问Jenkins API

来自分类Dev

预测API数据访问

来自分类Dev

SurveyMonkey API:导出受访者的csv或excel文件?

来自分类Dev

如何访问Feedly API

来自分类Dev

SurveyMonkey:企业应用程序的API

来自分类Dev

Access VBA API无法访问Windows 8上的文件

来自分类Dev

使用VBA和Oauth2交换Google Calendar API的访问令牌的授权代码

来自分类Dev

如何重置SurveyMonkey长期访问令牌

来自分类Dev

如何访问Gmail API?

来自分类Dev

禁止Http访问api

来自分类Dev

SurveyMonkey元数据API的可用性

来自分类Dev

SurveyMonkey API使用NodeJS创建调查

来自分类Dev

图api访问被拒绝

来自分类Dev

预测API数据访问

来自分类Dev

surveymonkey API呼叫返回状态码3-无效的请求

来自分类Dev

访问2010 VBA API TWIPS / PIXEL

来自分类Dev

访问特定的API

来自分类Dev

如何为SurveyMonkey生成受限访问API令牌?

来自分类Dev

从VBA访问SurveyMonkey API

来自分类Dev

Excel VBA中来自AMAZON XML API的访问元素

来自分类Dev

如何访问Gmail API?

来自分类Dev

SurveyMonkey-限制API调查访问

来自分类Dev

Surveymonkey REST API-跳过逻辑

来自分类Dev

访问Google Translator API

来自分类Dev

SurveyMonkey元数据API的可用性

来自分类Dev

NativeScript设备/ API访问

来自分类Dev

如何在付费帐户中使用API删除SurveyMonkey品牌?

来自分类Dev

如何访问OSM API

来自分类Dev

Excel中通过VBA访问API