Обработка json в excel

To Parse Custom JSON data is to split out its name/value pairs into a more readable useable format.

Excel is a powerful tool that allows you to connect to JSON data and read it.  However sometimes this data might require a little manipulation to be fully understood and analysed in Excel. 

In this article you will learn

  • What is JSON Data
  • To Connect to JSON data from Excel
  • How to Parse simple JSON Data using Excels Power Query
  • To Parse complex JSON Data using Excels Power Query

This article contains data tables to download so you can practice along and master the art of parsing custom JSON data using Excel.  We are also powered with STEEM so you can earn while you learn 😊.  If you are not familiar with Excel Power Tools you can find out about them here.

What is JSON Data?

JSON data is a way of representing objects or arrays.  It is easy to read, and it is easy to parse, even with Excel.  Many API calls will return JSON format and many web apps use JSON which easily moves information around the internet.

The syntax for JSON comes from JavaScript and can be summarized as follows:

  • Data is shown in name/value pairs separated by : For example “name” : ”paulag”
  • Data is separated by commas. For Example “name” : ”paulag” , “Sex” : “Female”
  • Curly brackets represent an object. An object being a name/value pair separated by a comma. For Example {“name” : ”paulag” , “Sex” : “Female”}
  • Square brackets hold arrays and contains a list of values separated by a comma.

Look at the sample JSON in the image below

How to Parse Custom JSON Data using Excel

{“total_population”: This shows the first object, which is a name/value pair.  The name of the object is total_population

[{“date”: “2019-01-02”, “population”: 7638335801}, {“date”: “2019-01-03”, “population”: 7638557789}]}  This is the value for the total population. The [ represents an array.  This array contains two objects. The objects are defined within the curly brackets and separated with a comma. Each object contains 2 lots of data (name/value pair) also separated with a comma.  The data, shown in the name/value pairs, in this example is date and population.

Here is one you can look at yourself. https://api.coinmarketcap.com/v1/ticker/bitcoin/

If you enter this to your browser, you will get something like the below:

excel JSON

Let’s take a look at that image in more detail.

Connecting to JSON data from Excel

In Excels Data ribbon, under GET and Transform Data, we have the option of connecting to data of multiple sources and multiple types. 

If we select Get data from file, we will then have the option to get data from a JSON file. 

In this example we have URL API endpoint https://api.coinmarketcap.com/v1/ticker/bitcoin/.  Therefore, from the Data Ribbon we can select, Get data from Web.  This will open a dialogue box in which you place the URL.

Next, Power query will then open.  Power query is a magic excel tool that will allow you transform data that you connect to into a usable format.

The JSON data will appear as a list of records Power Query. For excel to read this, we must convert a list to a table. Select ‘to table’ from the available option.

Next, Power query will create a table and you will see this step appear on the right of the power query window under applied steps. 

This new table contains a record. We must expand this record to get the value pairs. As this record only has 1 row, we would expect this to expand across the columns.  To do this, right click on the arrows in the column header.

This will reveal the names of the value pairs.  By selecting ok a new column will be set up in the table.  The name will be in the header and the value in the row.  

Further transformations

If we wanted this data going down the row, we could Unpivot the columns.  By selecting the id column.  Then from the Transform ribbon select the dropdown for unpivot columns and select unpivot other columns. 

When working with Power Query, it’s important to make sure you have the correct data types set.  To work with this data, we must now move to from Power Query to Excel.  If we select File, and then select Close and load, this will load the data as a table in Excel.  Or, if we select or Close and Load to, the data will be loaded into a Power Pivot Model.  

How to Parse JSON Data in Excel

Very often when you access JSON data with Excel it appears in 1 column.  This can happen for many reasons and is often the design of a database.

Look at the image below.  We can see the json_metadata field is still in its JSON syntax

How to Parse Custom JSON Data using Excel

When we encounter data like this, we can easily parse the column into its components.  From the image below we see we have 4 components. We have An Array, an Object, the data, and one of the data fields contains an array.

How to Parse Custom JSON Data using Excel

STEP by STEP

Download this file.  It contains a table as shown below.  (do not copy and paste the table as the JSON field will not be recognised.) 

tx_id

tid

json_metadata

timestamp

647524676

follow

[“follow”,{“follower”:”mervin-gil”,”following”:”jarvie”,”what”:[“blog”]}]

43466.89097

647524682

follow

[“follow”,{“follower”:”steliosfan”,”following”:”michealb”,”what”:[“blog”]}]

43466.89097

647524833

follow

[“follow”,{“follower”:”eugenezh”,”following”:”zentricbau”,”what”:[“blog”]}]

43466.89097

647524855

follow

[“follow”,{“follower”:”bitcoinportugal”,”following”:”manuellevi”,”what”:[]}]

43466.89097

647525074

follow

[“follow”,{“follower”:”eugenezh”,”following”:”adriellute”,”what”:[“blog”]}]

43466.89167

647525089

follow

[“follow”,{“follower”:”bigbigtoe”,”following”:”hoxly”,”what”:[“blog”]}]

43466.89167

647525121

follow

[“follow”,{“follower”:”mervin-gil”,”following”:”loveon”,”what”:[“blog”]}]

43466.89167

647525159

follow

[“follow”,{“follower”:”mervin-gil”,”following”:”pechichemena”,”what”:[“blog”]}]

43466.89167

647525233

follow

[“follow”,{“follower”:”imealien”,”following”:”pataty69″,”what”:[“blog”]}]

43466.89167

647525652

follow

[“follow”,{“follower”:”mervin-gil”,”following”:”kamile”,”what”:[“blog”]}]

43466.89236

647525818

follow

[“follow”,{“follower”:”bitcoinportugal”,”following”:”drmake”,”what”:[“blog”]}]

43466.89236

647525886

follow

[“follow”,{“follower”:”mervin-gil”,”following”:”bradfordtennyson”,”what”:[“blog”]}]

43466.89236

647525980

follow

[“follow”,{“follower”:”a0i”,”following”:”shoemanchu”,”what”:[“blog”]}]

43466.89236

647526007

follow

[“follow”,{“follower”:”voteme”,”following”:”kostyantin”,”what”:[“blog”]}]

43466.89236

648215552

follow

[“follow”,{“follower”:”ansie”,”following”:”hoxly”,”what”:[“blog”]}]

43467.75833

648215582

follow

[“follow”,{“follower”:”ashokcan143″,”following”:”abcor”,”what”:[]}]

43467.75833

648215691

follow

[“follow”,{“follower”:”ashokcan143″,”following”:”abasinkanga”,”what”:[]}]

43467.75903

648215820

follow

[“follow”,{“follower”:”nongvo.piy”,”following”:”acidyo”,”what”:[]}]

43467.75903

648215859

follow

[“follow”,{“follower”:”grid9games”,”following”:”yeninsfer”,”what”:[“blog”]}]

43467.75903

648215945

follow

[“follow”,{“follower”:”nongvo.piy”,”following”:”acidyo”,”what”:[“blog”]}]

43467.75903

Click on any of the cells that contain the data and from the Data Ribbon select FROM Table/Range

How to Parse Custom JSON Data using Excel

If your data is not in table format, Excel will then prompt you to create a table.  Select the cells the contain the data and tick the box to say that your table has headers.

How to Parse Custom JSON Data using Excel

Power Query editor window will open. On the canvas you can see your data and, on the right, you can see any transformation steps that have taken place.

How to Parse Custom JSON Data using Excel

To parse the json column, first select the column, then on the Transform Ribbon select Parse and select JSON

How to Parse Custom JSON Data using Excel

Power query will recognise the first [ and create a list format.  Next, we need to expand this list to new rows.  To do this click on the arrows on the top of the column and select Expand to New Rows.

How to Parse Custom JSON Data using Excel

What is returned is two lines for each tx-id.  The json column now has a row for the name of the array, which is follow, and a record.  The record will contain the data.

How to Parse Custom JSON Data using Excel

As we do not need the name of the array, we can use the filter to remove all the follow rows

How to Parse Custom JSON Data using Excel

We are now left with the records. We can expand this record, by pressing the arrow on the column.  From here we see we have the names of 3 data fields, Follower, Following and What

How to Parse Custom JSON Data using Excel

When we select OK, we get a new column in our data table for each data field.

However, the field named what contains an array, which is again shown as a list (or array) which needs to be expanded

How to Parse Custom JSON Data using Excel

Once we expand this, we are at the end of the JSON data and have extracted the relevant columns.  You can now use this data for further analysis in Excel or Power Pivot.  To load it back to excel, select File and Close & Load.

How to Parse Custom JSON Data using Excel

More complex JSON data extractions in Excel

So far, we have looked at getting JSON data into Power Query using an Excel table and directly from a URL.  There are other ways you can connect to JSON data including connecting directly to a JSON file.  Connecting is the easy part.  Things get more complicated when you have JSON columns where the strings are different in each row.  One might start with an array and so return a list, but some might start with an object and return a record.  

In Power Query lists are expanded to new rows in the table and records are expanded to new columns. Parsing custom JSON data in Excel can require some thinking.

 

Есть ли какие-нибудь инструменты для работы с JSON d Excel?

 

JeyCi

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

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

Изменено: JeyCi28.09.2015 10:45:19

чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок — обратитесь к собеседнику на ВЫ — ответ на ваш вопрос получите — а остальное вас не касается (п.п.п. на форумах)

 

Doober

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

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

Для работы в VBA использую найденный на просторах класс Jsonbad.
Пример использования присутствует.
Если у вас офис 64,то надо править класс

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

  • JsonBag.rar (12.21 КБ)

Изменено: Doober28.09.2015 12:24:41

 

А куда все это подкладывать?

 

Doober

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

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

Под квочку :D
Добавите в проект vba модуль JsonBag.cls и будет вам счастье.
Откройте блокнотом файл Форма , посмотрите реализацию по чтению,формированию json.
Будет трудно.Почитайте в инете что такое Json и с чем его едят.

 

Закопировал в модуль, там столько красного, жесть просто(((

 

Doober

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

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

#7

28.09.2015 14:08:53

Красного нет.Пример для авторизации

Код
Function Generate_Login() As String
    With New JsonBag
        .IsArray = False
        ![UserName] = "demo"
        ![Password] = "demo"
       Generate_Login = .JSON
    End With
End Function

Кратенькое

видео

в формате ехе как надо использовать ресурсы инета.

Изменено: Doober28.09.2015 14:09:31

<#0>

 

Николай Бородин

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

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

#8

28.09.2015 16:19:20

Цитата
Doober написал: Кратенькое видео в формате ехе как надо использовать ресурсы инета.

Ммм… чую подвох я в этой штуке

 

Doober

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

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

 

Игорь

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

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

#10

28.09.2015 19:38:58

А я использую конвертацию JSON в XML (на просторах инета нашел модуль парсинга JSON в объект, состоящий из коллекций и словарей, и добавил туда конвертацию в XML)
А из XML уже делаю выборку нужных мне данных (через объектную модель — командами типа SelectNodes)

PS: Может, кто подскажет, что это за синтаксис такой, с восклицательными знаками?
(по примеру от Doober)

Код
Function Generate_Login() As String
    With New JsonBag
        .IsArray = False
        ![UserName] = "demo"
        ![Password] = "demo"
       Generate_Login = .JSON
    End With
End Function

Код
 With JB
        .Clear
        ![First] = 1
        ![Second] = Null
        With .AddNewArray("Third")

это как-то касается NewEnum?

Цитата
NewEnum() As IUnknown [hidden iterator]
Used to iterate over the names of the list items in an «Object» type JsonBag.

Изменено: Игорь28.09.2015 19:44:07

 

Vitallic

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

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

Николай Бородин, на этом форуме встречал такую

тему

, судя по отзывам неплохая библиотека,
но я в ней не разобрался, к тому же все (два) решения которые я встречал написаны под 32-розрядный офис .

Второе найденое

решение

.  

 

Андрей VG

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

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

Excel 2016, 365

#12

29.09.2015 06:01:34

Доброе время суток

Цитата
Игорь написал:
PS: Может, кто подскажет, что это за синтаксис такой, с восклицательными знаками?

Это обращение к свойству по умолчанию с учётом того, что у свойства есть параметр (если значение параметра без пробелов, то можно опустить и символы [] вокруг него).(Интересно бы было знать — как в таком ключе использовать, если параметров у свойства больше одного)?

Код
'Default property.
Public Property Get Item(ByVal Key As Variant) As Variant
Attribute Item.VB_UserMemId = 0
Цитата
Игорь написал:
NewEnum() As IUnknown [hidden iterator]
Used to iterate over the names of the list items in an «Object» type JsonBag.

А это похоже настройка итератора, чтобы можно было использовать For Each

 

Игорь

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

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

Андрей, большое спасибо за ответ.
Теперь понял, что это такое

 

JeyCi

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

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

#14

29.09.2015 08:56:57

Цитата
Андрей VG написал: Интересно бы было знать — как в таком ключе использовать, если параметров у свойства больше одного)?

я не совсем могу представить — это как?..
но если вопрос о ситуации, например key2 (в JsonString ниже) — то вот такой ответ нашла когда-то (есть линк в #2 или

прямой линк

)… т.е. если у свойства есть несколько параметров, то они в рамках общего свойства тоже имеют свои свойства-идентифицирующие их… мне кажется, такова структура json — и никак иначе… имхо… и тогда просто в рамках свойства выделяется объект, состоящий из нескольких параметров и их свойств… я это однозначно видела  :) , когда адаптировала тот код (из примера1 с использованием ScriptControl — на stackoverflow) и не поставила set value=…

Код
    JsonString = "{""key1"": ""val1"", ""key2"": { ""key3"": ""val3"" } }"
    Set JsonObject = DecodeJsonString(CStr(JsonString))
    Keys = GetKeys(JsonObject)
    Value = GetProperty(JsonObject, "key1")   'свойство-значение
    Set Value = GetObjectProperty(JsonObject, "key2")   'свойство-объект

P.S. как в др кодах-обработки json — не знаю…

Изменено: JeyCi29.09.2015 09:10:50

чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок — обратитесь к собеседнику на ВЫ — ответ на ваш вопрос получите — а остальное вас не касается (п.п.п. на форумах)

 

Андрей VG

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

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

Excel 2016, 365

#15

29.09.2015 09:34:28

Цитата
Игорь написал: Андрей, большое спасибо за ответ.

Да не за что. Когда то кодил на VB6, там это всё явно выставлялось…

Цитата
JeyCi написал: я не совсем могу представить — это как?

Давайте по порядку.
Если вы создадите свой класс Class1, определите в нём свойство, допустим

Код
Public Property Get Item(ByVal Index As Long) As String
    '...
End Property
Public Property Let Item(ByVal Index As Long, ByVal Value As String)
    '...
End Property

Сохраните этот класс в файл и допишите в нём атрибут свойства по-умолчанию

Код
Public Property Get Item(ByVal Index As Long) As String
Attribute Item.VB_UserMemId = 0
    '...

То вы получите возможность обращаться к этому свойству в такой манере

Код
Dim p As New Class1
p(1) = "text"
'что эквивалентно
p.Item(1) = "text"
'или
p![1] = "text" '"хитрый" способ обращения к свойству с одним параметром

Но, допустим мы определили свойство с двумя параметрами

Код
Public Property Get Item(ByVal Xid As Long, ByVal Yid As Long) As String
    '...
End Property
Public Property Let Item(ByVal Xid As Long, ByVal Yid As Long, ByVal Value As String)
    '...
End Property

И указали его как свойство по умолчанию, варианты

Код
Dim p As New Class1
p(1, 1) = "text"
'или
p.Item(1, 1) = "text"

понятны, а как будет выглядеть это же в «хитрой» нотации с ![]

Изменено: Андрей VG30.09.2015 00:53:38

 

JeyCi

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

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

#16

29.09.2015 10:02:08

Цитата
Андрей VG написал: а как будет выглядеть это же в «хитрой» нотации с ![]

вот, теперь я поняла вопрос…
но пока я не делала ещё даже такого  

Цитата
Андрей VG написал: Сохраните этот класс в файл и допишите в нём атрибут свойства по-умолчанию

… и более «хитрых» вариантов тем более не видела… поэтому мой ответ оказался о другом…
спасибо за ликбез — теперь лучше буду читать коды…  8)
p.s. #14 тогда пусть послужит напоминанием тем, кто будет делать через подключение библиотеки ScriptControl

чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок — обратитесь к собеседнику на ВЫ — ответ на ваш вопрос получите — а остальное вас не касается (п.п.п. на форумах)

 

Vitallic,Скачал второй вариант, но запустить его в работу не могу. Там в коде есть такая тема, как создание объекта Dictionary, но его описания я нигде не нашел. Я так понимаю он должен быть в классах описан?

 

Игорь

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

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

Николай Бородин

, нажмите Tools — References, и поставьте галочку напротив Microsoft Scripting Runtime

 
 
 

Чувствую прям немного осталось

 

В общем что то я не пойму какие процедуры и функции мне нужно применять для преобразования строки json в объект! Ткните пальцем пожалуйста

 

Николай Бородин, «Справка» не пробовали нажать? Как объявлены JSONTEXT, parse?

 
 

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

  • Справка.png (26.81 КБ)
 

Udik

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

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

excel 2016х64 Контакты в профиле

#26

02.01.2017 18:06:23

Обычно, чтобы не гадать на какой системе будет работать макрос, по такому принципу делают

Код
#If VBA7 And Win64 Then
Declare PtrSafe Function Beep Lib "kernel32" (ByVal dwFreq As Long, ByVal dwDuration As Long) As Long
#Else
Declare Function Beep Lib "kernel32" (ByVal dwFreq As Long, ByVal dwDuration As Long) As Long
#End If

Арфы — нет, возьмите бубен.

 

sv_ispu

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

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

#27

03.01.2021 15:44:20

Помогите решить задачу. Необходимо в VBA сделать пользовательскую функцию, чтобы с помощью формул вытаскивать из JSON нужные теги…
Напр.

Код
=Фильтр.JSON(ВЕБСЛУЖБА("https://query1.finance.yahoo.com/v10/finance/quoteSummary/pbf?modules=price"), longName)

Результат: PBF Energy Inc.

В параметрах функции задаем источник JSON и Xpath (тег) который нужно извлечь.

В инете самое близкое нашел вот это (

https://medium.com/swlh/excel-vba-parse-json-easily-c2213f4d8e7a

), но там не для вставки в формулы. Я подозреваю, что можно как-то этот код с работой в формулах связать, но мозгов не хватает…

Изменено: sv_ispu03.01.2021 15:44:50

 
 

sv_ispu

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

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

Александр Моторин, вот спасибо, добрый человек! я сток промучался, а тут неск минут делов…. Для моей задачи пока хватит..Еще б разобраться с массивами, но это попозже напишу….

 

Андрей VG

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

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

Excel 2016, 365

#30

04.01.2021 10:07:59

Вариант на Power Query

Цитата
sv_ispu написал:
и Xpath (тег) который нужно извлечь.

Откуда информация, что в JSON есть теги и каким-то боком можно использовать XPath?

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

  • тупо в лоб UDF.xlsb (32.4 КБ)

JSON (Javascript Object Notation) is the most used data exchange format nowadays. Microsoft Excel doesn’t have built-in support for importing JSON to excel or exporting excel data to JSON.

VBA-JSON is an excellent library for parsing JSON in VBA. Lets see how to handle JSON in Excel VBA. If you’re new to JSON then read JSON tutorial for beginners

Prerequisites

  1. Save your excel file as Macro-Enabled workbook (Refer screen shot below)
  2. Enable macros if they are not already enabled. You can enable it by cliking on file > options > Trust Center > Trust Center Settings > Enable all macros

Save as xlsm
Enable excel macros

Getting Started

  1. Download VBA JSON latest version from here
  2. Extract it, open VBA code editor in excel (Alt + F11) and import the library as shown in the gif below.
  3. Add a reference to Microsoft scripting runtime. (Tools > references > select)
  4. Add a reference to MSXML (Tools > references)
    Select appropriate version based on your PC :
    1. Microsoft XML, v 3.0.
    2. Microsoft XML, v 4.0 (if you have installed MSXML 4.0 separately).
    3. Microsoft XML, v 5.0 (if you have installed Office 2003 – 2007 which provides MSXML 5.0 for Microsoft Office Applications).
    4. Microsoft XML, v 6.0 for latest versions of MS Office.

excel to json
Add reference microsoft xml and scripting runtime excel

Import JSON to Excel

This library provides a simple method ParseJson to parse JSON string into a dictionary object which can be used to extract data. Let’s see an example.

I’m using fake data from http://jsonplaceholder.typicode.com/ which is an API service with fake Json data.

We’ll be pulling user data from http://jsonplaceholder.typicode.com/users by making a GET request which responds with Json data.

json sample data - json to excel

Read more about GET requests in VBA here

Next, we’ll parse that Json and import it to excel. Code for importing data looks like this :

Public Sub exceljson()
Dim http As Object, JSON As Object, i As Integer
Set http = CreateObject("MSXML2.XMLHTTP")
http.Open "GET", "http://jsonplaceholder.typicode.com/users", False
http.Send
Set JSON = ParseJson(http.responseText)
i = 2
For Each Item In JSON
Sheets(1).Cells(i, 1).Value = Item("id")
Sheets(1).Cells(i, 2).Value = Item("name")
Sheets(1).Cells(i, 3).Value = Item("username")
Sheets(1).Cells(i, 4).Value = Item("email")
Sheets(1).Cells(i, 5).Value = Item("address")("city")
Sheets(1).Cells(i, 6).Value = Item("phone")
Sheets(1).Cells(i, 7).Value = Item("website")
Sheets(1).Cells(i, 8).Value = Item("company")("name")
i = i + 1
Next
MsgBox ("complete")
End Sub

Code explanation

  1. First, define JSON as an object and make a GET request to JSON API
  2. JSON data received in the response is parsed by passing it into ParseJson method.
  3. parsed data is converted into a collection of dictionaries.
  4. Loop through the collection to get each user’s details and set its values to the first sheet.

Running above code looks like gif below.

import json demo - json to excel

Reading JSON from a file

In the same example above, If you want to read JSON data from a local file then you can use FileSystemObject to read all text in the file and then pass it to ParseJson method.

Dim FSO As New FileSystemObject
Dim JsonTS As TextStream
Set JsonTS = FSO.OpenTextFile("example.json", ForReading)
JsonText = JsonTS.ReadAll
JsonTS.Close
Set JSON = ParseJson(JsonText)

Export Excel to Json

VBA-JSON provides another method ConvertToJson which can be used to convert excel data into JSON. Here’s an example.

Sample data with Name, Phone and Email is present in second sheet. Let’s convert it into JSON

Code for this looks like :

Public Sub exceltojson()
Dim rng As Range, items As New Collection, myitem As New Dictionary, i As Integer, cell As Variant
set rng = Range("A2:A3")
'Set rng = Range(Sheets(2).Range("A2"), Sheets(2).Range("A2").End(xlDown)) use this for dynamic range
i = 0
For Each cell In rng
Debug.Print (cell.Value)
myitem("name") = cell.Value
myitem("email") = cell.Offset(0, 1).Value
myitem("phone") = cell.Offset(0, 2).Value
items.Add myitem
Set myitem = Nothing
i = i + 1
Next
Sheets(2).Range("A4").Value = ConvertToJson(items, Whitespace:=2)
End Sub

Code Explanation

  1. First, define rng as range and set it to data range.
  2. ConvertToJson method takes a dictionary collection or array as parameter. So we should pass our data as a collection.
  3. A Dictionary is an object with keys and values just like JSON but doesn’t support multiple items like arrays or collections, so we create a dictionary for each item and push it into an array or a collection.
  4. Define a dictionary and a collection, loop through the range and set each row’s data into myitem
  5. Push myitem into collection and set it to nothing, because we are using the same dictionary to add next row’s data and push it to collection again.

Finally pass items collection to ConvertToJson method which returns a JSON string.

Running above code looks like gif below

export excel to json

Export Excel to JSON file

In the same example above, If you want to export excel data to JSON file then It can be done by opening a file for output by specifying the path of the file and printing data in it. Sample code below, Running this would save a JSON file in the current workbook’s folder.

Public Sub exceltojsonfile()
Dim rng As Range, items As New Collection, myitem As New Dictionary, i As Integer, cell As Variant, myfile As String
Set rng = Range("A2:A3")
'Set rng = Range(Sheets(2).Range("A2"), Sheets(2).Range("A2").End(xlDown)) use this for dynamic range
i = 0
For Each cell In rng
Debug.Print (cell.Value)
myitem("name") = cell.Value
myitem("email") = cell.Offset(0, 1).Value
myitem("phone") = cell.Offset(0, 2).Value
items.Add myitem
Set myitem = Nothing
i = i + 1
Next
myfile = Application.ActiveWorkbook.Path &amp;amp; "data.json"
Open myfile For Output As #1
Print #1, ConvertToJson(items, Whitespace:=2)
Close #1
End Sub

Export Excel to Nested JSON

Above code can be modified a bit to get a nested JSON as output. Just add dictionary in another dictionary so that it creates a nested JSON. code looks like this :

Public Sub exceltonestedjson()
Dim rng As Range, items As New Collection, myitem As New Dictionary, subitem As New Dictionary, i As Integer, cell As Variant
Set rng = Range("A2:A3")
'Set rng = Range(Sheets(2).Range("A2"), Sheets(2).Range("A2").End(xlDown)) use this for dynamic range
i = 0
For Each cell In rng
Debug.Print (cell.Value)
myitem("name") = cell.Value
myitem("email") = cell.Offset(0, 1).Value
myitem("phone") = cell.Offset(0, 2).Value
subitem("country") = cell.Offset(0, 3).Value
myitem.Add "location", subitem
items.Add myitem
Set myitem = Nothing
Set subitem = Nothing
i = i + 1
Next
Sheets(2).Range("A4").Value = ConvertToJson(items, Whitespace:=2)
End Sub

Running above code looks like image below

export excel to nested json

Using array of strings and objects in JSON

One of our readers asked me how to use an array of strings and objects inside the JSON.

Here’s how to do it:

Public Sub exceltojson()
Dim rng As Range, items As New Collection, myitem As New Dictionary, i As Integer, cell As Variant, objectContainer As New Dictionary, arrayContainer As New Collection
Dim j As Integer
'Set rng = Range("A2:A3")
Set rng = Range(Sheets(1).Range("A2"), Sheets(1).Range("A2").End(xlDown)) 'use this for dynamic range
i = 0
For Each cell In rng
myitem("id") = cell.Value
myitem("name") = cell.Offset(0, 1).Value

'tags
tagsString = cell.Offset(0, 2).Value
tagsCollection = getCollectionFromString(tagsString)
myitem.Add "tags", tagsCollection

'ingredients
ingredientsString = cell.Offset(0, 3).Value
weightsString = cell.Offset(0, 4).Value
ingredientsUnit = cell.Offset(0, 5).Value
ingredientsCollection = getCollectionFromString(ingredientsString)
weightsCollection = getCollectionFromString(weightsString)

j = 0
For Each ingredient In ingredientsCollection
objectContainer("ingredientnaam") = ingredient
objectContainer("eenheid") = ingredientsUnit
objectContainer("hoeveelheid") = weightsCollection(j)
arrayContainer.Add objectContainer
Set objectContainer = Nothing
j = j + 1
Next
myitem.Add "ingredienten", arrayContainer

'Reset values
Set arrayContainer = Nothing
j = 0

items.Add myitem
Set myitem = Nothing
i = i + 1
Next
Sheets(1).Range("A6").Value = ConvertToJson(items, Whitespace:=2)
End Sub

Function getCollectionFromString(val)
getCollectionFromString = Split(val, ", ")
End Function

Running above code looks like image below
export excel to nested json

Wrapping up

Read official documentation of VBA-JSON here and use VBA-Dictionary for Mac Support.

Related articles :

  • Complete JSON tutorial here – JSON for beginners
  • Handling CSV in VBA

If you have any questions or feedback, comment below and please use CodingisLove Bin for sharing your code.

  • Author
  • Recent Posts

A CA- by education, self taught coder by passion, loves to explore new technologies and believes in learn by doing.

16 Aug How to Import JSON to Excel Using VBA

Posted at 13:26h
in Excel VBA
12 Comments

Howdee! It’s becoming increasingly more common for data to be generated in a JSON format as opposed to XML. XML was widely used for years, but recently JSON has started to become the preferred method of data exchange. Many REST APIs have the option to return both but the majority that I interact with default to returning JSON formatted data. Therefore, as excel ninjas, it’s important to understand how to import JSON to Excel for analysis. Before we begin on that route, let’s take a quick moment to talk about what JSON is for those that aren’t familiar with it.

Curious how to do this in VSTO? Click Here!

What is JSON?

JSON stands for JavaScript Object Notation and is a lightweight data-interchange format. In layman’s terms, it is a string of text that represents a universal data structure. It is easy for humans to read (when formatted properly) and, because of the universal structure, it is very easy and fast for machines to parse and generate. It’s made simple because JSON, at it’s most basic, is only two data types. It is made up of objects, or arrays, or a combination of both. Objects are made up of key/value pairs (often called a dictionary) and arrays are simply collections of values or objects separated by a comma.

It’s important to note that object/dictionary and array are the terminology applicable to the .NET language. Other languages might have other terminology such as hash table for object, or vector for an array. This site gives a great high level, cross-language overview of JSON.

JSON Object

A JSON object always begins with { and ends with }. The key is separated from its value with a colon (“:”). The key/value pairs will then be separated by commas all within the curly brackets. In the image below, the first key “color” corresponds to its value “red”, while the second key “value” corresponds to the red hex code “#f00”. Hopefully you can see why this might be called a dictionary as you look up the key (word to define) to get its value (definition of the word).

import json to excel

JSON Array

A JSON array, in its simplest form, is a list of values separated by a comma that begins with [ and ends with ]. In the below image, the JSON array is a list of string data points. We can see that they are colors but there is no key in this example explicitly telling that this string represents a color. Therefore, JSON is most commonly seen as a combination of arrays and objects.

import json to excel

JSON Objects & Arrays Together

Most of the time, JSON is returned as an array of objects. If you recall, an object always begins and ends with curly brackets. Therefore, the array of objects would have several objects enclosed in curly brackets that are separated by commas and all objects are enclosed in normal brackets (the array). That looks like this image:

import json to excel

In this example, each object represents a color and its corresponding hex code. In Excel, this would likely be two columns of data. One column for color, and the other for its hex code value. Now that you’re more familiar with JSON data structure, let’s learn how to import JSON to Excel!

Setup JSON to Excel

There are several libraries out there to help you import JSON to Excel. The most popular of these is VBA-JSON which is available here on GitHub. This library will do most of the hard work of parsing the JSON string to a dictionary for you and then you can write the values to an excel worksheet. When you download the latest release, you’ll need to import the “JsonConverter.bas” file to your VBA project. This GIF shows how that is accomplished. You will also need to add a  reference to the “Microsoft Scripting Runtime” by clicking tools from the ribbon, selecting references and checking the box for Microsoft Scripting Runtime as shown in the screen grab.

Once you have completed both steps, insert a new module into your project and title it whatever you like. To get started, we need to dimension some variables to use later.

Dim ws As Worksheet
Dim jsonText As String
Dim jsonObject As Object

The ws variable will represent a worksheet in excel. In this example, we will use this worksheet to both read in our JSON string from and write the parsed JSON to Excel. To assign a worksheet to this variable, set it like this:

Set ws = Worksheets("JSON to Excel Example")

The jsonText variable will represent our string of valid JSON data. For this example, I’ve pasted that string of colors and hex codes we looked at earlier into cell A1 on the JSON to Excel Example tab. To assign that string to a variable, type this code:

jsonText = ws.Cells(1, 1)

This step is not necessary for the code to work for us. We could simply reference the cell in the worksheet that contains the JSON. However, most of the time you’ll be returning your JSON string from another data source, most likely a HTTP GET Web Call. If you’re not familiar with HTTP Requests in VBA, click here to learn more.

Lastly, to put the JSON string into the jsonObject, we will use one of the methods contained in the JsonConverter file you imported to begin this example. Since the builder of this library made all of the subroutines public, it is callable from the module this code is in. That call looks like this:

Set jsonObject = JsonConverter.ParseJson(jsonText)

This call instructs the JsonConverter module to parse the JSON string you’ve passed it using the jsonText variable to a collection of dictionaries that we can now access. Now that we’ve finished our setup, we can start learning to import JSON to Excel in the next section.

Import JSON to Excel

The code to import JSON to Excel might sound daunting, but it is much easier than it sounds. At a high level, all you have to do is loop through the jsonObject you’ve created, and write each dictionary value to the sheet. The wonderful thing about dictionaries, is this is easy to do with a for each loop. I’ve added a couple of variables and a for each loop to our code and the result is this:

Sub JsonToExcelExample()
Dim jsonText As String
Dim jsonObject As Object, item As Object
Dim i As Long
Dim ws As Worksheet

Set ws = Worksheets("JSON to Excel Example")

jsonText = ws.Cells(1, 1)

Set jsonObject = JsonConverter.ParseJson(jsonText)

i = 3

ws.Cells(2, 1) = "Color"
ws.Cells(2, 2) = "Hex Code"

For Each item In jsonObject
    ws.Cells(i, 1) = item("color")
    ws.Cells(i, 2) = item("value")
    i = i + 1
Next

End Sub

I set a counter variable, i, that I can use to tell the loop which row to write the data to. Next, create my column headers for the data. Then, for each “item” in the jsonObject write that dictionaries values to the cell row I indicate and increment my counter variable. That’s it! The results of our import JSON to Excel code looks like this:

import json to excel

As you can see, we’ve turned that odd-looking string of text in cell A1 to an easy to understand table of data with just a few lines of code!

Understanding JSON to Excel (Advanced)

Now, I do want to point out that understanding the structure of the JSON you’ll be parsing is very important. Within the for each loop, the code can access the value of each object by referencing its key. This goes back to understanding the key/value pair relationship of JSON and the dictionary structure to which it is parsed. The reason I stress this so much is because, when you’re pulling back more complex looking JSON, you may need to have multiple levels of dictionary references to access the value you want. There may also be times when you have to nest for loops when you have an array of objects with arrays of objects nested inside each object.

For example, let’s look at an example where the JSON is structured as a single object with key “data” and the value is an array of data about employee’s and their organizations:

import json to excel

As you can see, we have an object with an array nested inside. Some objects in the array contains other nested objects as well. This multi-tiered data structure is very common when pulling data from a REST service and was very confusing to me when I first began trying to import JSON to Excel. Let’s examine what the code looks like for this scenario before we dive any deeper.

Sub JsonToExcelAdvancedExample()
Dim jsonText As String
Dim jsonObject As Object, item As Object
Dim i As Long
Dim ws As Worksheet

Set ws = Worksheets("JSON to Excel Advanced Example")

jsonText = ws.Cells(1, 1)

Set jsonObject = JsonConverter.ParseJson(jsonText)

i = 3

ws.Cells(2, 1) = "id"
ws.Cells(2, 2) = "Name"
ws.Cells(2, 3) = "Username"
ws.Cells(2, 4) = "Email"
ws.Cells(2, 5) = "Street Address"
ws.Cells(2, 6) = "Suite"
ws.Cells(2, 7) = "City"
ws.Cells(2, 8) = "Zipcode"
ws.Cells(2, 9) = "Phone"
ws.Cells(2, 10) = "Website"
ws.Cells(2, 11) = "Company"

For Each item In jsonObject("data")
    ws.Cells(i, 1) = item("id")
    ws.Cells(i, 2) = item("name")
    ws.Cells(i, 3) = item("username")
    ws.Cells(i, 4) = item("email")
    ws.Cells(i, 5) = item("address")("street")
    ws.Cells(i, 6) = item("address")("suite")
    ws.Cells(i, 7) = item("address")("city")
    ws.Cells(i, 8) = item("address")("zipcode")
    ws.Cells(i, 9) = item("phone")
    ws.Cells(i, 10) = item("website")
    ws.Cells(i, 11) = item("company")("name")
    i = i + 1
Next

End Sub

The code overall is the exact same, just referencing a different tab and added more fields to pull out. The change I want to point out is to the for loop itself. The beginning of the for loop now starts by referencing the overall object that contains the array. This is referred to as the “root” of the JSON and you’ll see it if you’re querying a REST API for JSON data. This moves the for each loop inside the “data” level of the JSON and will now loop through all objects in the highest-level array. Had I left this out, the loop would only occur once as the JSON is all contained within a single object at its top level.

The second piece I want to point out is the lines for address and company. These are both objects contained within the parent object. So, in order for me to reach to value I want, I have to reference both keys to get the specific value I need. Lastly, I want to call out that you do not need to write every value from the returned JSON to the sheet. I have skipped over several fields to get the end result I desired and it does not affect my code results, which coincidently look like this:

import json to excel

I hope this brief explanation of how to import JSON to Excel was useful for you! Please let me know if it was helpful or if you have any questions in the comments below. Also, if you want to download the file with the example JSON and VBA code, you can do so here if you’re a free subscriber to the site. It’s free, easy, and only takes a moment to sign up.

Cheers!

R

UPDATE 3 (Sep 24 ’17)

Check VBA-JSON-parser on GitHub for the latest version and examples. Import JSON.bas module into the VBA project for JSON processing.

UPDATE 2 (Oct 1 ’16)

However if you do want to parse JSON on 64-bit Office with ScriptControl, then this answer may help you to get ScriptControl to work on 64-bit.

UPDATE (Oct 26 ’15)

Note that a ScriptControl-based approachs makes the system vulnerable in some cases, since they allows a direct access to the drives (and other stuff) for the malicious JS code via ActiveX’s. Let’s suppose you are parsing web server response JSON, like JsonString = "{a:(function(){(new ActiveXObject('Scripting.FileSystemObject')).CreateTextFile('C:\Test.txt')})()}". After evaluating it you’ll find new created file C:Test.txt. So JSON parsing with ScriptControl ActiveX is not a good idea.

Trying to avoid that, I’ve created JSON parser based on RegEx’s. Objects {} are represented by dictionaries, that makes possible to use dictionary’s properties and methods: .Count, .Exists(), .Item(), .Items, .Keys. Arrays [] are the conventional zero-based VB arrays, so UBound() shows the number of elements. Here is the code with some usage examples:

Option Explicit

Sub JsonTest()
    Dim strJsonString As String
    Dim varJson As Variant
    Dim strState As String
    Dim varItem As Variant

    ' parse JSON string to object
    ' root element can be the object {} or the array []
    strJsonString = "{""a"":[{}, 0, ""value"", [{""stuff"":""content""}]], b:null}"
    ParseJson strJsonString, varJson, strState

    ' checking the structure step by step
    Select Case False ' if any of the checks is False, the sequence is interrupted
        Case IsObject(varJson) ' if root JSON element is object {},
        Case varJson.Exists("a") ' having property a,
        Case IsArray(varJson("a")) ' which is array,
        Case UBound(varJson("a")) >= 3 ' having not less than 4 elements,
        Case IsArray(varJson("a")(3)) ' where forth element is array,
        Case UBound(varJson("a")(3)) = 0 ' having the only element,
        Case IsObject(varJson("a")(3)(0)) ' which is object,
        Case varJson("a")(3)(0).Exists("stuff") ' having property stuff,
        Case Else
            MsgBox "Check the structure step by step" & vbCrLf & varJson("a")(3)(0)("stuff") ' then show the value of the last one property.
    End Select

    ' direct access to the property if sure of structure
    MsgBox "Direct access to the property" & vbCrLf & varJson.Item("a")(3)(0).Item("stuff") ' content

    ' traversing each element in array
    For Each varItem In varJson("a")
        ' show the structure of the element
        MsgBox "The structure of the element:" & vbCrLf & BeautifyJson(varItem)
    Next

    ' show the full structure starting from root element
    MsgBox "The full structure starting from root element:" & vbCrLf & BeautifyJson(varJson)

End Sub

Sub BeautifyTest()
    ' put sourse JSON string to "desktopsource.json" file
    ' processed JSON will be saved to "desktopresult.json" file
    Dim strDesktop As String
    Dim strJsonString As String
    Dim varJson As Variant
    Dim strState As String
    Dim strResult As String
    Dim lngIndent As Long

    strDesktop = CreateObject("WScript.Shell").SpecialFolders.Item("Desktop")
    strJsonString = ReadTextFile(strDesktop & "source.json", -2)
    ParseJson strJsonString, varJson, strState
    If strState <> "Error" Then
        strResult = BeautifyJson(varJson)
        WriteTextFile strResult, strDesktop & "result.json", -1
    End If
    CreateObject("WScript.Shell").PopUp strState, 1, , 64
End Sub

Sub ParseJson(ByVal strContent As String, varJson As Variant, strState As String)
    ' strContent - source JSON string
    ' varJson - created object or array to be returned as result
    ' strState - Object|Array|Error depending on processing to be returned as state
    Dim objTokens As Object
    Dim objRegEx As Object
    Dim bMatched As Boolean

    Set objTokens = CreateObject("Scripting.Dictionary")
    Set objRegEx = CreateObject("VBScript.RegExp")
    With objRegEx
        ' specification http://www.json.org/
        .Global = True
        .MultiLine = True
        .IgnoreCase = True
        .Pattern = """(?:\""|[^""])*""(?=s*(?:,|:|]|}))"
        Tokenize objTokens, objRegEx, strContent, bMatched, "str"
        .Pattern = "(?:[+-])?(?:d+.d*|.d+|d+)e(?:[+-])?d+(?=s*(?:,|]|}))"
        Tokenize objTokens, objRegEx, strContent, bMatched, "num"
        .Pattern = "(?:[+-])?(?:d+.d*|.d+|d+)(?=s*(?:,|]|}))"
        Tokenize objTokens, objRegEx, strContent, bMatched, "num"
        .Pattern = "b(?:true|false|null)(?=s*(?:,|]|}))"
        Tokenize objTokens, objRegEx, strContent, bMatched, "cst"
        .Pattern = "b[A-Za-z_]w*(?=s*:)" ' unspecified name without quotes
        Tokenize objTokens, objRegEx, strContent, bMatched, "nam"
        .Pattern = "s"
        strContent = .Replace(strContent, "")
        .MultiLine = False
        Do
            bMatched = False
            .Pattern = "<d+(?:str|nam)>:<d+(?:str|num|obj|arr|cst)>"
            Tokenize objTokens, objRegEx, strContent, bMatched, "prp"
            .Pattern = "{(?:<d+prp>(?:,<d+prp>)*)?}"
            Tokenize objTokens, objRegEx, strContent, bMatched, "obj"
            .Pattern = "[(?:<d+(?:str|num|obj|arr|cst)>(?:,<d+(?:str|num|obj|arr|cst)>)*)?]"
            Tokenize objTokens, objRegEx, strContent, bMatched, "arr"
        Loop While bMatched
        .Pattern = "^<d+(?:obj|arr)>$" ' unspecified top level array
        If Not (.Test(strContent) And objTokens.Exists(strContent)) Then
            varJson = Null
            strState = "Error"
        Else
            Retrieve objTokens, objRegEx, strContent, varJson
            strState = IIf(IsObject(varJson), "Object", "Array")
        End If
    End With
End Sub

Sub Tokenize(objTokens, objRegEx, strContent, bMatched, strType)
    Dim strKey As String
    Dim strRes As String
    Dim lngCopyIndex As Long
    Dim objMatch As Object

    strRes = ""
    lngCopyIndex = 1
    With objRegEx
        For Each objMatch In .Execute(strContent)
            strKey = "<" & objTokens.Count & strType & ">"
            bMatched = True
            With objMatch
                objTokens(strKey) = .Value
                strRes = strRes & Mid(strContent, lngCopyIndex, .FirstIndex - lngCopyIndex + 1) & strKey
                lngCopyIndex = .FirstIndex + .Length + 1
            End With
        Next
        strContent = strRes & Mid(strContent, lngCopyIndex, Len(strContent) - lngCopyIndex + 1)
    End With
End Sub

Sub Retrieve(objTokens, objRegEx, strTokenKey, varTransfer)
    Dim strContent As String
    Dim strType As String
    Dim objMatches As Object
    Dim objMatch As Object
    Dim strName As String
    Dim varValue As Variant
    Dim objArrayElts As Object

    strType = Left(Right(strTokenKey, 4), 3)
    strContent = objTokens(strTokenKey)
    With objRegEx
        .Global = True
        Select Case strType
            Case "obj"
                .Pattern = "<d+w{3}>"
                Set objMatches = .Execute(strContent)
                Set varTransfer = CreateObject("Scripting.Dictionary")
                For Each objMatch In objMatches
                    Retrieve objTokens, objRegEx, objMatch.Value, varTransfer
                Next
            Case "prp"
                .Pattern = "<d+w{3}>"
                Set objMatches = .Execute(strContent)

                Retrieve objTokens, objRegEx, objMatches(0).Value, strName
                Retrieve objTokens, objRegEx, objMatches(1).Value, varValue
                If IsObject(varValue) Then
                    Set varTransfer(strName) = varValue
                Else
                    varTransfer(strName) = varValue
                End If
            Case "arr"
                .Pattern = "<d+w{3}>"
                Set objMatches = .Execute(strContent)
                Set objArrayElts = CreateObject("Scripting.Dictionary")
                For Each objMatch In objMatches
                    Retrieve objTokens, objRegEx, objMatch.Value, varValue
                    If IsObject(varValue) Then
                        Set objArrayElts(objArrayElts.Count) = varValue
                    Else
                        objArrayElts(objArrayElts.Count) = varValue
                    End If
                    varTransfer = objArrayElts.Items
                Next
            Case "nam"
                varTransfer = strContent
            Case "str"
                varTransfer = Mid(strContent, 2, Len(strContent) - 2)
                varTransfer = Replace(varTransfer, """", """")
                varTransfer = Replace(varTransfer, "\", "")
                varTransfer = Replace(varTransfer, "/", "/")
                varTransfer = Replace(varTransfer, "b", Chr(8))
                varTransfer = Replace(varTransfer, "f", Chr(12))
                varTransfer = Replace(varTransfer, "n", vbLf)
                varTransfer = Replace(varTransfer, "r", vbCr)
                varTransfer = Replace(varTransfer, "t", vbTab)
                .Global = False
                .Pattern = "\u[0-9a-fA-F]{4}"
                Do While .Test(varTransfer)
                    varTransfer = .Replace(varTransfer, ChrW(("&H" & Right(.Execute(varTransfer)(0).Value, 4)) * 1))
                Loop
            Case "num"
                varTransfer = Evaluate(strContent)
            Case "cst"
                Select Case LCase(strContent)
                    Case "true"
                        varTransfer = True
                    Case "false"
                        varTransfer = False
                    Case "null"
                        varTransfer = Null
                End Select
        End Select
    End With
End Sub

Function BeautifyJson(varJson As Variant) As String
    Dim strResult As String
    Dim lngIndent As Long
    BeautifyJson = ""
    lngIndent = 0
    BeautyTraverse BeautifyJson, lngIndent, varJson, vbTab, 1
End Function

Sub BeautyTraverse(strResult As String, lngIndent As Long, varElement As Variant, strIndent As String, lngStep As Long)
    Dim arrKeys() As Variant
    Dim lngIndex As Long
    Dim strTemp As String

    Select Case VarType(varElement)
        Case vbObject
            If varElement.Count = 0 Then
                strResult = strResult & "{}"
            Else
                strResult = strResult & "{" & vbCrLf
                lngIndent = lngIndent + lngStep
                arrKeys = varElement.Keys
                For lngIndex = 0 To UBound(arrKeys)
                    strResult = strResult & String(lngIndent, strIndent) & """" & arrKeys(lngIndex) & """" & ": "
                    BeautyTraverse strResult, lngIndent, varElement(arrKeys(lngIndex)), strIndent, lngStep
                    If Not (lngIndex = UBound(arrKeys)) Then strResult = strResult & ","
                    strResult = strResult & vbCrLf
                Next
                lngIndent = lngIndent - lngStep
                strResult = strResult & String(lngIndent, strIndent) & "}"
            End If
        Case Is >= vbArray
            If UBound(varElement) = -1 Then
                strResult = strResult & "[]"
            Else
                strResult = strResult & "[" & vbCrLf
                lngIndent = lngIndent + lngStep
                For lngIndex = 0 To UBound(varElement)
                    strResult = strResult & String(lngIndent, strIndent)
                    BeautyTraverse strResult, lngIndent, varElement(lngIndex), strIndent, lngStep
                    If Not (lngIndex = UBound(varElement)) Then strResult = strResult & ","
                    strResult = strResult & vbCrLf
                Next
                lngIndent = lngIndent - lngStep
                strResult = strResult & String(lngIndent, strIndent) & "]"
            End If
        Case vbInteger, vbLong, vbSingle, vbDouble
            strResult = strResult & varElement
        Case vbNull
            strResult = strResult & "Null"
        Case vbBoolean
            strResult = strResult & IIf(varElement, "True", "False")
        Case Else
            strTemp = Replace(varElement, """", """")
            strTemp = Replace(strTemp, "", "\")
            strTemp = Replace(strTemp, "/", "/")
            strTemp = Replace(strTemp, Chr(8), "b")
            strTemp = Replace(strTemp, Chr(12), "f")
            strTemp = Replace(strTemp, vbLf, "n")
            strTemp = Replace(strTemp, vbCr, "r")
            strTemp = Replace(strTemp, vbTab, "t")
            strResult = strResult & """" & strTemp & """"
    End Select

End Sub

Function ReadTextFile(strPath As String, lngFormat As Long) As String
    ' lngFormat -2 - System default, -1 - Unicode, 0 - ASCII
    With CreateObject("Scripting.FileSystemObject").OpenTextFile(strPath, 1, False, lngFormat)
        ReadTextFile = ""
        If Not .AtEndOfStream Then ReadTextFile = .ReadAll
        .Close
    End With
End Function

Sub WriteTextFile(strContent As String, strPath As String, lngFormat As Long)
    With CreateObject("Scripting.FileSystemObject").OpenTextFile(strPath, 2, True, lngFormat)
        .Write (strContent)
        .Close
    End With
End Sub

One more opportunity of this JSON RegEx parser is that it works on 64-bit Office, where ScriptControl isn’t available.

INITIAL (May 27 ’15)

Here is one more method to parse JSON in VBA, based on ScriptControl ActiveX, without external libraries:

Sub JsonTest()

    Dim Dict, Temp, Text, Keys, Items

    ' Converting JSON string to appropriate nested dictionaries structure
    ' Dictionaries have numeric keys for JSON Arrays, and string keys for JSON Objects
    ' Returns Nothing in case of any JSON syntax issues
    Set Dict = GetJsonDict("{a:[[{stuff:'result'}]], b:''}")
    ' You can use For Each ... Next and For ... Next loops through keys and items
    Keys = Dict.Keys
    Items = Dict.Items

    ' Referring directly to the necessary property if sure, without any checks
    MsgBox Dict("a")(0)(0)("stuff")

    ' Auxiliary DrillDown() function
    ' Drilling down the structure, sequentially checking if each level exists
    Select Case False
    Case DrillDown(Dict, "a", Temp, "")
    Case DrillDown(Temp, 0, Temp, "")
    Case DrillDown(Temp, 0, Temp, "")
    Case DrillDown(Temp, "stuff", "", Text)
    Case Else
        ' Structure is consistent, requested value found
        MsgBox Text
    End Select

End Sub

Function GetJsonDict(JsonString As String)
    With CreateObject("ScriptControl")
        .Language = "JScript"
        .ExecuteStatement "function gettype(sample) {return {}.toString.call(sample).slice(8, -1)}"
        .ExecuteStatement "function evaljson(json, er) {try {var sample = eval('(' + json + ')'); var type = gettype(sample); if(type != 'Array' && type != 'Object') {return er;} else {return getdict(sample);}} catch(e) {return er;}}"
        .ExecuteStatement "function getdict(sample) {var type = gettype(sample); if(type != 'Array' && type != 'Object') return sample; var dict = new ActiveXObject('Scripting.Dictionary'); if(type == 'Array') {for(var key = 0; key < sample.length; key++) {dict.add(key, getdict(sample[key]));}} else {for(var key in sample) {dict.add(key, getdict(sample[key]));}} return dict;}"
        Set GetJsonDict = .Run("evaljson", JsonString, Nothing)
    End With
End Function

Function DrillDown(Source, Prop, Target, Value)
    Select Case False
    Case TypeName(Source) = "Dictionary"
    Case Source.exists(Prop)
    Case Else
        Select Case True
        Case TypeName(Source(Prop)) = "Dictionary"
            Set Target = Source(Prop)
            Value = Empty
        Case IsObject(Source(Prop))
            Set Value = Source(Prop)
            Set Target = Nothing
        Case Else
            Value = Source(Prop)
            Set Target = Nothing
        End Select
        DrillDown = True
        Exit Function
    End Select
    DrillDown = False
End Function

Понравилась статья? Поделить с друзьями:
  • Обработка excel файла в pandas
  • Обработка excel на сервере
  • Обработка excel в табличный документ
  • Обоснование начальной максимальной цены контракта по 44 фз в excel
  • Оборудование в word of tanks