|
| 1 | +Attribute VB_Name = "simpleJsonJSParser" |
| 2 | + |
| 3 | +' Douglas Crockford json2.js implementation for VBA |
| 4 | +' version 2022-09-29 |
| 5 | +' https://github.com/douglascrockford/JSON-js/blob/master/json2.js |
| 6 | +' |
| 7 | +' simpleJsonJSParser derived from jsJsonParser (beta) v0.1.2 |
| 8 | +' Copyright (C) 2021 omegastripes |
| 9 | +' omegastripes@yandex.ru |
| 10 | +' https://github.com/omegastripes/VBA-JSON-parser |
| 11 | +' |
| 12 | +' This program is free software: you can redistribute it and/or modify |
| 13 | +' it under the terms of the GNU General Public License as published by |
| 14 | +' the Free Software Foundation, either version 3 of the License, or |
| 15 | +' (at your option) any later version. |
| 16 | +' |
| 17 | +' This program is distributed in the hope that it will be useful, |
| 18 | +' but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 19 | +' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 20 | +' GNU General Public License for more details. |
| 21 | +' |
| 22 | +' You should have received a copy of the GNU General Public License |
| 23 | +' along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 24 | + |
| 25 | +Option Explicit |
| 26 | + |
| 27 | +Sub test() |
| 28 | + Dim sample |
| 29 | + sample = "[{""a"":55}, 100]" |
| 30 | + Dim result |
| 31 | + Dim js |
| 32 | + Dim ok |
| 33 | + assign parseToVb(sample, js, , ok), result |
| 34 | + Debug.Print jsonParser.stringify(js, "", vbTab) |
| 35 | + Stop |
| 36 | +End Sub |
| 37 | + |
| 38 | +Function jsonParser() |
| 39 | + Static document As Object |
| 40 | + Static json As Object |
| 41 | + If json Is Nothing Then |
| 42 | + Set document = CreateObject("htmlfile") |
| 43 | + document.Write "<meta http-equiv=""x-ua-compatible"" content=""IE=9"" />'" |
| 44 | + document.parentWindow.execScript Replace( _ |
| 45 | + "`object`!=typeof JSON&&(JSON={}),function(){`use strict`;function f(t){return 10>t?`0`+t:t}function this_value(){return this.valueOf()}function quote(t){return rx_escapable.lastIndex=" & _ |
| 46 | + "0,rx_escapable.test(t)?'`'+t.replace(rx_escapable,function(t){var e=meta[t];return`string`==typeof e?e:`\\u`+(`0000`+t.charCodeAt(0).toString(16)).slice(-4)})+'`':'`'+t+'`'}function str(t,e){var r,n,o,u,f,a=gap,i=e[t];switch(i&&`object`==typeof i&&`f" & _ |
| 47 | + "unction`==typeof i.toJSON&&(i=i.toJSON(t)),`function`==typeof rep&&(i=rep.call(e,t,i)),typeof i){case`string`:return quote(i);case`number`:return isFinite(i)?String(i):`null`;case`boolean`:case`null`:return String(i);case`object`:if(!i)return`null`;i" & _ |
| 48 | + "f(gap+=indent,f=[],`[object Array]`===Object.prototype.toString.apply(i)){for(u=i.length,r=0;u>r;r+=1)f[r]=str(r,i)||`null`;return o=0===f.length?`[]`:gap?`[\n`+gap+f.join(`,\n`+gap)+`\n`+a+`]`:`[`+f.join(`,`)+`]`,gap=a,o}if(rep&&`object`==typeof rep" & _ |
| 49 | + ")for(u=rep.length,r=0;u>r;r+=1)`string`==typeof rep[r]&&(n=rep[r],o=str(n,i),o&&f.push(quote(n)+(gap?`: `:`:`)+o));else for(n in i)Object.prototype.hasOwnProperty.call(i,n)&&(o=str(n,i),o&&f.push(quote(n)+(gap?`: `:`:`)+o));return o=0===f.length?`{}`" & _ |
| 50 | + ":gap?`{\n`+gap+f.join(`,\n`+gap)+`\n`+a+`}`:`{`+f.join(`,`)+`}`,gap=a,o}}var rx_one=/^[\],:{}\s]*$/,rx_two=/\\(?:[`\\\/bfnrt]|u[0-9a-fA-F]{4})/g,rx_three=/`[^`\\\n\r]*`|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,rx_four=/(?:^|:|,)(?:\s*\[)+/" & _ |
| 51 | + "g,rx_escapable=/[\\`\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,rx_dangerous=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\u" & _ |
| 52 | + "fff0-\uffff]/g;`function`!=typeof Date.prototype.toJSON&&(Date.prototype.toJSON=function(){return isFinite(this.valueOf())?this.getUTCFullYear()+`-`+f(this.getUTCMonth()+1)+`-`+f(this.getUTCDate())+`T`+f(this.getUTCHours())+`:`+f(this.getUTCMinutes()" & _ |
| 53 | + ")+`:`+f(this.getUTCSeconds())+`Z`:null},Boolean.prototype.toJSON=this_value,Number.prototype.toJSON=this_value,String.prototype.toJSON=this_value);var gap,indent,meta,rep;`function`!=typeof JSON.stringify&&(meta={`\b`:`\\b`,` `:`\\t`,`\n`:`\\n`,`\f`:" & _ |
| 54 | + "`\\f`,`\r`:`\\r`,'`':'\\`',`\\`:`\\\\`},JSON.stringify=function(t,e,r){var n;if(gap=``,indent=``,`number`==typeof r)for(n=0;r>n;n+=1)indent+=` `;else`string`==typeof r&&(indent=r);if(rep=e,e&&`function`!=typeof e&&(`object`!=typeof e||`number`!=typeo" & _ |
| 55 | + "f e.length))throw new Error(`JSON.stringify`);return str(``,{``:t})}),`function`!=typeof JSON.parse&&(JSON.parse=function(text,reviver){function walk(t,e){var r,n,o=t[e];if(o&&`object`==typeof o)for(r in o)Object.prototype.hasOwnProperty.call(o,r)&&(" & _ |
| 56 | + "n=walk(o,r),void 0!==n?o[r]=n:delete o[r]);return reviver.call(t,e,o)}var j;if(text=String(text),rx_dangerous.lastIndex=0,rx_dangerous.test(text)&&(text=text.replace(rx_dangerous,function(t){return`\\u`+(`0000`+t.charCodeAt(0).toString(16)).slice(-4)" & _ |
| 57 | + "})),rx_one.test(text.replace(rx_two,`@`).replace(rx_three,`]`).replace(rx_four,``)))return j=eval(`(`+text+`)`),`function`==typeof reviver?walk({``:j},``):j;throw new SyntaxError(`JSON.parse`)})}();var json=JSON;json.GetType=json.getType=function(t){" & _ |
| 58 | + "switch(typeof t){case`string`:case`number`:case`boolean`:case`null`:return typeof t;case`object`:if(!t)return`null`;if(`[object Array]`===Object.prototype.toString.apply(t))return`array`}return`object`};json.CloneDict=json.cloneDict=function(t,e){for" & _ |
| 59 | + "(var r in t)e.Add(r,t[r]);return e};json.Parse=json.parse;json.Stringify=json.stringify;", _ |
| 60 | + "`", """" _ |
| 61 | + ) |
| 62 | + Set json = document.parentWindow.json |
| 63 | + End If |
| 64 | + Set jsonParser = json |
| 65 | +End Function |
| 66 | + |
| 67 | +Public Function parseToVb(sample, Optional jsonData, Optional result, Optional success) |
| 68 | + result = Empty |
| 69 | + success = False |
| 70 | + On Error Resume Next |
| 71 | + Set jsonData = jsonParser.parse(sample) |
| 72 | + If jsonData Is Nothing Then Exit Function |
| 73 | + Dim vbaJsonObject |
| 74 | + repack jsonData, result |
| 75 | + If Err.Number <> 0 Then Exit Function |
| 76 | + parseToVb = 1 |
| 77 | + assign result, parseToVb |
| 78 | + success = True |
| 79 | +End Function |
| 80 | + |
| 81 | +Private Sub repack(source, result) |
| 82 | + Select Case jsonParser.getType(source) |
| 83 | + Case "array" |
| 84 | + result = jsonParser.cloneDict(source, CreateObject("Scripting.Dictionary")).items |
| 85 | + Dim i |
| 86 | + For i = 0 To UBound(result) |
| 87 | + Dim ret |
| 88 | + repack result(i), ret |
| 89 | + If IsObject(ret) Then |
| 90 | + Set result(i) = ret |
| 91 | + Else |
| 92 | + result(i) = ret |
| 93 | + End If |
| 94 | + Next |
| 95 | + Case "object" |
| 96 | + Set result = jsonParser.cloneDict(source, CreateObject("Scripting.Dictionary")) |
| 97 | + For Each i In result |
| 98 | + repack result(i), ret |
| 99 | + If IsObject(ret) Then |
| 100 | + Set result(i) = ret |
| 101 | + Else |
| 102 | + result(i) = ret |
| 103 | + End If |
| 104 | + Next |
| 105 | + Case "string" |
| 106 | + result = CStr(source) |
| 107 | + Case "number" |
| 108 | + result = CDbl(source) |
| 109 | + Case "boolean" |
| 110 | + result = CBool(source) |
| 111 | + Case "null" |
| 112 | + result = Null |
| 113 | + End Select |
| 114 | +End Sub |
| 115 | + |
| 116 | +Sub assign(src, dest) |
| 117 | + If IsObject(src) Then |
| 118 | + Set dest = src |
| 119 | + Else |
| 120 | + dest = src |
| 121 | + End If |
| 122 | +End Sub |
| 123 | + |
| 124 | + |
0 commit comments