Excel vba rest api

Уровень сложности
Средний

Время на прочтение
9 мин

Количество просмотров 14K

Работая в IoT-сфере и плотно взаимодействуя с одним из основных элементов данной концепции технологий – сетевым сервером, столкнулся вот с какой проблемой (задачей): необходимо отправлять много запросов для работы с умными устройствами на сетевой сервер. На сервере был реализован REST API с оболочкой Swagger UI, где из графической оболочки можно было отправлять только разовые запросы. Анализ сторонних клиентов, типа Postman или Insomnia показал, что простого визуального способа поместить в скрипт массив из необходимого перечня идентификаторов устройств (или любых других элементов сервера), для обращения к ним – не нашлось.

Так как большая часть работы с выгрузками и данными была в Excel, то решено было вспомнить навыки, полученные на учебе в университете, и написать скрипт на VBA, который бы мою задачку решал.

Необходимо было:

  • получать информацию по устройствам с различными параметрами фильтрации (GET);

  • применять изменения в конфигурации по устройствам: имя, профиль устройства, сетевые лицензии и пр. (PUT);

  • отправлять данные для конфигурации и взаимодействия с устройствами (POST).

И сегодня я расскажу вам про то, как с помощью Excel, пары формул и самописных функций на VBA можно реализовать алгоритм, отправляющий любое необходимое количество REST-API запросов с использованием авторизации Bearer Token.

Данная статья будет полезная тем, кто воспользуется данным решением под Windows, но еще больше она будет полезна тем людям, которые хотят использовать данное решение на MacOS (с Excel x64) . Как вы уже догадались, ниже будут рассмотрены два варианта реализации под разные системы, так как с MacOS есть нюанс.


Часть 1. Реализация решения под Windows

GET

Начнем с самого простого: GET – запросов. В данном примере необходимо получить ответ (информацию) от сервера по заданному списку устройств.

Для реализации GET – запросов нам дано:

1)   Ссылка, в которой указываются параметры запроса. 

https://dx-api.thingpark.io/core/latest/api/devices?deviceEUI=

2)   Заголовки запроса + Токен авторизации (Bearer Token)

—header ‘Accept: application/json’ —header ‘Authorization: Bearer

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzY29wZSI6WyJTVUJTQ1JJQkVSOjY3MDAiXSwiZXhwIjozNzc0MTY0MzE4LCJqdGkiOiI5OTNiOTk1Ny03NGY1LTQ5MDgtYjg4Ni0xYjk5NTVkZDQwZTEiLCJjbGllbnRfaWQiOiJkZXYxLWFwaS9lcnRoLnRlY2guZGVzayt2bGFkaXNsYXYuZ2F0Y2Vua29AZ21haWwuY29tIn0.dqybsMdVXXpQV8_ykufNZoQpSPZrVA67uieOJan-qs8W7rAImyy0552buniHXPWy6ilvdwJKPCdIKE__LghP6A

3)   Параметр, указываемый в ссылке (в данном примере это идентификаторы устройств – DevEUI):

1ABCDEFF00AABBCC

0016ACC4DCF15A23

D88039FFFE954DF4

0000000000001103

0000000000001104

Имея такие данные на входе, делаем в Excel лист-шаблон, который заполняем в соответствии с тем, что имеем:

  • столбец А уходит вот значения параметров

  • столбец F уходит под ссылку-родителя

  • столбец H уходит под заголовки, где в ячейке H1 единоразово для текущего листа указывается токен:

=СЦЕП("--header 'Accept: application/json' --header 'Authorization: Bearer ";$H$1;"'")

  • столбец I уходит под URL (ссылки-дети, на основе ссылки-родителя)

=СЦЕПИТЬ($F$1;A2)

  • столбец J уходит под результат (ответ от сервера)

Шаблон листа для GET-запросов

Шаблон листа для GET-запросов

Далее, нам необходимо реализовать подпрограмму(макрос) отправки GET-запросов. Состоит она из четырех частей:

  1. цикла, который считает количество строк для работы по листу, пробегая по столбцу А с 2 по первую пустую ячейку, чтобы у цикла был конец.

  2. функции, для работы с REST API (используется стандартная, библиотека Msxml2.XMLHTTP.6.0, встроенная в Windows., поэтому сложностей с реализацией не возникает. Для MacOS есть альтернатива)

  3. временной задержки, в случае если нужно отправлять запросы не сразу, после получения ответа, а задав время ожидания

  4. таймером, который показывает время выполнения всего макроса после завершения

    Код:

    Sub GET_Request()
    
    Dim i As Integer
    Dim j As Integer
    Dim objHTTP As Object
    Dim Json As String
    Dim result As String
    Dim URL As String
    Dim Token As String
    a = Timer
    
        i = 1
            Do While Not IsEmpty(Cells(i, 1))
            i = i + 1
            Loop
        i = i - 1
        'MsgBox i
    
        For j = 2 To i
            Json = Range("D" & j)
            URL = Range("I" & j)
            Token = Range("H1")
    
            Set objHTTP = CreateObject("Msxml2.XMLHTTP.6.0")
                objHTTP.Open "GET", URL, False
                objHTTP.setRequestHeader "Content-type", "application/json"
                objHTTP.setRequestHeader "Accept", "application/json"
                objHTTP.setRequestHeader "Authorization", "Bearer " + Token
                objHTTP.Send (Json)
                result = objHTTP.responseText
                Range("J" & j).Value = result
            Set objHTTP = Nothing
            'Application.Wait (Now + TimeValue("0:00:01"))
        Next j
    
    MsgBox Timer - a
    
    End Sub
    

Привязываем подпрограмму к кнопкам для удобства и выполним скрипт. Получается: 

Таким образом, скрипт проходит по столбцу I, забирая из значения каждой ячейки URL, для тех строк, где в столбце А есть значения (которые и подставляются в URL). Для удобства также сделаны кнопки очистки полей и подсветка запросов условным форматированием, в случае успешного ответа на запрос.

PUT

Чуть-чуть усложним задачу и перейдем к PUT-запросам. В данном примере необходимо изменить профиль устройства, чтобы сервер по-другому с ним взаимодействовал.

К исходным данным для GET – запроса добавляется тело запроса с ключем-значением (п4). Итого дано:

1)   Ссылка, в которой указываются параметры запроса.

https://dx-api.thingpark.io/core/latest/api/devices/

2)   Заголовки запроса + Токен авторизации (Bearer Token)

—header ‘Content-Type: application/json’ —header ‘Accept: application/json’ —header ‘Authorization: Bearer

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzY29wZSI6WyJTVUJTQ1JJQkVSOjY3MDAiXSwiZXhwIjozNzc0MTY0MzE4LCJqdGkiOiI5OTNiOTk1Ny03NGY1LTQ5MDgtYjg4Ni0xYjk5NTVkZDQwZTEiLCJjbGllbnRfaWQiOiJkZXYxLWFwaS9lcnRoLnRlY2guZGVzayt2bGFkaXNsYXYuZ2F0Y2Vua29AZ21haWwuY29tIn0.dqybsMdVXXpQV8_ykufNZoQpSPZrVA67uieOJan-qs8W7rAImyy0552buniHXPWy6ilvdwJKPCdIKE__LghP6A

3)   Параметр, указываемый в ссылке (в данном примере это внутренние идентификаторы устройств – hRef):

17272

18199

17242

17245

17248

4)   Тело запроса, с ключом и значением:

{«deviceProfileId»:»LORA/GenericA.1.0.3a_ETSI»}

Немного дополняем новый PUT-лист в Excel по сравнению с GET (остальное без изменений):

  • новый столбец B теперь отвечает за ключ deviceProfileId (ячейка B1), а все значения ниже за его возможные значения)

  • столбец D отвечает за формирование итогового тела сообщения в формате JSON.

=СЦЕПИТЬ("'{""";$B$1;""":""";B2;"""";"}'")

Немного поменяем макрос и вынесем его в отдельную подпрограмму: 

Код:

Sub PUT_Request()

Dim i As Integer
Dim j As Integer
Dim objHTTP As Object
Dim Json As String
Dim result As String
Dim URL As String
Dim Token As String
a = Timer

    i = 1
        Do While Not IsEmpty(Cells(i, 1))
        i = i + 1
        Loop
    i = i - 1
    'MsgBox i

    For j = 2 To i
        Json = Range("D" & j)
        URL = Range("I" & j)
        Token = Range("H1")

        Set objHTTP = CreateObject("Msxml2.XMLHTTP.6.0")
            objHTTP.Open "PUT", URL, False
            objHTTP.setRequestHeader "Content-type", "application/json"
            objHTTP.setRequestHeader "Accept", "application/json"
            objHTTP.setRequestHeader "Authorization", "Bearer " + Token
            objHTTP.Send (Json)
            result = objHTTP.responseText
            Range("J" & j).Value = result
        Set objHTTP = Nothing
        'Application.Wait (Now + TimeValue("0:00:01"))
    Next j

MsgBox Timer - a

End Sub

Привяжем макрос к кнопке и выполним. 

Логика абсолютно аналогична GET запросу.

POST

Для POST запросов все аналогично PUT. Только немного меняется код в части типа запроса. В данном примере на устройство отправляется команда-конфигурация с указанием тела посылки (payload_hex) и порта (fport) для конкретного устройства. 

Код:

Sub PUT_Request()

Dim i As Integer
Dim j As Integer
Dim objHTTP As Object
Dim Json As String
Dim result As String
Dim URL As String
Dim Token As String
a = Timer

    i = 1
        Do While Not IsEmpty(Cells(i, 1))
        i = i + 1
        Loop
    i = i - 1
    'MsgBox i

    For j = 2 To i
        Json = Range("D" & j)
        URL = Range("I" & j)
        Token = Range("H1")

        Set objHTTP = CreateObject("Msxml2.XMLHTTP.6.0")
            objHTTP.Open "PUT", URL, False
            objHTTP.setRequestHeader "Content-type", "application/json"
            objHTTP.setRequestHeader "Accept", "application/json"
            objHTTP.setRequestHeader "Authorization", "Bearer " + Token
            objHTTP.Send (Json)
            result = objHTTP.responseText
            Range("J" & j).Value = result
        Set objHTTP = Nothing
        'Application.Wait (Now + TimeValue("0:00:01"))
    Next j

MsgBox Timer - a

End Sub

Получившаяся таблица выглядит следующим образом:

 На этом часть для Windows заканчивается. Здесь все оказалось довольно просто: стандартная библиотека, простенький алгоритм перебора значений в цикле. 


Часть 2. Реализация решения под MacOS и Excel 64-bit

В виду того, что работал я на двух машинах под управлением разных ОС, хотелось, чтобы решение было универсальным. В итоге, собрав по крупицам информацию по интернет-форумам с данной тематикой у меня вышло следующее решение. Принцип работы его остается схожим, а изменения были внесены в часть, где использовалась стандартная библиотека WindowsMsxml2.XMLHTTP.6.0, которой в MacOS не было по понятным причинам. 

Чтобы обойти данное ограничение, был выбран единственный рабочий подход через cUrl, exec и функции. Данное решение точно работает под версией MacOS 10.14 и Excel 16.51. Функция ниже, в том или ином виде, встречается на различных форумах, однако на текущих версиях софта – не работает. В итоге, после небольших правок получили рабочий вариант:

 Была отлажена функция вызова ExecShell:

Код:

Option Explicit
Private Declare PtrSafe Function popen Lib "/usr/lib/libc.dylib" (ByVal Command As String, ByVal Mode As String) As LongPtr
Private Declare PtrSafe Function pclose Lib "/usr/lib/libc.dylib" (ByVal file As LongPtr) As Long
Private Declare PtrSafe Function fread Lib "/usr/lib/libc.dylib" (ByVal outStr As String, ByVal size As LongPtr, ByVal items As LongPtr, ByVal stream As LongPtr) As Long
Private Declare PtrSafe Function feof Lib "/usr/lib/libc.dylib" (ByVal file As LongPtr) As LongPtr

Function execShell(Command As String, Optional ByRef exitCode As Long) As String
    Dim file As LongPtr
    file = popen(Command, "r")

    If file = 0 Then
        Exit Function
    End If

    While feof(file) = 0
        Dim chunk As String
        Dim read As Long
        chunk = Space(500)
        read = fread(chunk, 1, Len(chunk) - 1, file)
        If read > 0 Then
            chunk = Left$(chunk, read)
            execShell = execShell & chunk
        End If
    Wend

    exitCode = pclose(file)
    
End Function

И написаны отдельные функции для работы с различным методами GET / PUT / POST, которые на входе принимают URL и параметры):

Код:

Function HTTPGet(sUrl As String, sQuery As String) As String

    Dim sCmd As String
    Dim sResult As String
    Dim lExitCode As Long

    sCmd = "curl -X GET " & sQuery & "" & " " & sUrl
    sResult = execShell(sCmd, lExitCode)
    HTTPGet = sResult

End Function

Function HTTPPost(sUrl As String, sQuery1 As String, sQuery2 As String) As String

    Dim sCmd As String
    Dim sResult As String
    Dim lExitCode As Long

    sCmd = "curl -X POST " & sQuery1 & "" & " -d " & sQuery2 & "" & " " & sUrl
    sResult = execShell(sCmd, lExitCode)
    HTTPPost = sResult

End Function

Function HTTPPut(sUrl As String, sQuery1 As String, sQuery2 As String) As String

    Dim sCmd As String
    Dim sResult As String
    Dim lExitCode As Long

    sCmd = "curl -X PUT " & sQuery1 & "" & " -d " & sQuery2 & "" & " " & sUrl
    sResult = execShell(sCmd, lExitCode)
    HTTPPut = sResult

End Function

Так как мы заменяем библиотеку Msxml2.XMLHTTP.6.0 – поменялась реализация макросов в этой части: мы заменили Msxml2 на написанные выше функции и получили следующее:

Код:

'GET-запросы
Sub SendGETRequest()

Dim i As Integer
Dim j As Integer
Dim result As String
Dim URL As String
Dim Auth As String

a = Timer

    'Подсчет заполненных ячеек первого столбца
    i = 1
        Do While Not IsEmpty(Cells(i, 1))
        i = i + 1
        Loop
    i = i - 1

    'Цикл, который отправляет запрос от 2 до последнего элемента
    For j = 2 To i
        URL = Range("I" & j)
        Auth = Range("H" & j)
        result = HTTPGet(URL, Auth)
        Range("J" & j).Value = result
        'Application.Wait (Now + TimeValue("0:00:01"))
    Next j

MsgBox Timer - a

End Sub


'PUT-запросы
Sub SendPUTRequest()

Dim i As Integer
Dim j As Integer
Dim result As String
Dim URL As String
Dim Auth As String
Dim Message As String


a = Timer

    'Подсчет заполненных ячеек первого столбца
    i = 1
        Do While Not IsEmpty(Cells(i, 1))
        i = i + 1
        Loop
    i = i - 1

    'Цикл, который отправляет запрос от 2 до последнего элемента
    For j = 2 To i
        Message = Range("D" & j)
        URL = Range("I" & j)
        Auth = Range("H" & j)
        result = HTTPPut(URL, Auth, Message)
        Range("J" & j).Value = result
        'Application.Wait (Now + TimeValue("0:00:01"))
    Next j

MsgBox Timer - a

End Sub


'POST-запросы
Sub SendPOSTRequest()

Dim i As Integer
Dim j As Integer
Dim result As String
Dim URL As String
Dim Auth As String
Dim Message As String

a = Timer

    'Подсчет заполненных ячеек первого столбца
    i = 1
        Do While Not IsEmpty(Cells(i, 1))
        i = i + 1
        Loop
    i = i - 1

    'Цикл, который отправляет запрос от 2 до последнего элемента
    For j = 2 To i
        Message = Range("D" & j)
        URL = Range("I" & j)
        Auth = Range("H" & j)
        result = HTTPPost(URL, Auth, Message)
        Range("J" & j).Value = result
        'Application.Wait (Now + TimeValue("0:00:01"))
    Next j

MsgBox Timer – a

Итог

В итоге, у меня получилось аналогичное windows по работе и функционалу решение для MacOS c использованием Excel 64-bit. 

На просторах интернета я не нашел какого-то сборного и единого описания, только фрагменты кода и подходов, которые в большинстве случаев не работали полностью или частично. Поэтому решил объединить все в рабочее решение и выложить на хабр для истории. 

На текущий момент я все еще не встретил иного решения, которое бы позволяло в пару кликов копипастить тысячи идентификаторов и параметров из excel и массово их отправлять на сервер. Надеюсь, кому-то пригодится  :)

Если такие сторонние решения есть, а я не в курсе, и все можно было сделать проще, быстрее и изящнее – делитесь опытом в комментариях.

Примечание:

Файл-пример, который можно потыкать, пока жив сервер и «бессрочный» токен: 

https://disk.yandex.ru/d/y7EVtn8afM4QPg

Открытое описание API, если кому-то будет любопытно

Excel is probably one of the most used tools in this world, so the demand for integrations with extremely complex spreadsheets is a recurring scenario. APIs allow easy access to information in systems, which is becoming more and more standard in the market, with that in mind, some demands of connecting to systems via API in Excel are necessary and very useful, so I decided to share a little how I created this integration. Let’s learn how to query Rest APIs using VBA and convert the result to JSON for use in the spreadsheet.

This article hopes you will know the basics of Excel and VBA, as well as what is an API and how it works . Our goal will be to consult a Public Pokemon API and list the result in the tab results .

Creating a blank worksheet

First let’s create a blank sheet with macro enabled, inside it I’ll create a tab called results .

Excel spreadsheet

Creating the macro to query the API

by shortcut alt + f11 let’s open the Excel macro editor, and create a module called list pokemons .

Macro VBA

Importing the VBA-JSON library

As the API we’re going to query returns a JSON as an answer we will need to import the library VBA JSON , it will take care of all the boring work of translating the JSON and returning as an array and object. Installation is very simple, just download the latest version here and in the macro editor go to File > Import File > JsonConverter.bas .

Import VBA JSON

Enabling Microsoft Scripting Runtime

We also need to enable Microsoft Scripting Runtime, to do this just browse Tools > References and search and enable in the list the Microsoft Scripting Runtime .

Excel API Rest Microsoft Scripting Runtime

Creating the VBA macro to query the REST API

Below is the complete code for our request, it might sound scary, but don’t worry, I’ll explain what each part is doing:

Sub listPokemons()
Dim json As String
Dim jsonObject As Object, item As Object
Dim i As Long
Dim ws As Worksheet
Dim objHTTP As Object

'We selected our results sheet
Set ws = Worksheets("results")

'We create our request object and send
Set objHTTP = CreateObject("WinHttp.WinHttpRequest.5.1")
URL = "https://pokeapi.co/api/v2/pokemon"
objHTTP.Open "GET", URL, False
objHTTP.Send
strResult = objHTTP.responseText
json = strResult

Set objectJson = JsonConverter.ParseJson(json)

'We create the header cells
ws.Cells(1, 1) = "name"
ws.Cells(1, 2) = "link"

'We loop the results property of the API response
i = 2 'We will start the counter on line 2
For Each pokemon InJsonObject("results")
    ws.Cells(i, 1) = pokemon("name")
    ws.Cells(i, 2) = pokemon("url")
    i = i + 1
next

End Sub

First we define all the variables that we will use in our scripts, including the VBA JSON library import that we previously imported into our project.

Dim json As String
Dim jsonObject As Object, item As Object
Dim i As Long
Dim ws As Worksheet
Dim xmlhttp As Object
Set xmlhttp = CreateObject("MSXML2.serverXMLHTTP")
Dim objHTTP As Object

Then we select the spreadsheet we want to display the results of the API query, in our case Worksheets("results") and then we create an object that will allow us to make the request to the API. https://pokeapi.co/api/v2/pokemon . We’ll take the answer and put it in the variable json , for now it is nothing more than a text.

'We selected our results sheet
Set ws = Worksheets("results")

'We create our request object and send
Set objHTTP = CreateObject("WinHttp.WinHttpRequest.5.1")
URL = "https://pokeapi.co/api/v2/pokemon"
objHTTP.Open "GET", URL, False
objHTTP.Send
strResult = objHTTP.responseText
json = strResult

Here where the magic happens, the function parsejson from the VBA JSON library converts the text of our variable json for an accessible object in our script. We are now able to access all properties programmatically in our code.

Set objectJson = JsonConverter.ParseJson(json)

Now that we have the result of our API accessible, we create in the first row of the spreadsheet the header containing the columns Name and link .

'We create the header cells
ws.Cells(1, 1) = "name"
ws.Cells(1, 2) = "link"

Now before analyzing the script we need to understand the result of the API. If you open the link https://pokeapi.co/api/v2/pokemon in your browser you will see the following result:

{
  "count": 964,
  "next": "https://pokeapi.co/api/v2/pokemon?offset=20&limit=20",
  "previous": null,
  "results": [
    {
      "name": "bulbasaur",
      "url": "https://pokeapi.co/api/v2/pokemon/1/"
    },
    {
      "name": "ivysaur",
      "url": "https://pokeapi.co/api/v2/pokemon/2/"
    },
    {
      "name": "venusaur",
      "url": "https://pokeapi.co/api/v2/pokemon/3/"
    },
    {
      "name": "charmander",
      "url": "https://pokeapi.co/api/v2/pokemon/4/"
    },
    {
      "name": "charmeleon",
      "url": "https://pokeapi.co/api/v2/pokemon/5/"
    },
    {
      "name": "charizard",
      "url": "https://pokeapi.co/api/v2/pokemon/6/"
    },
    {
      "name": "squirtle",
      "url": "https://pokeapi.co/api/v2/pokemon/7/"
    },
    {
      "name": "wartortle",
      "url": "https://pokeapi.co/api/v2/pokemon/8/"
    },
    {
      "name": "blastoise",
      "url": "https://pokeapi.co/api/v2/pokemon/9/"
    },
    {
      "name": "caterpie",
      "url": "https://pokeapi.co/api/v2/pokemon/10/"
    },
    {
      "name": "metapod",
      "url": "https://pokeapi.co/api/v2/pokemon/11/"
    },
    {
      "name": "butterfree",
      "url": "https://pokeapi.co/api/v2/pokemon/12/"
    },
    {
      "name": "weedle",
      "url": "https://pokeapi.co/api/v2/pokemon/13/"
    },
    {
      "name": "kakuna",
      "url": "https://pokeapi.co/api/v2/pokemon/14/"
    },
    {
      "name": "beedrill",
      "url": "https://pokeapi.co/api/v2/pokemon/15/"
    },
    {
      "name": "pidgey",
      "url": "https://pokeapi.co/api/v2/pokemon/16/"
    },
    {
      "name": "pidgeotto",
      "url": "https://pokeapi.co/api/v2/pokemon/17/"
    },
    {
      "name": "pidgeot",
      "url": "https://pokeapi.co/api/v2/pokemon/18/"
    },
    {
      "name": "rattata",
      "url": "https://pokeapi.co/api/v2/pokemon/19/"
    },
    {
      "name": "raticate",
      "url": "https://pokeapi.co/api/v2/pokemon/20/"
    }
  ]
}

We are interested in the property. results , an array containing a list of pokemons with their names and links to more details. We will access this matrix at jsonobject("results") and we will loop to display each pokemon result in a new row of our table.

'We loop the results property of the API response
i = 2 'We will start the counter on line 2
For Each pokemon InJsonObject("results")
    ws.Cells(i, 1) = pokemon("name")
    ws.Cells(i, 2) = pokemon("url")
    i = i + 1
next

If everything goes as expected, by pressing f5 to run our macro, in your spreadsheet you should see the following result:

Excel API Rest

Conclusion

This was a very simple example of a query, with the object of HT TP it is possible to perform all types of requests, GET, POST, UPDATE, … The interesting thing is to understand how the request is made and how you can display the result, thanks to the VBA JSON library, which already drastically reduces the work required. Now you just need to adapt this flow and script to your needs.

3.7
6
votos

Nota do Artigo

1.   Introduction

This blog post aims to get you started using the Planning Analytics REST API. Excel will be used as the user interface with VBA to drive the queries handle the results.

Excel is not the ideal interface to work with JSON but through the use of 3rd party modules, JSON can be parsed into objects that can be dealt with in Excel VBA.

In this post we look at building processes to retrieve Sessions and associated Threads as well as a request to cancel a Thread.

There are multiple methods of interacting with the REST API:

  • A service using MSXML2.XMLHTTP60
  • Via Cognos Office Automation Object using the Reporting object

This post will look at using the MSXML2.XMLHTTP60 option where the Planning Analytics for Excel add-in is not required. The main difference that I have noticed when working with Planning Analytics on the Cloud (PAOC) is that you can only access the REST API through the provided automation user (non-interactive account). Using the Reporting object, you can interact with the REST API through the authenticated user.

For my examples, I will be connecting to PAOC through the automation user. You could change the endpoint for your local server e.g. http://tm1server:<HTTPPortNumber>/api/v1/

2.   Connection Settings

On our first sheet in the workbook we will create the server access details.

We will make use of the following parameters as a start:

Connection:       A name to identify the connection

Server:              Endpoint of my server

Database:          TM1 database name

Username:        The automation user

Password:         Password

CAM Namespace: For PAOC this is linked to LDAP

Name your sheet as Config and add each of the parameters to sheet starting in cell B3.

For each parameter, add a named range scoped to the workbook as follows:

pServer, pDatabase, pUsername, pPassword, pCAMNamespace

You should have a sheet that looks something like the below:

On my sheet I have multiple connections and have linked my connection to a list of servers to select and switch as required. You could add this to your solution later to extend it further.

3.   Testing the connection

We will need 4 components before we can test the connection;

  • Base64Encoder to encode our credentials
  • JSON Converter to parse JSON into VBA objects we can deal with
  • A function to perform the query and return the parsed JSON object
  • A process to test our connection to the server

3.1.  Base 64 Encoder

There are various functions available on the web but I used the following:

Option Explicit
Function Base64Encode(text As String) As String
  Dim arrData() As Byte
  arrData = StrConv(text, vbFromUnicode)

  Dim objXML As Variant
  Dim objNode As Variant

  Set objXML = CreateObject("MSXML2.DOMDocument")
  Set objNode = objXML.createElement("b64")

  objNode.DataType = "bin.base64"
  objNode.nodeTypedValue = arrData
  Base64Encode = objNode.text

  Set objNode = Nothing
  Set objXML = Nothing
End Function

Add a new module to your VBA project and call it modRESTAPI or similar. Paste the above function into the module. I like to add Option Explicit to ensure the variables are correctly defined and we don’t encounter surprises.

3.2.  JSON Converter

Download Tim Hall’s module from https://github.com/VBA-tools/VBA-JSON.

Import the module into your VBA project to make it available to our calls.

This makes use of Dictionary data types and requires the Microsoft Scripting Library reference to be selected in Tools, References.

3.3.  Function to Query the REST API

Copy the function below and add to your VBA project in the module you previously created.

Function ExecuteQuery(pAction As String, pQueryString As String, Optional strPayload As String) As Object

    Dim TM1Service As New MSXML2.XMLHTTP60
    
    Dim pServer As String
    Dim pDatabase As String
    Dim pUsername As String
    Dim pPassword As String
    Dim pCAMNamespace As String
    
    Dim sBase64Credentials As String
    
    Dim sQueryString As String
    Dim sQueryResult As String
    
    Dim bAsynch As Boolean
    
    Sheets("Config").Calculate
    
    pServer = ThisWorkbook.Names("pServer").RefersToRange
    pDatabase = ThisWorkbook.Names("pDatabase").RefersToRange
    pUsername = ThisWorkbook.Names("pUsername").RefersToRange
    pPassword = ThisWorkbook.Names("pPassword").RefersToRange
    pCAMNamespace = ThisWorkbook.Names("pCAMNamespace").RefersToRange
       
    sBase64Credentials = Base64Encode(pUsername & ":" & pPassword & ":" & pCAMNamespace)

    With TM1Service
            'Query design for PAOC but could add in some code to look for ibmcloud.com and use the below or a local endpoint
            sQueryString = pServer & "tm1/api/" & pDatabase & "/api/v1/" + pQueryString
             
            If UCase(pAction) = "POST" Then
               bAsynch = True
            Else
               bAsynch = False
            End If
             
            .Open pAction, sQueryString, bAsynch
             
            .setRequestHeader "Content-Type", "application/json"
            .setRequestHeader "Accept", "application/json;odata.metadata=none"
            .setRequestHeader "TM1-SessionContext", "TM1 REST API tool"
            .setRequestHeader "Authorization", "CAMNamespace " & sBase64Credentials
           
            .Send strPayload
             
            While .readyState <> 4
                DoEvents
            Wend
            
            If .Status >= 400 And .Status <= 599 Then
                sQueryResult = CStr(.Status) + " - " + .statusText
                If .responseText <> "" Then
                    sQueryResult = sQueryResult + vbCrLf & .responseText
                End If
                MsgBox "Error " + sQueryResult, vbCritical, "Connection"
                GoTo Cleanup
            End If
        
        sQueryResult = .responseText
        
        'This outputs the JSON to the Immediate window.
        'You can copy this to a viewer like http://jsonviewer.stack.hu/ to interrogate the JSON
        Debug.Print sQueryResult
        
    End With
    
    If sQueryResult <> "" Then
        Set ExecuteQuery = JsonConverter.ParseJson(sQueryResult)
    Else
        Set ExecuteQuery = Nothing
    End If
    
Cleanup:
        
End Function

Be sure to go to Tools, References and tick Microsoft XML, v6.0 from available references as the TM1Service leverages this.

A walk-through of what the function does:

All the server parameters required are retrieved

Username, password and CAMNamespace are concatenated then Base64 encoded for authentication.

The query string is built based on the parameters passed from the underlying caller process.

Next we need to set the Request Headers for the call we are about to make. This sets the expected content type to JSON and some other settings required.

Note that I am setting odata.metadata=none as I do not need any additional information like the odata.etags. This could also be set to minimal to or removed depending on what you would like to see returned.

I have also set TM1-SessionContext so that I can easily see which are calls from my testing versus other sessions.

We then send the request and get a response. If the response is not ready, we do events then check again.

Our response is then checked to see if we have success or errors. See https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html for more on return codes.

Assuming we have a success code and some JSON returned from the query, we parse the JSON using the JSONConverter and return the result back to the calling process.

If an error was encountered, we show the error and associated text to assist in troubleshooting.

3.4.  Test Function

Our test function is simply going to request the server information and return it to a message box if successfully connected.

Sub GetServer()
    Dim oJSON As Variant
    Dim oKey As Variant
    Dim pQueryString As String
    Dim sResult As String
    
    pQueryString = "Server"
    
    Set oJSON = ExecuteQuery("Get", pQueryString)
    sResult = ""
    
    If Not oJSON Is Nothing Then
        For Each oKey In oJSON
            sResult = sResult & oKey & " - " & oJSON(oKey) & vbCrLf
        Next
        MsgBox sResult, vbInformation, "Server Details"
    End If

End Sub

You should be able to run the code to test it or step through it line by line to check what each step is doing.

The JSON returned is returned to an object which in this case is a dictionary object i.e. key and value pairs.

The code loops through each key and returns the associated value to a string then pops the result up in a message box.

Now that the connection has been successfully tested we can move on to retrieving Sessions and Threads.

4.   Retrieving Sessions and Threads

We want to retrieve both Sessions and Threads in one query. Threads are linked to a Session which means that we can expand Sessions to include the Threads using a query like:

Sessions?$expand=Threads

A session in the resultant JSON should look something like the below:

{
            "ID": 5707,
            "Context": "",
            "Active": true,
            "Threads": [
                {
                    "ID": 13016,
                    "Type": "User",
                    "Name": "LDAP/xxx_tm1_automation ccc_user CAMID("LDAP:u:uid=xxx_tm1_automation,ou=people")",
                    "Context": "",
                    "State": "Run",
                    "Function": "GET /api/v1/Sessions",
                    "ObjectType": "",
                    "ObjectName": "",
                    "RLocks": 2841,
                    "IXLocks": 0,
                    "WLocks": 0,
                    "ElapsedTime": "P0DT00H00M00S",
                    "WaitTime": "P0DT00H00M00S",
                    "Info": ""
                }
            ]
        },...

Threads could contain multiple records for the same Session e.g. where multi-threading is occurring. Note that Threads has square then each Thread has braces. The square brackets are seen as an array whereas the braces are interpreted as a dictionary.

Add a new sheet to the Excel book to return the Session and Threads results.

In my sheet I have a header row on row 7 and return the results to row 8 onwards. Above row 7 I have some space to add command buttons.

Cell A7 contains ID, B7, Context then Active, Thread ID etc. per above JSON.

For Cell A8 I added a named range, scoped to the sheet, called Sessions and added in the text «Start». This indicates the start of my result range but importantly also updates the last cell used for the clear function.

I also added a button to call my macro to make running the process easier.

Add the below code to your module. This will execute the query and return the results to the sheet.

Sub GetActiveSessions()
Dim oJSON As Variant
Dim oSession As Variant
Dim oThreads As Variant
Dim oThread As Variant
Dim oThreadDetail As Variant
Dim pQueryString As String
Dim sResult As String
Dim iRow As Integer
Dim iCol As Integer
Dim sResultRange As String

Application.EnableEvents = False
Application.ScreenUpdating = False


'Clear old rows
sResultRange = "Sessions"
Range(Range(sResultRange), Range(sResultRange).SpecialCells(xlLastCell)).EntireRow.Clear

pQueryString = "Sessions?$expand=Threads"
Range("qryREST").Value2 = pQueryString

Set oJSON = ExecuteQuery("Get", pQueryString)
sResult = ""

If Not oJSON Is Nothing Then
    iRow = 0
    For Each oSession In oJSON("value")
        iCol = 0
        For Each oThreads In oSession
            If oThreads <> "Threads" Then
                Range(sResultRange).Offset(iRow, iCol).Value2 = oSession(oThreads)
                iCol = iCol + 1
            Else
                'Threads - defined as oJSON("value")(<item>)("Threads")(<threaditem>)("ID")
                If oSession("Threads").Count > 0 Then
                    For Each oThread In oSession("Threads")
                        iCol = 3
                        For Each oThreadDetail In oThread
                            Range(sResultRange).Offset(iRow, iCol).Value2 = oThread(oThreadDetail)
                            iCol = iCol + 1
                        Next
                        
                        If oThread("ID") <> oSession("Threads")(oSession("Threads").Count)("ID") Then
                            iRow = iRow + 1
                        End If
                    Next
                End If
            End If
        Next
        iRow = iRow + 1
    Next
End If

Application.EnableEvents = True
Application.ScreenUpdating = True

End Sub

With the above code, it may be useful to add some watches to better understand what each object contains.

Per the JSON snippet above, there are Session related properties and then a container of zero of more Threads.

My Sessions sheet looks like the below snippet after running the macro:

You can see the Session detail with the Thread detail alongside. Where there are multiple Threads, these would be iterated starting in column D of subsequent rows.

5.   Cancelling a Thread

Essentially, we want to select a Thread ID and pass this to a REST API action which will request the cancellation.

Add the following code to your module:

Sub ThreadCancel()

    Dim oJSON As Variant
    Dim pQueryString As String
    
    Dim sThread As String
   
    'Thread ID is in column D
    sThread = ActiveCell.EntireRow.Columns(4).Value2
    If sThread = "" Then GoTo Cleanup:
    
    pQueryString = "Threads('" & sThread & "')/tm1.CancelOperation"
    
    Set oJSON = ExecuteQuery("Post", pQueryString)
    
Cleanup:

End Sub

The process will read the Thread ID from column D for the row of the ActiveCell. This value is then sent to the CancelOperation.

You can add another button to your sheet to cancel the Thread by assigning the ThreadCancel process to it.

To test this function, you will need to run a process from PAW or possibly create a simple process with a Sleep function to keep the process running for a few seconds.

The screenshot below shows the Session and the active Threads along with the process being run.

To cancel the Thread, select a cell in the relevant row then click the Cancel Thread button or run your process. 

PAW should then show you a message box that the process has been cancelled (may not show to non-admin users):

 

6.   Summary

You now have a way to check active Sessions and Threads running on a specified server.

You also have a way to cancel a Thread should there be an issue with a process.

You could extend this example by adding to your configuration sheet, catering to multiple connections. You could also change your Cancel Thread process to cater for multiple selected Threads.

These examples have laid the foundation for many more REST API query projects and will allow you to easily extend to querying cubes, dimensions, subsets etc.

Please leave a comment if you found this useful or have something else to say. Let me know too of any errors so that I can address them.

#PlanningAnalyticswithWatson

Hello everyone. In this post, we are going to look at how to make a rest API call from VBA. That is what we are going to learn in this post. And this is a sample API which going to return this dummy data user object. You can download the source code at the bottom of the post.

We are going to cover the below point in this article

  • Getting a JSON response from a REST API with VBA excel
  • How do JSON POST requests in Excel VBA
  • Parse API response data in VBA

And this is the URL: https://reqres.in/api/users/2

{
"data": {
"id": 2,
"email": "janet.weaver@reqres.in",
"first_name": "Janet",
"last_name": "Weaver",
"avatar": "https://reqres.in/img/faces/2-image.jpg"
},
"support": {
"url": "https://reqres.in/#support-heading",
"text": ""
}
}

if you make an API call with this get request, you will get on the dummy data user ID, email,first_name,last_name, image, etc.

How to call rest api from excel vba and parse json response return by rest Api

And this is what we are going to use that in our script.  Excel doesn’t have a built JSON parser. So we are going to use VBA-tools JSON parser which helps us to parse the JSON that we receive after making a get request.

And we have to pass this JSON object as a parameter to this VBA JSON or method so that we can easily parse the object and get a value that we are looking for.

So go to the Git link : https://github.com/VBA-tools/VBA-JSON

So just click on the download code and it will be downloaded in the zip format.

json vba

And now go to your Excel sheet. I have already created a blank Excel format. so go to the developer tool and visual basic.

Vba

So now you can see the visual basic IDE and go to insert, and insert a form and add two button control on it.

Inset form in vba

Create Vba form

So before writing a script, we need to do some import.

The first thing is we need to import the JSON converter that we download from Github. Go to File and click on Import file. So I have already exported the zip

so this is the folder that I extracted go inside this folder and select the JsonConverter.bas And click on Open.

Open bas file

You can see a new module here, so it imported all the scripts which are present on the Bas file.

jsonconverter

So now go back to the Form and click on Tools and select references. And now we are going to deal with a dictionary.

So enable the Microsoft scripting runtime references that you can find it in the list scroll down. So here you can see Microsoft Scripting runtime, select and click on OK.

msscript

So let write API calling code on button click of each button i.e GetUser and CreateUser and write code for calling the rest api.

Using Excel and VBA to get rest API data

Click on GetUser and wrute below code

so let me create a variable called objRequest and the data type is the object and we need to store the endpoint URL in a string. So let me create a variable called strUrl .

Private Sub CommandButton1_Click()
    Dim JsonObject As Object
    Dim objRequest As Object
    Dim strUrl As String
    Dim blnAsync As Boolean
    Dim strResponse As String
    
    Set objRequest = CreateObject("MSXML2.XMLHTTP")
    strUrl = "https://reqres.in/api/users/2"
    blnAsync = True

    With objRequest
        .Open "GET", strUrl, blnAsync
        .setRequestHeader "Content-Type", "application/json"
        .setRequestHeader "Authorization", "Bearer " & token
        .Send
        'spin wheels whilst waiting for response
        While objRequest.readyState <> 4
            DoEvents
        Wend
        strResponse = .responseText
    End With
     Set JsonObject = JsonConverter.ParseJson(strResponse)
     MsgBox (JsonObject("data")("email"))
End Sub

It should be the string format and we are going to make the request using XMLHttpRequest and where to make a request, blnAsync as you need to pass a boolean value true or also whether you are making a sync operation or not.

And finally, after we get the response, we are going to pass it and store it in a variable. name this variable as JsonObject  and data type is an object so that’s it. We have created all the variables that we need to make the HTTP call.

and then filanly we are Parsing String Response From API inVBA. So let’s show this response to a message box and see whether it actually makes an API call or makes sure that we are getting the response or not. we are extracting the “email” from the api response, showing it in a message box.

Now let’s click on “Getuser” button, So we got the response and it successfully makes a get request.

Json get api result

Excel VBA HTTP post request json

Private Sub CommandButton2_Click()
    Dim objHTTP As Object
    Dim Json As String
    Dim Jsonresult As Object
    Json = "{""name"":""Mark Henry"",""job"":""Project Manager""}"
    'here I am pulling creating json body
    Dim result As String

    Set objHTTP = CreateObject("MSXML2.ServerXMLHTTP")
    URL = "https://reqres.in/api/user"
    objHTTP.Open "POST", URL, False

   objHTTP.setRequestHeader "Content-type", "application/json"
   objHTTP.Send (Json)
   result = objHTTP.responseText
   Set Jsonresult = JsonConverter.ParseJson(result)
   MsgBox ("User created with name :" & Jsonresult("name"))

End Sub

we have set the request header using ssetRequestHeader and you have to specify the key-value, Content-type, and application/json. And so we have to specify that as an argument here, application/json. we are going to get the response in the form of JSON our next line.

Download Source Code

The post [Solved]-How to call rest api from Excel macros vba and Parse Json appeared first on Software Development | Programming Tutorials.

Read More Articles

  • How can I retrieve JSON from an HTTP endpoint, from within Excel on MacOS, and parse it?
  • How to read from a text (.txt) file and place data into an excel 2016 document using VBA Macros editor?
  • How to fix and extract google CSE JSON API results with excel vba
  • How can I read a HTTP-header while making an API call from Excel VBA using JSON?
  • How to call a C# function from VBA and Excel
  • How to copy «specific» rows from one sheet and paste in to another in an excel using VBA Macros
  • How to Call VBA Function from Excel Cells?
  • How do I call VBA code in an Excel spreadsheet from Java?
  • How to call Excel VBA functions and subs using Python win32com?
  • How to find and call javascript method from vba
  • How do I call an Oracle stored procedure from an Excel VBA script?
  • How to load vba macros to the excel file from a text file by a C# code?
  • How to call an Excel VBA Macro from Java Code?
  • Excel VBA — call same macro from both Ribbon and AutoOpen
  • Passing a LPCTSTR parameter to an API call from VBA in a PTRSAFE and UNICODE safe manner
  • How to call VBA function from excel
  • How to instantiate a vba class and call a method from vb.net?
  • How to make VBA count from 0 and not 1 in Excel Macro
  • VBA — How to download .xls from website and put data into excel file
  • How to call Word macros from Excel
  • How to delete a column of a table and shift the rest to the left without affecting the previous tables in excel vba
  • Excel VBA — How to get data from multiple-array JSON into columns
  • How to copy column data from one sheet and then copy that to another sheet in vba excel
  • Using VBA and VBA-JSON to access JSON data from WordPress API
  • How can I extract a specific Letter(s) and numbers from a text string via VBA Or excel Formula
  • how to get path input from textbox and use in command button in vba macros
  • How to retrieve data from other Excel using VBA and SQL?
  • Excel VBA macro using iTunes search API — fastest way to query & parse JSON results
  • In VBA how do I write a script to copy a button from one worksheet to a worksheet in a different note book(without recording macros and using .select)
  • How to set a variable equal to a json value from another variable excel vba
  • Append data to beginning of CSV file
  • before save validation on vba
  • VBA Split String Loop
  • Copying to a Macro if there is a «-» in a certain cell (VBA)
  • Get list of all user with attributes from AD with VBA
  • Validation List automatically convert string as date in VBA
  • Programmatically add sound effects to the soundeffect library in a PowerPoint presentation
  • Debug is finding an error 91 with an intersect(target, [range variable]).value
  • Copy specific lines from text files into excel
  • Access Continuous form based on recordest made with VBA (fill the form fields)
  • Is there a way to store all Excel VBA Google searches in a separate sheet in the Excel file?
  • VBA Loop search by text,offset then incremnt
  • Extracting data from a dynamic userform VBA
  • Add a commandbutton with a macro assigned
  • VBA macro multiplying column with outside cell, if certain criteria is met
  • How to make a VBA script (that runs on Command Button Click) reflect data that has changed after I saved the script?
  • Find range between two words and iterate through it with loop
  • Excel VBA to replace column values with another value?
  • Finding the n-th cell in a column with a given property
  • Controlling Encrypt and Digitally Sign buttons in Outlook 2007 or later

Содержание

  1. How to use Excel VBA to query REST JSON APIs
  2. Creating a blank worksheet
  3. Creating the macro to query the API
  4. Importing the VBA-JSON library
  5. Enabling Microsoft Scripting Runtime
  6. Creating the VBA macro to query the REST API
  7. Conclusion
  8. rpharrison/Excel-REST
  9. Sign In Required
  10. Launching GitHub Desktop
  11. Launching GitHub Desktop
  12. Launching Xcode
  13. Launching Visual Studio Code
  14. Latest commit
  15. Git stats
  16. Files
  17. README.md
  18. Как Excel и VBA помогают отправлять тысячи HTTP REST API запросов
  19. Часть 1. Реализация решения под Windows
  20. Часть 2. Реализация решения под MacOS и Excel 64-bit

How to use Excel VBA to query REST JSON APIs

Excel is probably one of the most used tools in this world, so the demand for integrations with extremely complex spreadsheets is a recurring scenario. APIs allow easy access to information in systems, which is becoming more and more standard in the market, with that in mind, some demands of connecting to systems via API in Excel are necessary and very useful, so I decided to share a little how I created this integration. Let’s learn how to query Rest APIs using VBA and convert the result to JSON for use in the spreadsheet.

This article hopes you will know the basics of Excel and VBA, as well as what is an API and how it works . Our goal will be to consult a Public Pokemon API and list the result in the tab results .

Creating a blank worksheet

First let’s create a blank sheet with macro enabled, inside it I’ll create a tab called results .

Creating the macro to query the API

by shortcut alt + f11 let’s open the Excel macro editor, and create a module called list pokemons .

Importing the VBA-JSON library

As the API we’re going to query returns a JSON as an answer we will need to import the library VBA JSON , it will take care of all the boring work of translating the JSON and returning as an array and object. Installation is very simple, just download the latest version here and in the macro editor go to File > Import File > JsonConverter.bas .

Enabling Microsoft Scripting Runtime

We also need to enable Microsoft Scripting Runtime, to do this just browse Tools > References and search and enable in the list the Microsoft Scripting Runtime .

Creating the VBA macro to query the REST API

Below is the complete code for our request, it might sound scary, but don’t worry, I’ll explain what each part is doing:

First we define all the variables that we will use in our scripts, including the VBA JSON library import that we previously imported into our project.

Then we select the spreadsheet we want to display the results of the API query, in our case Worksheets(«results») and then we create an object that will allow us to make the request to the API. https://pokeapi.co/api/v2/pokemon . We’ll take the answer and put it in the variable json , for now it is nothing more than a text.

Here where the magic happens, the function parsejson from the VBA JSON library converts the text of our variable json for an accessible object in our script. We are now able to access all properties programmatically in our code.

Now that we have the result of our API accessible, we create in the first row of the spreadsheet the header containing the columns Name and link .

We are interested in the property. results , an array containing a list of pokemons with their names and links to more details. We will access this matrix at jsonobject(«results») and we will loop to display each pokemon result in a new row of our table.

If everything goes as expected, by pressing f5 to run our macro, in your spreadsheet you should see the following result:

Conclusion

This was a very simple example of a query, with the object of HT TP it is possible to perform all types of requests, GET, POST, UPDATE, … The interesting thing is to understand how the request is made and how you can display the result, thanks to the VBA JSON library, which already drastically reduces the work required. Now you just need to adapt this flow and script to your needs.

Источник

rpharrison/Excel-REST

Use Git or checkout with SVN using the web URL.

Work fast with our official CLI. Learn more.

Sign In Required

Please sign in to use Codespaces.

Launching GitHub Desktop

If nothing happens, download GitHub Desktop and try again.

Launching GitHub Desktop

If nothing happens, download GitHub Desktop and try again.

Launching Xcode

If nothing happens, download Xcode and try again.

Launching Visual Studio Code

Your codespace will open once ready.

There was a problem preparing your codespace, please try again.

Latest commit

Git stats

Files

Failed to load latest commit information.

README.md

VBA-Web (formerly Excel-REST) makes working with complex webservices and APIs easy with VBA on Windows and Mac. It includes support for authentication, automatically converting and parsing JSON, working with cookies and headers, and much more.

  • Download the latest release (v4.1.6)
  • To install/upgrade in an existing file, use VBA-Web — Installer.xlsm
  • To start from scratch in Excel, VBA-Web — Blank.xlsm has everything setup and ready to go

For more details see the Wiki

To upgrade from Excel-REST to VBA-Web, follow the Upgrading Guide

Note: XML support has been temporarily removed from VBA-Web while parser issues for Mac are resolved. XML support is still possible on Windows, follow these instructions to use a custom formatter.

  • Authentication support is built-in, with suppory for HTTP Basic, OAuth 1.0, OAuth 2.0, Windows, Digest, Google, and more. See Authentication for more information
  • For proxy environments, Client.EnabledAutoProxy = True will automatically load proxy settings
  • Support for custom request and response formats. See RegisterConverter

The following examples demonstrate using the Google Maps API to get directions between two locations.

There are 3 primary components in VBA-Web:

  1. WebRequest for defining complex requests
  2. WebClient for executing requests
  3. WebResponse for dealing with responses.

In the above example, the request is fairly simple, so we can skip creating a WebRequest and instead use the Client.GetJSON helper to GET json from a specific url. In processing the response, we can look at the StatusCode to make sure the request succeeded and then use the parsed json in the Data parameter to extract complex information from the response.

If you wish to have more control over the request, the following example uses WebRequest to define a complex request.

The above example demonstrates some of the powerful feature available with WebRequest . Some of the features include:

  • Url segments (Replace in resource with value)
  • Method (GET, POST, PUT, PATCH, DELETE)
  • Format (json, xml, url-encoded, plain-text) for content-type and accept headers and converting/parsing request and response
  • QuerystringParams
  • Body
  • Cookies
  • Headers

For more details, see the WebRequest portion of the Docs

The following example demonstrates using an authenticator with VBA-Web to query Twitter. The TwitterAuthenticator (found in the authenticators/ folder) uses Twitter’s OAuth 1.0a authentication and details of how it was created can be found in the Wiki.

For more details, check out the Wiki, Docs, and Examples

Источник

Как Excel и VBA помогают отправлять тысячи HTTP REST API запросов

Работая в IoT-сфере и плотно взаимодействуя с одним из основных элементов данной концепции технологий – сетевым сервером, столкнулся вот с какой проблемой (задачей): необходимо отправлять много запросов для работы с умными устройствами на сетевой сервер. На сервере был реализован REST API с оболочкой Swagger UI, где из графической оболочки можно было отправлять только разовые запросы. Анализ сторонних клиентов, типа Postman или Insomnia показал, что простого визуального способа поместить в скрипт массив из необходимого перечня идентификаторов устройств (или любых других элементов сервера), для обращения к ним – не нашлось.

Так как большая часть работы с выгрузками и данными была в Excel, то решено было вспомнить навыки, полученные на учебе в университете, и написать скрипт на VBA, который бы мою задачку решал.

получать информацию по устройствам с различными параметрами фильтрации (GET);

применять изменения в конфигурации по устройствам: имя, профиль устройства, сетевые лицензии и пр. (PUT);

отправлять данные для конфигурации и взаимодействия с устройствами (POST).

И сегодня я расскажу вам про то, как с помощью Excel, пары формул и самописных функций на VBA можно реализовать алгоритм, отправляющий любое необходимое количество REST-API запросов с использованием авторизации Bearer Token.

Данная статья будет полезная тем, кто воспользуется данным решением под Windows, но еще больше она будет полезна тем людям, которые хотят использовать данное решение на MacOS (с Excel x64). Как вы уже догадались, ниже будут рассмотрены два варианта реализации под разные системы, так как с MacOS есть нюанс.

Часть 1. Реализация решения под Windows

GET

Начнем с самого простого: GET – запросов. В данном примере необходимо получить ответ (информацию) от сервера по заданному списку устройств.

Для реализации GET – запросов нам дано:

1) Ссылка, в которой указываются параметры запроса.

2) Заголовки запроса + Токен авторизации (Bearer Token)

—header ‘Accept: application/json’ —header ‘Authorization: Bearer

3) Параметр, указываемый в ссылке (в данном примере это идентификаторы устройств – DevEUI):

Имея такие данные на входе, делаем в Excel лист-шаблон, который заполняем в соответствии с тем, что имеем:

столбец А уходит вот значения параметров

столбец F уходит под ссылку-родителя

столбец H уходит под заголовки, где в ячейке H1 единоразово для текущего листа указывается токен:

=СЦЕП(«—header ‘Accept: application/json’ —header ‘Authorization: Bearer «;$H$1;»‘»)

столбец I уходит под URL (ссылки-дети, на основе ссылки-родителя)

столбец J уходит под результат (ответ от сервера)

Шаблон листа для GET-запросов

Далее, нам необходимо реализовать подпрограмму(макрос) отправки GET-запросов. Состоит она из четырех частей:

цикла, который считает количество строк для работы по листу, пробегая по столбцу А с 2 по первую пустую ячейку, чтобы у цикла был конец.

функции, для работы с REST API (используется стандартная, библиотека Msxml2.XMLHTTP.6.0, встроенная в Windows., поэтому сложностей с реализацией не возникает. Для MacOS есть альтернатива)

временной задержки, в случае если нужно отправлять запросы не сразу, после получения ответа, а задав время ожидания

таймером, который показывает время выполнения всего макроса после завершения

Привязываем подпрограмму к кнопкам для удобства и выполним скрипт. Получается:

Таким образом, скрипт проходит по столбцу I, забирая из значения каждой ячейки URL, для тех строк, где в столбце А есть значения (которые и подставляются в URL). Для удобства также сделаны кнопки очистки полей и подсветка запросов условным форматированием, в случае успешного ответа на запрос.

PUT

Чуть-чуть усложним задачу и перейдем к PUT-запросам. В данном примере необходимо изменить профиль устройства, чтобы сервер по-другому с ним взаимодействовал.

К исходным данным для GET – запроса добавляется тело запроса с ключем-значением (п4). Итого дано:

1) Ссылка, в которой указываются параметры запроса.

2) Заголовки запроса + Токен авторизации (Bearer Token)

—header ‘Content-Type: application/json’ —header ‘Accept: application/json’ —header ‘Authorization: Bearer

3) Параметр, указываемый в ссылке (в данном примере это внутренние идентификаторы устройств – hRef):

4) Тело запроса, с ключом и значением:

Немного дополняем новый PUT-лист в Excel по сравнению с GET (остальное без изменений):

новый столбец B теперь отвечает за ключ deviceProfileId (ячейка B1), а все значения ниже за его возможные значения)

столбец D отвечает за формирование итогового тела сообщения в формате JSON.

Немного поменяем макрос и вынесем его в отдельную подпрограмму:

Привяжем макрос к кнопке и выполним.

Логика абсолютно аналогична GET запросу.

POST

Для POST запросов все аналогично PUT. Только немного меняется код в части типа запроса. В данном примере на устройство отправляется команда-конфигурация с указанием тела посылки (payload_hex) и порта (fport) для конкретного устройства.

Получившаяся таблица выглядит следующим образом:

На этом часть для Windows заканчивается. Здесь все оказалось довольно просто: стандартная библиотека, простенький алгоритм перебора значений в цикле.

Часть 2. Реализация решения под MacOS и Excel 64-bit

В виду того, что работал я на двух машинах под управлением разных ОС, хотелось, чтобы решение было универсальным. В итоге, собрав по крупицам информацию по интернет-форумам с данной тематикой у меня вышло следующее решение. Принцип работы его остается схожим, а изменения были внесены в часть, где использовалась стандартная библиотека WindowsMsxml2.XMLHTTP.6.0, которой в MacOS не было по понятным причинам.

Чтобы обойти данное ограничение, был выбран единственный рабочий подход через cUrl, exec и функции. Данное решение точно работает под версией MacOS 10.14 и Excel 16.51. Функция ниже, в том или ином виде, встречается на различных форумах, однако на текущих версиях софта – не работает. В итоге, после небольших правок получили рабочий вариант:

Была отлажена функция вызова ExecShell:

И написаны отдельные функции для работы с различным методами GET / PUT / POST, которые на входе принимают URL и параметры):

Так как мы заменяем библиотеку Msxml2.XMLHTTP.6.0 – поменялась реализация макросов в этой части: мы заменили Msxml2 на написанные выше функции и получили следующее:

В итоге, у меня получилось аналогичное windows по работе и функционалу решение для MacOS c использованием Excel 64-bit.

На просторах интернета я не нашел какого-то сборного и единого описания, только фрагменты кода и подходов, которые в большинстве случаев не работали полностью или частично. Поэтому решил объединить все в рабочее решение и выложить на хабр для истории.

На текущий момент я все еще не встретил иного решения, которое бы позволяло в пару кликов копипастить тысячи идентификаторов и параметров из excel и массово их отправлять на сервер. Надеюсь, кому-то пригодится 🙂

Если такие сторонние решения есть, а я не в курсе, и все можно было сделать проще, быстрее и изящнее – делитесь опытом в комментариях.

Файл-пример, который можно потыкать, пока жив сервер и «бессрочный» токен:

Источник

Понравилась статья? Поделить с друзьями:
  • Excel vba resize что это
  • Excel vba replace примеры
  • Excel vba replace with
  • Excel vba replace what
  • Excel vba inputbox дата