Доступ к веб содержимому excel через api

Power Query умеет подключаться не только к web страничкам, но и к API, не требующим авторизации. Если API позволяет анонимным пользователям забирать данные, Power Query подойдёт идеально.  

Подключимся к API застройщика, чтобы отслеживать актуальную стоимость квартиры. Находим нужную квартиру на сайте застройщика: https://beta.pik.ru/flat/801472.

«https://api.pik.ru/v1/flat?id=» — URL адрес, по которому застройщик предоставляет информацию, а «801472» – идентификатор квартиры.

Информация на сайте показана красиво, но разбросана по разным вкладкам.
Мы же хотим получить лаконичную табличку в Excel:

Адрес
Стоимость
Скидка
Заселение до
Площадь
Комнаты
Этаж
Ссылка
PDF

GET-запрос к API ПИК на Power Query

Для разнообразия воспользуюсь Power Query в Excel. Создаем пустой запрос:

В строке формул пишем: 

Json.Document(Web.Contents("https://api.pik.ru/v1/flat?id=801472"))

В результате получаем строку с вложенными составными элементами, которые также могут содержать вложенные элементы:

Называем запрос «getData_oneFlat» и вставляем пустой шаг после шага Источник (чтобы открыть меню — щелкаем правой кнопкой мышки на шаг Источник):

С помощью функции Record.FromList формируем строку с нужными данными, используя шаг Источник. В строке формул пишем: 

Record.FromList(
{Источник[block][address], Источник[price], Источник[discount], Источник[bulk][date_till], Источник[area], Источник[rooms], Источник[floor], Источник[url], Источник[pdf]}, 
type [ Адрес = text, Стоимость = number, Скидка = number, Заселение до = text, Площадь = number, Комнаты = number, Этаж = number, Ссылка = text, PDF = text])

Давайте разбираться как работает функция Record.FromList:

  1. Первый аргумент функции отвечает за содержимое полей – это список: 
    {Источник[block][address], Источник[price]}
  2. Источник[price] – возвращает содержимое поля price
  3. Источник[block][address] – возвращает содержимое поля address из Record вложенной в поле block
  4. Второй аргумент отвечает за названия и тип полей – это строка: 
    type [Адрес = text, Стоимость = number]

Результат — строка нужных нам значений:

Преобразуем строку в таблицу:

Выгрузим результат на лист Excel и посмотрим что получилось:

Такой формат нас устроит, теперь мы видим всю информацию по квартире в удобной таблице. 

Несколько GET-запросов с помощью функции

Теперь попробуем забрать сразу несколько квартир и разместить их в одной табличке. 

Для этого убираем последний шаг и создаём функцию getData от параметра flat (номер квартиры), заменяя сам номер на «flat»:

(flat as text)=>
let
   Источник = Json.Document(Web.Contents("https://api.pik.ru/v1/flat?id="& flat )),
   create_table = Record.FromList(
{Источник[block][address], 
Источник[price], 
Источник[discount], 
Источник[bulk][date_till], 
Источник[area], 
Источник[rooms], 
Источник[floor],
Источник[url],
Источник[pdf]
},
type [
Адрес = text, 
Стоимость = number, 
Скидка = number, 
Заселение до = text, 
Площадь = number, 
Комнаты = number, 
Этаж = number,
Ссылка = text,
PDF = text
])
in
   create_table

Теперь наша функция будет получать данные по той квартире, которую мы укажем в параметре.

Составляем на листе Excel список интересных нам квартир:

Загружаем список квартир в Power Query, выставляем столбцу текстовый тип. Затем добавляем новый столбец с вызовом нашей функции от каждой квартиры в списке, получается такой код:

let
   Источник = Excel.CurrentWorkbook(){[Name="Таблица2"]}[Content],
   #"Измененный тип" = Table.TransformColumnTypes(Источник,{{"Получаемые квартиры", type text}}),
   #"Вызвана настраиваемая функция" = Table.AddColumn(#"Измененный тип", "getData", each getData([Получаемые квартиры]))
in
   #"Вызвана настраиваемая функция"

Таблица в Power Query выглядит так:

Нажимаем на стрелочки справа от «getData» и разворачиваем нужные столбцы, а затем выгружаем всё на лист Excel. Теперь у нас есть табличка со стоимостью, скидками, площадью и датами заселения для всех интересных нам объектов:

Заключение

Пример вызова API сайта компании ПИК показывает как Power Query может быть полезен в бытовых задачах. Используйте PQ если вам нужно быть в курсе изменений данных, будь то стоимость квартиры или цена товара в интернет-магазине. 

Если компания предоставляет данные по открытому API, вы всегда можете использовать магию Power Query и вывести эти данные себе в Excel-файл. Можно сравнить несколько товаров/категорий или вообще написать алгоритм, который будет отображать только самые интересные товары. 

 

mitridat

Пользователь

Сообщений: 4
Регистрация: 23.09.2017

Всем привет. Ищу совета. Поиск курил, но не нашел ничего, возможно я совсем нуб.
Возникла  необходимость как то транслировать  курсы валют с биржи в таблицу Excel. Для более  удобного анализа и последующих расчетов.

Пробовал вставлять через: Данные — Импорт внешних данных — Создать веб-запрос
Но на

сайте биржи

это не работает, сценарии не исполняются, короче там не просто таблица, к тому же она на нескольких страницах.

Понимаю, что надо правильнее всего использовать API, он есть на бирже. но как подключиться через эксель я не знаю. Подскажите пожалуйста!

Надеюсь на Вашу помощь.

 

mitridat

Пользователь

Сообщений: 4
Регистрация: 23.09.2017

В APi есть к примеру код

https://bittrex.com/api/v1.1/public/getmarketsummaries

Он выдает данные нужные, как их сделать табличного вида? и как сделать чтоб они постоянно подгружались.

 

Андрей VG

Пользователь

Сообщений: 11878
Регистрация: 22.12.2012

Excel 2016, 365

Доброе время суток.
Самое простое воспользоваться Power Query для импорта данных в формате JSON. Ну, или в VBA — темы уже обсуждались поищите по Json.
Успехов.

Прикрепленные файлы

  • bjson.xlsx (50.3 КБ)

 

mitridat

Пользователь

Сообщений: 4
Регистрация: 23.09.2017

Это то что нужно!!! Волшебство!!! Спасибо буду разбираться!!

 

mitridat

Пользователь

Сообщений: 4
Регистрация: 23.09.2017

Андрей VG, Очень вам благодарен, не могли бы вы уточнить что и куда в вставляли в power query, чтоб получить таблицу такого вида?

 

Андрей VG

Пользователь

Сообщений: 11878
Регистрация: 22.12.2012

Excel 2016, 365

#6

23.09.2017 13:27:13

Цитата
mitridat написал:
не могли бы вы уточнить что и куда в вставляли в power query, чтоб получить таблицу такого вида?

В приложенном файле в расширенном редакторе Power Query можно посмотреть код, формирующий результирующую таблицу. А базовый в редакторе формируется Создать источник/Другие источники/Интернет Ну, а дальше трансформации по смыслу, я их просто в одну функцию собрал, подобно тому, как это делают с формулами на листе, как напишут чего-нибудь на 100500 символов, так без бутылки не разберёшься :)

 

phantom_c

Пользователь

Сообщений: 8
Регистрация: 03.10.2017

Приветствую! С таким запросом как в примере проблем не возникало. Но вопрос похожий. Тоже запрос делается к бирже. GET запрос JSON. Но выдает такую ошибку. А если делать запрос из интернета, то скачивается файл с расширением JSON. Подскажите как быть, куда копать?  

ссылка

Изменено: phantom_c03.10.2017 11:48:02
(добавил скрин)

 

Андрей VG

Пользователь

Сообщений: 11878
Регистрация: 22.12.2012

Excel 2016, 365

#8

03.10.2017 16:48:29

Цитата
phantom_c написал:
Подскажите как быть, куда копать?

Вы не одиноки

в этой проблеме. Какой-то вариант там есть. Если выйдет отпишитесь.

 

phantom_c

Пользователь

Сообщений: 8
Регистрация: 03.10.2017

Андрей VG, спасибо за ссылку, будем посмотреть )

 

phantom_c

Пользователь

Сообщений: 8
Регистрация: 03.10.2017

#10

03.10.2017 18:16:26

Андрей VG, Спасибо Вам огромное! Ссылка ваша очень помогла! А теперь решение проблемы:

Код
let
    BufferedBinary = Binary.Buffer(Web.Contents("http://vote.sos.ca.gov/returns/president/party/democratic/county/all")),
    TextStep1 = Text.FromBinary(BufferedBinary),
    TextStep2 = Text.Replace(TextStep1, "#(cr,lf)", "#(lf)"),
    TextStep3 = Text.Replace(TextStep2, "#(lf)", "#(cr,lf)"),
    Table = Web.Page(TextStep3)
in
    Table

ну а после уже преобразуем как нам надо )
Но все равно выдает ту-же ошибку при попытке обновить данные
Чуть позже еще поковыряю)
главное начать…

 

fedor1981

Пользователь

Сообщений: 6
Регистрация: 11.01.2018

Ничего не выходит. Уже неделю мучаюсь с этой проблемой. Кто-нибудь нашел решение?

Изменено: fedor198111.01.2018 13:05:47

 

phantom_c

Пользователь

Сообщений: 8
Регистрация: 03.10.2017

fedor1981, всего неделю… я так и не смог решить данную проблему ( а прошло больше 3 месяцев ((
единственный вариант (как мне кажется) через vba

 

Jungl

Пользователь

Сообщений: 830
Регистрация: 18.01.2016

#13

11.01.2018 13:02:18

Цитата
fedor1981 написал:
Уже неделю мучаюсь

у меня при переходе по ссылке выдает «vote.sos.ca.gov -Access Denied», вы уверены, что не зря мучаетесь?

 

Юрий М

Модератор

Сообщений: 60578
Регистрация: 14.09.2012

Контакты см. в профиле

fedor1981, вернитесь в своё сообщение и удалите то, что Вы считаете цитатой. И запомните: кнопка цитирования не для ответа!

 

fedor1981

Пользователь

Сообщений: 6
Регистрация: 11.01.2018

 

phantom_c

Пользователь

Сообщений: 8
Регистрация: 03.10.2017

Jungl, та ссылка просто как пример была, скопипастил вариант решения ))
а нужно например вот это

ссылка

 

fedor1981

Пользователь

Сообщений: 6
Регистрация: 11.01.2018

Перечитал их форум. Никто так и не нашел решение проблемы.

 

Jungl

Пользователь

Сообщений: 830
Регистрация: 18.01.2016

fedor1981, ну раз не получается через Power Query, рассмотрите вариант через VBA. Я использовал сплиты, можно регулярками.
Запуск сочетанием клавиш CTRL + Q.

Прикрепленные файлы

  • 96151.xlsm (19.19 КБ)

 

fedor1981

Пользователь

Сообщений: 6
Регистрация: 11.01.2018

Jungl, Класс. Пока единственное решение. Буду пробовать такой вариант. Спасибо за помощь.

 

phantom_c

Пользователь

Сообщений: 8
Регистрация: 03.10.2017

Jungl, спасибо огромное! а можно еще подобное решение для

ссылка

, только там список пар берется

отсюда

?

 

phantom_c

Пользователь

Сообщений: 8
Регистрация: 03.10.2017

Jungl, ну и совсем круто было-бы если к каждой паре прикрутить еще

это

в конец этой ссылки пары добавлять как и предыдущем варианте

Изменено: phantom_c11.01.2018 14:47:29

 

fedor1981

Пользователь

Сообщений: 6
Регистрация: 11.01.2018

phantom_c, У меня есть скрипт на питоне для получения цен с Yobit. Интересно было увидеть такое же решение для Excel.

 

phantom_c

Пользователь

Сообщений: 8
Регистрация: 03.10.2017

fedor1981, на питоне видел, но там получение данных и создание нового файла с записью, а мне кроме получения еще анализ небольшой прикрутить надо будет ) потому и нужны еще и стаканы цен с глубиной хотя-бы до 10, а лучше с выбором глубины…

Изменено: phantom_c11.01.2018 14:54:00

 

Jungl

Пользователь

Сообщений: 830
Регистрация: 18.01.2016

Ребята, я вам не мать-тереза.))
Здесь помогают тем, у кого что-то не получается сделать самостоятельно.
С вашей стороны я не вижу ни файлов примеров, что как должно выглядеть, ни кода. Только ссылки, ссылки мне ничего не дадут, если вы хотите по своему видеть в таблице.

Все это решаемо, если знать откуда-что тянуть. Я вам дал код на одном примере, ваша задача попытаться подстроить под свои нужды.

phantom_c, ваши ссылки не работают кроме info, а желания разбираться в api у меня нет.

 

fedor1981

Пользователь

Сообщений: 6
Регистрация: 11.01.2018

Jungl, И так очень помог. Начало есть.
Возразить нечего. Пошел учить VBA. 8)  

 

illusion51

Пользователь

Сообщений: 2
Регистрация: 22.01.2018

#26

22.01.2018 10:31:27

помогите пожалуйста.. Пытаюсь переделать пример

bjson.xlsx

 под

Цитата
https://yobit.net/api/3/ticker/ltc_btc

вот код запроса

Цитата
let
   Источник = Table.FromRecords(Json.Document(Web.Contents(«https://yobit.io/api/3/ticker/ltc_btc))[ltc_btc]),
   #»Измененный тип» = Table.TransformColumnTypes(Источник,{{«high», type number}, {«low», type number}, {«vol», type number}, {«vol-cur», type number}, {«last», type number}, {«buy», type number}, {«sell», type number}, {«updated», type number}})
in
   #»Измененный тип»

но при обновлении данных появляется ошибка

Цитата
Expression.Error: Не удается преобразовать значение типа Record в тип List.
Подробные сведения:
   Value=Record
   Type=Type

Прикрепленные файлы

  • json yobit.xlsx (22.25 КБ)
  • yobit.jpg (73.15 КБ)

 
 

illusion51

Пользователь

Сообщений: 2
Регистрация: 22.01.2018

вот сделал две версии через json для Yobit
первая обновляет -средние цены
вторая обновляет — крайние цены

данные — обновить

 

exploted

Пользователь

Сообщений: 1
Регистрация: 05.03.2018

Добрый день, тоже борюсь с этой проблемой, пытаюсь вывести цены аск и бид в таблицу эксель.
есть у кого успехи в этом направлении?

 

Alecsmar

Пользователь

Сообщений: 1
Регистрация: 10.12.2018

#30

26.06.2019 00:32:02

Господа, как можно решить такую задачу?
Ссылка на ресурс

https://www.cvk.gov.ua/pls/vp2019/wp335pt001f01=720.html

Если кликать по цифрам во второй колонке таблицы, то открывается другая таблица, инфа из которой как раз нужна. Хотелось бы собрать инфу из каждой страницы в один лист эксель — сквозное копирование, как будто руками.
Хотябы просто скопировать разово, про обновление информации я уже молчу, хотя порой оно требуется несколько раз в день.
В идеале, при вытягивании таблицы из каждой страницы, ее нужно обозначать, т.е. добавить столбец в начало и в него прописывать «номер округа». Но это уже просто хотелки. Если это сложно, то я и ВПРом подтяну это из другой таблицы

This tutorial is for you if you’re an Excel user who would like to learn how to extend your spreadsheets with data from APIs. You might be one of the people who spend most of their workdays in Excel and do calculations and visualizations but still work manually to import or even just copy and paste data from external sources.

If data is available from an API, however, there are various ways in which can consume it directly from Excel, saving you time and preventing errors.

That is, unfortunately, just as long you are using a Windows PC. The integrations presented in this article do not work in Excel for Mac or the web-based version of the Office apps.

BASF provides the Periodic Table of Elements API, which enables you to query the periodic table and retrieve all kinds of information about chemical elements.

We assume you came here from the Introduction to APIs. If not, please check out that document to learn the basics of APIs before continuing.

The Periodic Table of Elements API follows the CRUD/RESTful paradigm but implements only a subset. Specifically, the periodic table is read-only and allows HTTP GET requests exclusively. It is also limited to one resource called «element».

The base URL for the API is https://dev.api.basf.com/chemical/. Every endpoint starts with this URL.

For the elements, there are two endpoints. The first is a collection endpoint that allows you to either retrieve the full periodic table or request a subset of elements through filter parameters. It is called a collection endpoint because it always returns a collection data structure containing multiple items. The second is an individual resource endpoint that allows you to retrieve a single element.

Both endpoints return JSON-formatted responses.

All BASF APIs require authentication. The Periodic Table of Elements API uses an app-only context with an API key. If you haven’t done so, please read the introduction, terminology, and app-only context sections of the Authentication and Authorization guide. You can skip the part on the app and user context and OAuth as it is not required for this API.

To use authentication, you need to create an account and an application. The process gives you a Client ID, which you can then use as your API key. If you do not have an API key, follow the steps outlined in the Get Started guide. Make sure you select the API product BASF Periodic Table while creating your app.

In Excel for Windows, there are three options for getting external data from an API, which we’ll investigate throughout this article.

The first option is the built-in WEBSERVICE() function. Retrieving data from a URL is a single step. However, extracting the information is rather cumbersome as Excel doesn’t understand JSON responses and you have to use string processing functions. Also, as the function only supports the URL as a parameter, this works only with APIs that allow you to provide authentication information as part of the URL. The BASF Periodic Table of Elements API fits the criteria, as it uses a query string for authentication. For other APIs that require custom headers, though, you’re out of luck.

The second option is using VBA, Visual Basic for Applications, to write a Macro in Basic code to consume an API and fill the sheet programmatically. It is the most powerful and flexible option and should work with all kinds of APIs, but it requires you to have some basic programming knowledge.

The third option is the Power Query builder that allows you to gather and combine data from different sources, including APIs. If you have already used the Power Query builder, for example, to access a database directly, this is the sensible way to do it. It’s also a good choice if you do not want to work with code and the WEBSERVICE() option is too limited.

We’ll use an individual resource endpoint with the WEBSERVICE() function as well as the VBA macro, and we’ll demonstrate the collection endpoint with the Power Query builder.

Before we introduce the WEBSERVICE() function, let’s look at functions in Excel in general. They allow you to fill a table cell with computed data. To enter a function into a cell, you start with the equals sign (=), followed by the function name, a left parenthesis [(], your arguments (if needed), and a right parenthesis [)] to end. If there is more than one argument, you separate them with semicolons (;). A common function that you may have used is SUM(), which adds the data from a number of other cells and returns the result. It takes a range of cells as its argument.

The WEBSERVICE() function also takes one argument, a URL. Then, Excel issues an HTTP GET request to fetch whatever is available at that URL, and puts it into the cell as its result. If we want to do an API requests, since the function only allows a single argument, we have to encode the full API request into the URL. As mentioned before, this rules out APIs that require other HTTP methods (such as POST) or custom headers, e.g., for authorization. With the Periodic Table API, however, we put the API key in the URL and only need the GET method.

Open a new Excel workbook, and enter the following line into a cell, replacing the string APIKEY with the previously generated key:

=WEBSERVICE("https://dev.api.basf.com/chemical/elements/He?x-api-key=APIKEY")

Once you hit Enter or click on another cell, you should see a JSON structure describing the Helium element appear in your cell.

As mentioned before, every API endpoint starts with the base URL. For the Periodic Table API, that is https://dev.api.basf.com/chemical/. Then, the path to a resource or collection endpoint follows. In our example, we retrieved a single element, hence, we used a resource endpoint. Typically, the path to a resource starts with the pluralized resource name, followed by a slash (/) and finally an identifier. If you look at the URL above, you can identify elements/He as this path. The question mark (?) separates the parameter section, and you can see the x-api-key parameter that authenticates the request.

We can separate the base URL and the API key from the URL and build the URL dynamically through string concatenation. That is useful if you have multiple requests in the same Excel sheet and, let’s say, you want to share this sheet with another person who then provides a different API key. The other person then only has to enter their API key in one designated cell instead of modifying your API requests.

As next step, we’ll create a sheet that allows users to modify the base URL and API key in one place. We’ll also apply string processing functions to parse a single field from the JSON response. You can follow along these steps. If something is unclear or doesn’t work for you, you can compare your sheet with the screenshots as well as the full Excel workbook that we’ll provide as download further below.

Here we go:

  1. Type «Base URL» in A1 and the base URL https://dev.api.basf.com/chemical/ in B1.
  2. Type «API Key» in A2 and paste your API key from the developer portal in B2.
  3. Type «Element» as a header in A4 and some elements below it. As an example, we’ll put «H» in A5 and «N» in A6.
  4. Type «API URL» as a header in B4. To build the URL, concatenate the following elements: a reference to the field containing the base URL, «elements/», a reference to the field containing the element name, «?x-api-key=», and a reference to the field containing the API key. You need to use absolute references to base URL and API key and a relative reference to the element name. Your function call should look like this: =CONCAT($B$1;»elements/»;A5;»?x-api-key=»;$B$2)
  5. Type «API Response» as a header in C4. Make the webservice call using the URL you built in the previous step by typing =WEBSERVICE(B5) in C5. You should see a JSON API response appear in the cell.
  6. Type «Atomic Mass» as a header in D4. As there is no JSON parser in Excel, we copy a substring from the API response between the atomic_mass field and the subsequent field, covalent_radius. The whole function looks like this: =MID(C5;SEARCH(«atomic_mass»;C5)+13;SEARCH(«covalent_radius»;C5)-SEARCH(«atomic_mass»;C5)-16) You should now see only the atomic mass as a number in the cell.
  7. Select the cells B5 to D5, grab the right bottom corner, and drag them down to the B6 to D6. You should see the API URL, API response and atomic mass for the second element appear.
  8. To get the atomic mass for more elements, add a new element symbol in column A and copy or drag down the three other columns.

Please note that Excel function names are localized along with the Excel user interface. If your Excel installation is in German, replace the names based on this list:

  • CONCAT – TEXTKETTE
  • MID – TEIL
  • SEARCH – SUCHEN

You can get a working Excel workbook in the PeriodicTableWebservice.xlsx file (TODO: add download).

Visual Basic for Applications, or VBA for short, is a powerful programming language that you can use to automate Microsoft Office applications, including Excel. VBA is closely related to, but not fully compatible with, other versions of the Basic language (such as Visual Basic .NET).

If you not worked with VBA before but have programming skills in a different language, you have to learn a new syntax, but should be able to understand the structure of the macro we build in this section.

Our goal is to retrieve various attributes of specific chemical elements (but not the entire periodic table). The sheet layout uses one row per element. The user should enter the element names into the first column of the sheet (A). Then, upon running the macro, it should go through the list of rows and fill the other columns with details. For example, the atomic mass in the second column (B) and the covalent radius in the third column (C).

Open Excel with a new, empty sheet. Then, press the combination Alt and F11 on your keyboard to launch the Visual Basic editor.

On the left side of the editor, you can see the project structure. There’s an entry for your sheet. Double-click on this entry to open the code view where you can enter Basic code that is specific to that sheet.

We start by creating two global string variables, one for the base URL and the API key. It helps us separate them from the code itself so we can swap them if necessary.

Dim baseUrl, apiKey As String

It’s not possible to assign a value to these variables yet. We’ll do that later.

As mentioned under the objective above, we need to retrieve specific elements that the user enters into the sheet, not the full periodic table. For this purpose, we use the API endpoint for specific elements and have to make multiple requests. Hence it is useful to develop an abstraction and put the logic for the API request into a function.

In VBA, you can define functions with the Function keyword. They have parameters with types and a return type. Here is the definition of our getElement() function:

Function getElement(id As String) As Object

Next, we create a script control. That is actually a workaround because there is no native JSON parser available and we don’t want to install a third-party module. The script control can execute JScript, which is a version of JavaScript, and thus understand JSON.

Dim scriptControl As Object
Set scriptControl = CreateObject("MSScriptControl.ScriptControl")
scriptControl.Language = "JScript"

Then, we can make an HTTP request to the API endpoint. VBA makes HTTP requests through the XMLHTTP object. While building the request, we use string concatenation to build the API URL and include the base URL and API key from the variables we defined earlier.

With CreateObject("MSXML2.XMLHTTP")
    .Open "GET", baseUrl + "elements/" + id + "?x-api-key=" + apiKey, False
    .send

Once we have a response, we can parse it with the script control and assign the result to the function name, which is VBA’s way of specifying the returned value for a function:

    Set getElement = scriptControl.Eval("(" + .responsetext + ")")
    .abort

After that, all is left is closing the With-block and the function. The VBA editor might have already generated this code for you automatically.

End With
End Function

Macros are public VBA subroutines. Let’s call ours getPeriodicElementData():

Public Sub getPeriodicElementData()

Inside the subroutine, we first assign some values to our global variables. Add these lines and replace APIKEY with your API key from the developer portal:

baseUrl = [https://dev.api.basf.com/chemical/](https://dev.api.basf.com/chemical/)
apiKey = "APIKEY"

Then, as we want to go through our sheet row by row to get element data, we set up a counter variable:

Dim row As Integer
row = 1

Our algorithm goes through all rows until it stops at an empty row. We can achieve this with a Do-Until-loop:

Do Until IsEmpty(Cells(row, 1))

Inside the loop, we call our getElement() function we created in the previous section. By using a With-block, we can access the attributes of the elements directly and write them in the cells. Our sample code reads two attributes, atomic mass and covalent radius, which go in the row of the current element and the second or third column respectively.

    With getElement(Cells(row, 1))
        Cells(row, 2) = .atomic_mass
        Cells(row, 3) = .covalent_radius
    End With

If you want, you can extend this code with more properties from the element object and put them in additional columns. Tip: Use the WEBSERVICE() function to get the full JSON structure so you can see the available properties.

Afterwards, make sure to increase the row variable, otherwise you have an infinite loop:

    row = row + 1

Finally, we close the loop and the subroutine. The VBA editor might have already generated this code for you automatically.

Loop
End Sub

Before we can run the macro, we should add a couple of element symbols in the first column (A) so that the macro has something to do. As an example, use the elements H, S and O. Use one row for each, so that H is in the first, S in the second and O in the third row.

During development, you can run your macro directly from the VBA editor, using either the play button in the toolbar, the Run menu, or the F5 key on your keyboard.

The macro should run and automatically fill the other columns for your three rows.

To re-run your macro later when you’ve closed the VBA editor, follow these steps:

  1. Open the View ribbon.
  2. Click on Macros.
  3. Select the macro and click Run to execute.

The Power Query builder provides access to a variety of data sources. It even enables the combination of data from multiple sources. In this tutorial, though, we’ll just show you the basics to make an API call and display the results in your Excel sheet. We use the collection endpoint to retrieve the complete periodic table.

To get started, go to the Data ribbon, click the Get Data button, choose From Other Sources, and From Web.

In the popup window, enter the URL for the API. You can configure advanced settings such as HTTP headers for your request, but the BASF Periodic Table API doesn’t need any. You have to provide the full URL to the collection endpoint and add the query parameter for authentication directly into the URL. In the following sample, replace APIKEY with the Client ID of your application

https://dev.api.basf.com/chemical/elements?x-api-key=APIKEY

Once you confirm with OK, the Power Query Builder opens and shows the API response. At first, you just see the container element items. Right-click on it and select Drill Down.

Note the list of applied steps on the right side of the window. It shows you everything you did in the query builder and you can undo any step by clicking the X next to it.

Now you see a list of records and you can click on each to see the different attributes of each element. The next step is converting this list into a table and you do this by clicking the To Table button.

A popup with additional options may appear which you can simply confirm with OK. After that, you see the list as a table but it still has just one column that we need to expand into multiple columns so you can see each attribute of the element in its own column. To do so, click the expand icon (<>) in the column header.

In the popup, select the fields that you like or keep all fields intact. You can uncheck «Use original column name as prefix» as the prefix doesn’t provide any value when you’re just working with one data source.

Once you see the data you want in the query builder, your final step is transferring the table into the Excel sheet. You do this with the Close&Load button.

You’re done! Your excel sheet contains the periodic table of elements now.

Congratulations on making it through the tutorial! We hope it deepened your understanding of APIs and how to consume them with Excel. Feel free to contact developer@basf.com with feedback and questions.

Это наш очередной пост в колонку “Office как Платформа”. На этот раз приветствуем Дмитрия Соловьева ( dmitriysolovev), руководителя центра поддержки Office 365 в компании АстроСофт – автора уже нескольких статей по технологии PowerBI. В этой статье Дмитрий расскажет о том, как использовать REST API для получения данных из внешних источников для визуализации и анализа в PowerBI. – Владимир Юнев

Всем привет! На хабре было уже несколько постов на тему Power BI. Если судить по комментариям, то как минимум нескольким читателям актуальна тема получения данных из REST веб-сервисов. Сегодня ее и рассмотрим на примере получения и обработки данных с портала открытых данных г. Санкт-Петербурга (http://data.gov.spb.ru/). Экзекуции будут подвергнуты данные технико-экономических паспортов многоквартирных домов (http://data.gov.spb.ru/datasets/69/). В роли «пыточного инструмента» выступит Excel 2016, в состав которого теперь по умолчанию встроен Power Query.

Введение

В целом Power Query позволяет получать данные из открытых и не очень источников различными способами (рис.1):

  1. Получение данных «Из интернета». В этом случае достаточно указать URL страницы, на которой находятся интересующие нас данные и загрузить их. Из недостатков – стабильно работает только на страницах, использующих табличную вёрстку; приходится писать функции в случае, если данные разбиты на страницы; администраторы сайта могут Вас забанить, если будет слишком много запросов (а они будут, если страниц много);
  2. Получение данных из канала OData. Этот вариант подходит для различных LOB-приложений, которые поддерживают OData;
  3. Написать запрос с нуля, используя возможности языка «M». Как раз этот вариант я и буду использовать в данном случае.


Рис.1. — Варианты источников данных Power Query

Часть 1. Проба сервиса на вкус

В большинстве случаев для того, чтобы работать с REST API требуется получить API Token. Для его получения на сайте открытых данных г. Санкт-Петербурга требуется зарегистрировать учётную запись разработчика, затем токен отобразится в личном кабинете. Также на сайте можно найти краткую инструкцию по использованию API (http://data.gov.spb.ru/developers/). Обращаю внимание на формат передачи токена, поскольку эта информация мне понадобится, чтобы получить доступ к нужной мне информации (рис.2).


Рис.2. — Документация к API

Итак, у меня есть пример использования API, есть токен и теперь можно попробовать получить пробную информации с сайта открытых данных г. Санкт-Петербурга. Первым делом я выбираю тип запроса «Из Интернета» и в открывшемся окне указываю адрес: http://data.gov.spb.ru/api/v1/datasets/ (рис.3).


Рис.3. — Запрос данных Из Интернета

После нажатия кнопки «ОК» ожидаемо вижу окно авторизации с сообщением о том, что используются недопустимые учетные данные. К слову, Power Query поддерживает несколько типов учетных данных при работе с внешними запросами, среди которых есть и Web API. Этот тип авторизации позволяет передать токен, что я и попытаюсь сделать. Немного подумав, Power Query опять выдает сообщение о том, что я использую неверные учетные данные. Позднее нужно будет проанализировать – в каком формате Power Query передает API ключ и что с этим можно делать (рис.4).


Рис.4. — Ошибка авторизации Power Query

Так как простой способ подключения к API результата не принёс, то придется пойти более сложным и сформировать запрос вручную. Для этого создадим пустой запрос и откроем расширенный редактор (рис.5):


Рис.5. — Запуск расширенного редактора запросов

Как Вы уже знаете, «за внешней оболочкой» Power Query лежит свой язык программирования M. Для получения данных из веб-источников используется функция Web.Contents, которая принимает два параметра – Url веб-сайта и набор параметров запроса (API ключ, таймаут подключения, заголовки запроса и т.д.). Возвращает эта функция набор двоичных данных, которые затем можно обработать с использование других функций языка М. Сформируем тестовый запрос, который должен вернуть набор доступных на портале наборов данных:

Web.Contents("http://data.gov.spb.ru/api/v1/datasets/ ", [Headers=[#"Authorization"="Token c81a**************************fe3"]])

После ввода текста запроса нужно нажать кнопку «Готово» и просмотреть полученный результат (рис.6).


Рис.6. — Пример тестового запроса к API

Результаты тестового запроса показаны на рисунке 7. Поскольку функция Web.Contents возвращает результат своей работы в виде двоичных данных, то логично, что на экране мы видим значок, а не цифры. Для того, чтобы увидеть результаты в более доступном для человека виде, нужно дважды кликнуть на значок (рис.7 и рис.8).


Рис.7. — Результаты тестового запроса к API


Рис.8. — Развернутые двоичные данные

Внешний вид редактора запросов после «проваливания» в результаты работы функции Web.Contents можно увидеть на рисунке 8. Обратите внимание на строку формул, в которой видна функция Json.Document(Source). Функция Json.Document возвращает содержимое Json документа, а в качестве аргумента в нее передан результат выполнения предыдущего шага с именем «Source». Да, язык M выполняет пошаговую обработку кода, при этом каждый шаг должен иметь свое имя. В случае работы с запросами в режиме обычного редактора все шаги отображаются в правой части экрана и при необходимости могут быть изменены. Правда с изменением стоит быть поосторожнее, т.к. при последовательном выполнении шагов это тоже самое, что и вмешательство в прошлое, со всеми вытекающими последствиями.

Результат запроса имеет вид «Список». В рамках данной статьи мы не разбираем различия между списками и таблицами в Power Query, поэтому скажу, что для дальнейшей работы с данными нам потребуется преобразовать результаты запроса в таблицу и затем развернуть содержимое столбцов. Итоговый внешний вид полученных данных видно на рисунке 10. Как и обещано в документации к API мы получили полный перечень наборов данных и их идентификаторов (рис.9 и рис.10).


Рис.9. — Преобразование в таблицу


Рис.10 — Перечень источников данных с их идентификаторами

Если открыть расширенный редактор запросов, то мы увидим, что для всех выполненных нами шагов был автоматически сгенерирован код на языке «М» (рис.11).

let
    Source= Web.Contents("http://data.gov.spb.ru/api/v1/datasets/", [Headers=[#"Authorization"="Token c81*******************************fe3"]]),
    #"Импортированные данные JSON" = Json.Document(Source),
    #"Преобразовано в таблицу" = Table.FromList(#"Импортированные данные JSON", Splitter.SplitByNothing(), null, null, ExtraValues.Error),
    #"Развернутый элемент Column1" = Table.ExpandRecordColumn(#"Преобразовано в таблицу", "Column1", {"id", "name"}, {"id", "name"})
in
    #"Развернутый элемент Column1"


Рис.11. — Код в расширенном редакторе запросов

На этом завершу первую пробу API и перейду к формированию второго запроса.

Часть 2. Получаем данные ТЭП домов Санкт-Петербурга

После недолгого изучения документации к API стало ясно, что для получения нужных данных нам потребуются два запроса к API:

  • http://data.gov.spb.ru/api/v1/datasets/69/versions/latest/ — возвращает описание данных в последней версии набора данных
  • http://data.gov.spb.ru/api/v1/datasets/69/versions/latest/data/ — возвращает данные, содержащиеся в последней версии.

В данном случае 69 это идентификатор набора данных, который мы можем получить либо в результатах нашего первого запроса к API, либо открыв страницу нужного набора в браузере и просмотрев URL (рис.12).


Рис.12. — ИД набора данных в URL-адресе

В результате я получаю данные с описанием полей набора данных и сам набор данных о технико-экономических паспортах домов, который после очистки можно будет визуализировать в Power BI или проанализировать при помощи Power Pivot и сводных таблиц в Excel (рис.13 и рис.14).


Рис.13. — Описание набора данных


Рис.14. — Набор данных ТЭП домов Санкт-Петербурга

На этом часть статьи, посвященная выполнению базовых запросов из Power Query к REST API завершается. В следующих частях более подробно рассмотрим возможности Power Query, которые пригодятся при построении запросов к веб-сервисам в реальной жизни – функции, передача параметров и многое другое.

Дополнительные ссылки

Посмотреть основную документацию по созданию офисных приложений вы можете на портале Центра Разработки Office, также вы можете скачать примеры готовых приложений.

Очень много интересной информации, новостей и описания работы с разнообразными источниками данных с помощью PowerBI можно найти в блоге разработчиков.

Об авторе


Дмитрий Соловьёв (MCSA, MCITP, MCT)
Руководитель центра поддержки Office 365 в компании АстроСофт.
dmitriysolovev

Около 10 лет работал с продуктами корпорации Microsoft в качестве инженера, разработчика и тренера. Последние четыре года специализируется на внедрении систем на базе SharePoint, Exchange, Office 365, Microsoft Azure. Магистр по специальности «Техническая эксплуатация летательных аппаратов и их систем»

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

Какие темы бизнес-аналитики вас интересуют?


48.57%
Аналитика с помощью инструментов на десктопе
17


54.29%
Подключение к разнообразным источникам данных
19


57.14%
Использование REST API для доступа к данным
20


68.57%
Визуализация данных в реальном времени
24


42.86%
Интеграция инструментов BI с облачными технологиями
15

Проголосовали 35 пользователей.

Воздержались 8 пользователей.

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

Понравилась статья? Поделить с друзьями:
  • Дорожная карта проекта образец в excel скачать бесплатно
  • Доступ к буферу обмена excel
  • Дорожная карта проекта в excel примеры
  • Доступ к базам данных в excel
  • Дорожная карта продукта excel