系列文章索引
Excel 也可以玩 REST
Excel 也可以玩 REST (2)
Excel 也可以玩 REST (3)
本篇來做幾個準(zhǔn)備動作,講解一下接下來需要用到的 VBA 轉(zhuǎn) Json 格式,以及涉及到的 VBA 字符串中 雙引號 的處理方法。
VBA 字符串的雙引號問題
首先我們來看看 雙引號 問題。為什么要提到這個呢?因?yàn)槿绻褂?Ajax 原生 POST 請求,請求頭里設(shè)置 Content-Type:application/json
,請求的參數(shù)會顯示在 Request Payload 中。Json 格式自然要用到雙引號。
假設(shè)我們有這樣一個 json 字符串:
{
"username": "admin",
"password": "w123456"
}
對于習(xí)慣了多年 Python 類似語言對 json 字符串的簡潔,打心底對 VBA 的麻煩深惡痛絕。在 VBA 中,表達(dá)上面的字符串有兩種方法,第一種方法,使用 Chr(34)
函數(shù)。ASCII 碼 34 對應(yīng)雙引號。這種方法這個 json 字符串看起來是這樣的:
Dim payload As String
payload = "{" & Chr(34) & "username" & Chr(34) & ":" _
& Chr(34) & "admin" & Chr(34) & "," & Chr(34) _
& "password" & Chr(34) & ":" & Chr(34) & "123456" & Chr(34) & "}"
是不是非常不直觀?而且容易弄錯對吧?那么看看第二種方法。使用 ""
(兩個雙引號) 表達(dá)一個雙引號。不知道為啥微軟不用其他語言類似的轉(zhuǎn)義字符 (escape characters)。用第二種方法的代碼如下:
Dim payload As String
payload = "{" & """username""" _
& ":" & """admin""" & "," _
& """password""" & ":" & """123456""" & "}"
感覺好一點(diǎn),但要習(xí)慣一下。我思考了一下,覺得可以先用單引號,然后用 Replace()
函數(shù)將單引號替換成雙引號的方式,不是 VBA 標(biāo)準(zhǔn)的字符串表達(dá)方法,但相對直觀:
Dim payload As String
payload = "{'username':'admin','password':'123456'}"
payload = Replace(payload, "'", Chr(34))
如果是很復(fù)雜的 json 字符串,用以上方法都是極不好的。所以,接下來就隆重介紹上一篇博文所提到的 https://github.com/VBA-tools/VBA-JSON 模塊。這個模塊的 ConvertToJson()
函數(shù)可以將 Dictionary,Collection 和 Array 轉(zhuǎn)換成 Json 字符串。用起來也簡單:
Public Sub convert_json_test()
Dim loginData As New Dictionary
loginData.Add "username", "admin"
loginData.Add "password", "123456"
Debug.Print JsonConverter.ConvertToJson(loginData)
End Sub
Excel 數(shù)據(jù)如何轉(zhuǎn)成 Json
VBA-JSON 這個模塊,還可以方便地將 Excel 中的數(shù)據(jù)轉(zhuǎn)換成 Json 字符串,對需要轉(zhuǎn)換類似數(shù)據(jù)庫中數(shù)據(jù)表的數(shù)據(jù)也很方便。上一篇我們從網(wǎng)頁中得到了如下圖所示的數(shù)據(jù):
現(xiàn)在需要將數(shù)據(jù)再轉(zhuǎn)換成為 Json。因?yàn)槊恳恍袛?shù)據(jù)都是具有相同數(shù)據(jù)結(jié)構(gòu),所以自然要用到 Json 數(shù)組,最后的結(jié)果應(yīng)該類似下面這樣:
{
"value": [
{
"ID": 0,
"Name": "Bread",
"Description": "Whole grain bread",
"ReleaseDate": "1992-01-01T00:00:00",
"Rating": 4,
"Price": 2.5
},
{
"ID": 1,
"Name": "Milk",
"Description": "Low fat milk",
"ReleaseDate": "1995-10-01T00:00:00",
"Rating": 3,
"Price": 3.5
}
...
]
}
類似地,我們使用 Dictionary 和 Collection 來達(dá)到目的:
Public Sub sheet_to_json()
Dim dict(1 To 11) As New Dictionary
Dim prodCol As New Collection
Dim i As Integer
For i = 1 To 11
dict(i).Add "ID", Sheet1.Cells(i + 1, 1).Value
dict(i).Add "Name", Sheet1.Cells(i + 1, 2).Value
dict(i).Add "Description", Sheet1.Cells(i + 1, 3).Value
dict(i).Add "ReleaseDate", Sheet1.Cells(i + 1, 4).Value
dict(i).Add "DiscontinuedDate", Sheet1.Cells(i + 1, 5).Value
dict(i).Add "Rating", Sheet1.Cells(i + 1, 6).Value
dict(i).Add "Price", Sheet1.Cells(i + 1, 7).Value
prodCol.Add dict(i)
Next
Debug.Print "{" & """value""" & ":" & JsonConverter.ConvertToJson(prodCol) & "}"
End Sub
基本上,這個可以作為 Excel 轉(zhuǎn) Json 的通用方法了。有了本篇的準(zhǔn)備,接下來可以在 Excel 中提交各種 http 請求。后面的博文準(zhǔn)備接著講解基于 http 請求實(shí)現(xiàn)數(shù)據(jù)庫 CRUD 的操作。也會說說基于 Excel 的 http 請求有什么應(yīng)用場景。