在Windows上的Excel VBA中,如何获得string化的JSON表示而不是“”用于parsing的JSONvariables?

在这里回答我自己的问题。
我已经在Excel VBA中使用JSON做了一些工作,并且发布了大量的调查结果,我将以问答格式进行发布。https: //stackoverflow.com/help/self-answer http://blog.stackoverflow.com/2011 / 07 / ITS-OK-到问一答,你自己的问题/

所以在stackoverflow的其他地方,你可以看到关于在VBA中parsingJSON的问题,但他们似乎错过了一两招。

首先,我使用自定义的JSONparsing库进行了重新设置,而改用ScriptControl的Eval方法作为我所有JSON代码的基础。 而且我们也expression了本地微软解决scheme的偏好。

这里是一个先前的问题在Windows的Excel VBA中,如何缓解由IDE的大小写行为破坏的parsingJSON的点语法遍历问题? 在这个问题上build立。 它显示了如何使用VBA.CallByName比使用点语法来遍历parsing的JSON对象更健壮。 另外一个先前的问题在Windows上的Excel VBA中,如何通过parsing的JSON数组循环? 展示了它如何被用来访问数组元素。 但CallByName返回一个奇怪的variablestypes,它出现在监视窗口中作为Object / JScriptTypeInfo,并且如果一个types的Debug.Print在直接窗口中(或hover在variables上)得到无形的“[object Object]”。

我们如何改进这个并获得JSONstring表示?

这里是你在Debug.Print(?)之后的立即窗口中看到的一个屏幕截图,如果你将鼠标hover在一个variables上。

对象对象

这是系列5的问题3.这里是全系列

Q1 在Windows上的Excel VBA中,如何缓解由IDE的大小写行为破坏的已parsingJSON的点语法遍历问题?

Q2 在Windows上的Excel VBA中,如何通过parsing的JSON数组循环?

Q3 在Windows的Excel VBA中,如何获得string化的JSON表示而不是“[object object]”来parsingJSONvariables?

Q4 在Windows Excel VBA中,如何获取JSON密钥以预先取得“运行时错误438”:对象不支持此属性或方法“?

Q5 在Windows上的Excel VBA中,对于parsing的JSONvariables,这个JScriptTypeInfo究竟是什么?

解决与处理parsing的JSON对象有关的其他堆栈溢出问题的答案使用小脚本方法,我们可以在这里使用这种方法。

首先,我们承认道格拉斯·克罗克福德(Douglas Crockford)是“JavaScript:The Good Parts”的作者,并且是javascript专家。 所以我们很乐意在编码方面采用他的代码。 我们可以通过一个简单的Xml HTTP Request(通常缩写为XHR)来获取他的代码,并将返回结果传递给ScriptControl的AddCode方法。 然后添加一些代码,允许我们通过调用Douglas的库来覆盖“[object Object]”的默认表示forms。 然后确保我们dynamic地将覆盖dynamic添加到所有的JScriptTypeInfovariables中,包括用DecodeJsonString()包装的ScriptControl的Eval方法以及用GetJSONObject()包装的VBA.CallByName。

从而,

'Tools->References-> 'Microsoft Script Control 1.0; {0E59F1D2-1FBE-11D0-8FF2-00A0D10038BC}; C:\Windows\SysWOW64\msscript.ocx 'Microsoft Xml, v6.0 Option Explicit Private Function GetScriptEngine() As ScriptControl Static soScriptEngine As ScriptControl If soScriptEngine Is Nothing Then Set soScriptEngine = New ScriptControl soScriptEngine.Language = "JScript" soScriptEngine.AddCode GetJavaScriptLibrary("https://raw.githubusercontent.com/douglascrockford/JSON-js/master/json2.js") soScriptEngine.AddCode "function overrideToString(jsonObj) { jsonObj.toString = function() { return JSON.stringify(this); } }" End If Set GetScriptEngine = soScriptEngine End Function Private Function GetJavaScriptLibrary(ByVal sURL As String) As String Dim xHTTPRequest As MSXML2.XMLHTTP60 Set xHTTPRequest = New MSXML2.XMLHTTP60 xHTTPRequest.Open "GET", sURL, False xHTTPRequest.send GetJavaScriptLibrary = xHTTPRequest.responseText End Function Private Function DecodeJsonString(ByVal JsonString As String) As Object Dim oScriptEngine As ScriptControl Set oScriptEngine = GetScriptEngine Set DecodeJsonString = oScriptEngine.Eval("(" + JsonString + ")") Call oScriptEngine.Run("overrideToString", DecodeJsonString) '* this gives JSON rendering instead of "[object Object]" End Function Private Function GetJSONObject(ByVal obj As Object, ByVal sKey As String) As Object Dim objReturn As Object Set objReturn = VBA.CallByName(obj, sKey, VbGet) Call GetScriptEngine.Run("overrideToString", objReturn) '* this gives JSON rendering instead of "[object Object]" Set GetJSONObject = objReturn End Function Private Sub TestJSONParsingWithCallByName2() Dim sJsonString As String sJsonString = "{'key1': 'value1' ,'key2': { 'key3': 'value3' } }" Dim objJSON As Object Set objJSON = DecodeJsonString(sJsonString) Stop Dim objKey2 As Object Set objKey2 = GetJSONObject(objJSON, "key2") Debug.Print objKey2 Stop End Sub 

下面是显示JScriptTypeInfovariables的string的新代码的截图

在这里输入图像描述

谢谢S Meaden,这是我正在寻找的,一个简单的方法来将JSON对象转换为string。 我用你的想法,并将其与我的代码合并,但我不喜欢每次需要创build一个JSON对象进行连接和下载脚本的想法。 所以我把JSON2.js代码压缩成了一个函数,然后用它来代替我下一个正在粘贴的东西,也许有人会喜欢这个想法。

 Private Function JSON2() As String 'https://stackoverflow.com/questions/37711073/in-excel-vba-on-windows-how-to-get-stringified-json-respresentation-instead-of 'https://raw.githubusercontent.com/douglascrockford/JSON-js/master/json2.js JSON2 = _ "if(typeof JSON!==""object""){JSON={};}" _ & "(function(){""use strict"";var rx_one=/^[\],:{}\s]*$/;var rx_two=/\\(?:[""\\\/bfnrt]|u[0-9a-fA-F]{4})/g;var rx_three=/""[^""\\\n\r]*""|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;var rx_four=/(?:^|:|,)(?:\s*\[)+/g;var rx_escapable=/[\\""\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;var rx_dangerous=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;function f(n){return n<10?""0""+n:n;}" _ & "function this_value(){return this.valueOf();}" _ & "if(typeof Date.prototype.toJSON!==""function""){Date.prototype.toJSON=function(){return isFinite(this.valueOf())?this.getUTCFullYear()+""-""+" _ & "f(this.getUTCMonth()+1)+""-""+" _ & "f(this.getUTCDate())+""T""+" _ & "f(this.getUTCHours())+"":""+" _ & "f(this.getUTCMinutes())+"":""+" _ & "f(this.getUTCSeconds())+""Z"":null;};Boolean.prototype.toJSON=this_value;Number.prototype.toJSON=this_value;String.prototype.toJSON=this_value;}" _ & "var gap;var indent;var meta;var rep;function quote(string){rx_escapable.lastIndex=0;return rx_escapable.test(string)?""\""""+string.replace(rx_escapable,function(a){var c=meta[a];return typeof c===""string""?c:""\\u""+(""0000""+a.charCodeAt(0).toString(16)).slice(-4);})+""\"""":""\""""+string+""\"""";}" _ & "function str(key,holder){var i;var k;var v;var length;var mind=gap;var partial;var value=holder[key];if(value&&typeof value===""object""&&typeof value.toJSON===""function""){value=value.toJSON(key);}" _ & "if(typeof rep===""function""){value=rep.call(holder,key,value);}" JSON2 = JSON2 _ & "switch(typeof value){case""string"":return quote(value);case""number"":return isFinite(value)?String(value):""null"";case""boolean"":case""null"":return String(value);case""object"":if(!value){return""null"";}" _ & "gap+=indent;partial=[];if(Object.prototype.toString.apply(value)===""[object Array]""){length=value.length;for(i=0;i<length;i+=1){partial[i]=str(i,value)||""null"";}" _ & "v=partial.length===0?""[]"":gap?""[\n""+gap+partial.join("",\n""+gap)+""\n""+mind+""]"":""[""+partial.join("","")+""]"";gap=mind;return v;}" _ & "if(rep&&typeof rep===""object""){length=rep.length;for(i=0;i<length;i+=1){if(typeof rep[i]===""string""){k=rep[i];v=str(k,value);if(v){partial.push(quote(k)+(gap?"": "":"":"")+v);}}}}else{for(k in value){if(Object.prototype.hasOwnProperty.call(value,k)){v=str(k,value);if(v){partial.push(quote(k)+(gap?"": "":"":"")+v);}}}}" _ & "v=partial.length===0?""{}"":gap?""{\n""+gap+partial.join("",\n""+gap)+""\n""+mind+""}"":""{""+partial.join("","")+""}"";gap=mind;return v;}}" _ & "if(typeof JSON.stringify!==""function""){meta={""\b"":""\\b"",""\t"":""\\t"",""\n"":""\\n"",""\f"":""\\f"",""\r"":""\\r"",""\"""":""\\\"""",""\\"":""\\\\""};JSON.stringify=function(value,replacer,space){var i;gap="""";indent="""";if(typeof space===""number""){for(i=0;i<space;i+=1){indent+="" "";}}else if(typeof space===""string""){indent=space;}" _ & "rep=replacer;if(replacer&&typeof replacer!==""function""&&(typeof replacer!==""object""||typeof replacer.length!==""number"")){throw new Error(""JSON.stringify"");}" _ & "return str("""",{"""":value});};}" _ & "if(typeof JSON.parse!==""function""){JSON.parse=function(text,reviver){var j;function walk(holder,key){var k;var v;var value=holder[key];if(value&&typeof value===""object""){for(k in value){if(Object.prototype.hasOwnProperty.call(value,k)){v=walk(value,k);if(v!==undefined){value[k]=v;}else{delete value[k];}}}}" _ & "return reviver.call(holder,key,value);}" _ & "text=String(text);rx_dangerous.lastIndex=0;if(rx_dangerous.test(text)){text=text.replace(rx_dangerous,function(a){return""\\u""+" _ & "(""0000""+a.charCodeAt(0).toString(16)).slice(-4);});}" _ & "if(rx_one.test(text.replace(rx_two,""@"").replace(rx_three,""]"").replace(rx_four,""""))){j=eval(""(""+text+"")"");return(typeof reviver===""function"")?walk({"""":j},""""):j;}" _ & "throw new SyntaxError(""JSON.parse"");};}}());" End Function