ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 19680|回复: 39

[分享] Vba Json

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2013-4-6 20:37 | 显示全部楼层 |阅读模式
本帖已被收录到知识树中,索引项:网页交互
创建一个“类模块”,命名为“VbaJson”
然后把下面的代码粘贴进去:


  1. Private Whitespace, NumberRegex, StringChunk
  2. Private b, f, r, n, t

  3. Private Sub Class_Initialize()
  4.     Whitespace = " " & vbTab & vbCr & vbLf
  5.     b = ChrW(8)
  6.     f = vbFormFeed
  7.     r = vbCr
  8.     n = vbLf
  9.     t = vbTab
  10.     Set NumberRegex = New RegExp
  11.     NumberRegex.Pattern = "(-?(?:0|[1-9]\d*))(\.\d+)?([eE][-+]?\d+)?"
  12.     NumberRegex.Global = False
  13.     NumberRegex.MultiLine = True
  14.     NumberRegex.IgnoreCase = True
  15.     Set StringChunk = New RegExp
  16.     StringChunk.Pattern = "([\s\S]*?)([""\\\x00-\x1f])"
  17.     StringChunk.Global = False
  18.     StringChunk.MultiLine = True
  19.     StringChunk.IgnoreCase = True
  20. End Sub

  21. Public Function encode(ByRef obj)
  22.     Dim buf, i, c, g
  23.     Set buf = CreateObject("Scripting.Dictionary")
  24.     Select Case VarType(obj)
  25.     Case vbNull
  26.         buf.Add buf.Count, "null"
  27.     Case vbBoolean
  28.         If obj Then
  29.             buf.Add buf.Count, "true"
  30.         Else
  31.             buf.Add buf.Count, "false"
  32.         End If
  33.     Case vbInteger, vbLong, vbSingle, vbDouble
  34.         buf.Add buf.Count, obj
  35.     Case vbString
  36.         buf.Add buf.Count, """"
  37.         For i = 1 To Len(obj)
  38.             c = Mid(obj, i, 1)
  39.             Select Case c
  40.             Case """": buf.Add buf.Count, """"
  41.             Case "": buf.Add buf.Count, "\"
  42.             Case "/": buf.Add buf.Count, "/"
  43.             Case b: buf.Add buf.Count, "\b"
  44.             Case f: buf.Add buf.Count, "\f"
  45.             Case r: buf.Add buf.Count, "\r"
  46.             Case n: buf.Add buf.Count, "\n"
  47.             Case t: buf.Add buf.Count, "\t"
  48.             Case Else
  49.                 If AscW(c) >= 0 And AscW(c) <= 31 Then
  50.                     c = Right("0" & Hex(AscW(c)), 2)
  51.                     buf.Add buf.Count, "\u00" & c
  52.                 Else
  53.                     buf.Add buf.Count, c
  54.                 End If
  55.             End Select
  56.         Next
  57.         buf.Add buf.Count, """"
  58.     Case vbArray + vbVariant
  59.         g = True
  60.         buf.Add buf.Count, "["
  61.         For Each i In obj
  62.             If g Then g = False Else buf.Add buf.Count, ","
  63.             buf.Add buf.Count, encode(i)
  64.         Next
  65.         buf.Add buf.Count, "]"
  66.     Case vbObject
  67.         If TypeName(obj) = "Dictionary" Then
  68.             g = True
  69.             buf.Add buf.Count, "{"
  70.             For Each i In obj
  71.                 If g Then g = False Else buf.Add buf.Count, ","
  72.                 buf.Add buf.Count, """" & i & """" & ":" & encode(obj(i))
  73.             Next
  74.             buf.Add buf.Count, "}"
  75.         Else
  76.             Err.Raise 8732, , "None dictionary object"
  77.         End If
  78.     Case Else
  79.         buf.Add buf.Count, """" & CStr(obj) & """"
  80.     End Select
  81.     encode = Join(buf.Items, "")
  82. End Function

  83. Public Function Decode(ByRef str)
  84.     Dim idx
  85.     idx = SkipWhitespace(str, 1)
  86.     If Mid(str, idx, 1) = "{" Then
  87.         Set Decode = ScanOnce(str, 1)
  88.     Else
  89.         Decode = ScanOnce(str, 1)
  90.     End If
  91. End Function

  92. Private Function ScanOnce(ByRef str, ByRef idx)
  93.     Dim c, ms
  94.     idx = SkipWhitespace(str, idx)
  95.     c = Mid(str, idx, 1)
  96.     If c = "{" Then
  97.         idx = idx + 1
  98.         Set ScanOnce = parseObject(str, idx)
  99.         Exit Function
  100.     ElseIf c = "[" Then
  101.         idx = idx + 1
  102.         ScanOnce = parseArray(str, idx)
  103.         Exit Function
  104.     ElseIf c = """" Then
  105.         idx = idx + 1
  106.         ScanOnce = parseString(str, idx)
  107.         Exit Function
  108.     ElseIf c = "n" And StrComp("null", Mid(str, idx, 4)) = 0 Then
  109.         idx = idx + 4
  110.         ScanOnce = Null
  111.         Exit Function
  112.     ElseIf c = "t" And StrComp("true", Mid(str, idx, 4)) = 0 Then
  113.         idx = idx + 4
  114.         ScanOnce = True
  115.         Exit Function
  116.     ElseIf c = "f" And StrComp("false", Mid(str, idx, 5)) = 0 Then
  117.         idx = idx + 5
  118.         ScanOnce = False
  119.         Exit Function
  120.     End If
  121.     Set ms = NumberRegex.Execute(Mid(str, idx))
  122.     If ms.Count = 1 Then
  123.         idx = idx + ms(0).Length
  124.         ScanOnce = CDbl(ms(0))
  125.         Exit Function
  126.     End If
  127.     Err.Raise 8732, , "No JSON object could be ScanOnced"
  128. End Function

  129. Private Function parseObject(ByRef str, ByRef idx)
  130.     Dim c, key, value
  131.     Set parseObject = CreateObject("Scripting.Dictionary")
  132.     idx = SkipWhitespace(str, idx)
  133.     c = Mid(str, idx, 1)
  134.     If c = "}" Then
  135.         Exit Function
  136.     ElseIf c <> """" Then
  137.         Err.Raise 8732, , "Expecting property name"
  138.     End If
  139.     idx = idx + 1
  140.     Do
  141.         key = parseString(str, idx)
  142.         idx = SkipWhitespace(str, idx)
  143.         If Mid(str, idx, 1) <> ":" Then
  144.             Err.Raise 8732, , "Expecting : delimiter"
  145.         End If
  146.         idx = SkipWhitespace(str, idx + 1)
  147.         If Mid(str, idx, 1) = "{" Then
  148.             Set value = ScanOnce(str, idx)
  149.         Else
  150.             value = ScanOnce(str, idx)
  151.         End If
  152.         parseObject.Add key, value
  153.         idx = SkipWhitespace(str, idx)
  154.         c = Mid(str, idx, 1)
  155.         If c = "}" Then
  156.             Exit Do
  157.         ElseIf c <> "," Then
  158.             Err.Raise 8732, , "Expecting , delimiter"
  159.         End If
  160.         idx = SkipWhitespace(str, idx + 1)
  161.         c = Mid(str, idx, 1)
  162.         If c <> """" Then
  163.             Err.Raise 8732, , "Expecting property name"
  164.         End If
  165.         idx = idx + 1
  166.     Loop
  167.     idx = idx + 1
  168. End Function

  169. Private Function parseArray(ByRef str, ByRef idx)
  170.     Dim c, values, value
  171.     Set values = CreateObject("Scripting.Dictionary")
  172.     idx = SkipWhitespace(str, idx)
  173.     c = Mid(str, idx, 1)
  174.     If c = "]" Then
  175.         parseArray = values.Items
  176.         Exit Function
  177.     End If
  178.     Do
  179.         idx = SkipWhitespace(str, idx)
  180.         If Mid(str, idx, 1) = "{" Then
  181.             Set value = ScanOnce(str, idx)
  182.         Else
  183.             value = ScanOnce(str, idx)
  184.         End If
  185.         values.Add values.Count, value
  186.         idx = SkipWhitespace(str, idx)
  187.         c = Mid(str, idx, 1)
  188.         If c = "]" Then
  189.             Exit Do
  190.         ElseIf c <> "," Then
  191.             Err.Raise 8732, , "Expecting , delimiter"
  192.         End If
  193.         idx = idx + 1
  194.     Loop
  195.     idx = idx + 1
  196.     parseArray = values.Items
  197. End Function

  198. Private Function parseString(ByRef str, ByRef idx)
  199.     Dim chunks, content, terminator, ms, esc, char
  200.     Set chunks = CreateObject("Scripting.Dictionary")
  201.     Do
  202.         Set ms = StringChunk.Execute(Mid(str, idx))
  203.         If ms.Count = 0 Then
  204.             Err.Raise 8732, , "Unterminated string starting"
  205.         End If
  206.         content = ms(0).Submatches(0)
  207.         terminator = ms(0).Submatches(1)
  208.         If Len(content) > 0 Then
  209.             chunks.Add chunks.Count, content
  210.         End If
  211.         idx = idx + ms(0).Length
  212.         If terminator = """" Then
  213.             Exit Do
  214.         ElseIf terminator <> "" Then
  215.             Err.Raise 8732, , "Invalid control character"
  216.         End If
  217.         esc = Mid(str, idx, 1)
  218.         If esc <> "u" Then
  219.             Select Case esc
  220.             Case """": char = """"
  221.             Case "": char = ""
  222.             Case "/": char = "/"
  223.             Case "b": char = b
  224.             Case "f": char = f
  225.             Case "n": char = n
  226.             Case "r": char = r
  227.             Case "t": char = t
  228.             Case Else: Err.Raise 8732, , "Invalid escape"
  229.             End Select
  230.             idx = idx + 1
  231.         Else
  232. : char = ChrW("&H" & Mid(str, idx + 1, 4))
  233.             idx = idx + 5
  234.         End If
  235.         chunks.Add chunks.Count, char
  236.     Loop
  237.     parseString = Join(chunks.Items, "")
  238. End Function

  239. Private Function SkipWhitespace(ByRef str, ByVal idx)
  240.     Do While idx <= Len(str) And _
  241.        InStr(Whitespace, Mid(str, idx, 1)) > 0
  242.         idx = idx + 1
  243.     Loop
  244.     SkipWhitespace = idx
  245. End Function

  246. Function ParseJson(strJson)
  247.     Set HTML = CreateObject("htmlfile")
  248.     Set Window = HTML.parentWindow
  249.     Window.execScript "var json = " & strJson, "JScript"
  250.     Set ParseJson = Window.json
  251. End Function
复制代码

然后,用下面的代码测试:

  1. Private Sub CommandButton1_Click()    '时时彩
  2.     Dim tt As String
  3.     Columns("B:B").NumberFormatLocal = "@"
  4.     With CreateObject("WinHttp.WinHttpRequest.5.1")
  5.         .Open "GET", "http://baidu.lecai.com/lottery/draw/view/200", False
  6.         .send
  7.         tt = Split(Split(Replace(.responseText, "[]", """"""), "var phaseData = ")(1), ";")(0)
  8.         With CreateObject("new:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
  9.             .SetText tt
  10.             .PutInClipboard
  11.         End With
  12.         '读取json开始
  13.         Dim json
  14.         Set json = New VbaJson
  15.         Set r = json.Decode(tt)
  16.         i = 0
  17.         For Each v In r
  18.             For Each s In r(v)
  19.                 t = ""
  20.                 For Each u In r(v)(s)("result")("red")
  21.                     t = t & u
  22.                 Next
  23.                 i = i + 1
  24.                 Cells(i, 1) = s
  25.                 Cells(i, 2) = t
  26.                 Cells(i, 3) = r(v)(s)("open_time")
  27.             Next
  28.         Next
  29.         Set json = Nothing
  30.         '读取json结束
  31.     End With
  32. End Sub
复制代码


评分

2

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-4-6 20:40 | 显示全部楼层
这个是上面的附件:


VBAJSON.rar

29.27 KB, 下载次数: 726

TA的精华主题

TA的得分主题

发表于 2013-4-6 21:07 | 显示全部楼层

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-4-7 07:21 | 显示全部楼层
本帖最后由 蓝天630902 于 2013-4-7 16:19 编辑

这个是
game88city
不过呢,最好是不要赌,赌必输。

game88city.rar

33.92 KB, 下载次数: 344

点评

说得很有哲理,高  发表于 2013-4-23 20:11

TA的精华主题

TA的得分主题

发表于 2013-4-7 08:35 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
感谢分享,这样就方便很多了

TA的精华主题

TA的得分主题

发表于 2013-4-7 11:24 | 显示全部楼层
偶是新手,水平还没到建立类的程度,但相信总有一天会看懂的。谢谢分享!

TA的精华主题

TA的得分主题

发表于 2013-4-7 14:38 | 显示全部楼层
蓝天630902 发表于 2013-4-7 07:21
这个是
game88city
不过呢,最好是不要赌,赌必输。

不能运行,你的代码没处理防盗链吧。

另外,是不是给人做义工去了?{:soso_e112:}

TA的精华主题

TA的得分主题

发表于 2013-4-14 19:46 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
哇,这么厉害,只能仰望之。

TA的精华主题

TA的得分主题

发表于 2013-4-15 00:02 | 显示全部楼层

请问要如何下载百度词典里的数据?想了一个晚上还想不出来。(附件已上传)谢谢

本帖最后由 cumulonimbus 于 2013-4-15 14:05 编辑

百度词典下载{:soso_e113:}已解决。

TA的精华主题

TA的得分主题

发表于 2013-4-15 12:22 | 显示全部楼层
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-5-9 09:18 , Processed in 0.038235 second(s), 16 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表