I'm not arguing with you - It's definitely a good suggestion.
Printable View
The JsonBag has a property for this, just as documented (unlike so much undocumented closed-source code of dubious attribution people promote):
It is a trivial matter to assign True to this property or even to alter its default value to True. The latter is spelled out pretty explicitly:Quote:
DecimalMode As Boolean [read/write]
Defaults to False.
The setting of this property determines how numbers are parsed and serialized. See the discussion Impact Of DecimalMode Setting above.
This should only be set on a JsonBag instance that is being used as a "root" document node when it is empty.
If somebody can't figure out how to change the default value to True they have a bigger problem. ;)Code:Private Sub Class_Initialize()
TypeNameOfMe = TypeName(Me)
PtrWhiteSpace = StrPtr(WHITE_SPACE)
Clear 'Creates Collections.
DecimalMode = False 'Default
Whitespace = False 'Default
WhitespaceIndent = 4 'Default.
WhitespaceNewLine = vbNewLine 'Default.
End Sub
You're repeating yourself.
My point was, that this property would be completely unnecessary (with just a slight addition in your parsing-code).
As it is, it is just confusing - especially since it behaves inconsistently (and is *not* adhering to your "documentation").
Since you say in your Doc: "...this property determines how numbers are parsed and serialized..."
Example:
So - the latter result (of JB2 above) is not holding its promise (to serialize in Double-Format, as the Doc states),Code:Dim JB1 As New JsonBag
JB1.DecimalMode = False '<- use Double-Mode
JB1.JSON = "{""longNumber"":1556427511093526531}"
Debug.Print JB1("longNumber") 'will print 1.55642751109353E+18
Dim JB2 As New JsonBag
JB2.DecimalMode = False '<- use Double-Mode
JB2("longNumber") = CDec("1556427511093526531")
Debug.Print JB2.JSON 'will print {"longNumber":1556427511093526531}
since a Double clearly cannot hold an integer-value in that precision (as the first printout of JB1 shows).
So, as already suggested - either fix your code - or your wrong documentation
(now curious whether you're able to manage one of the two things without further sidekicks,
a simple "dear fellow-developer, thank you for pointing that out" would already be enough... <g>).
Olaf
Perhaps you didn't read the documentation?
Under the discussion on DecimalMode it says:
The behavior you showed above matches this exactly. If anything perhaps there is a small flaw there (the bold text you quoted), but unlike some people I provide both the source and documentation. I'll keep this documentation change in mind for a future release. At least it has been covered to death here now though.Quote:
This property setting only impacts assignments to the JSON property, i.e. parsing serialized JSON. If you directly assign a numeric value the actual type your code used is stored in the object hierarchy data. Of course as noted it may also impact retrieval from the JSON property, i.e. serializing the tree into JSON text.
Let's cut back on the sniping shall we... in both directions. You've both provided some excellent work in this forum and both deserve to have that acknowledged.
keep any criticism friendly and constructive and let's receive it in the same vein.
Hey guys,
i' on was on the version 1,6, it was working perfectly, thanks for great job.
But :) One week ago our IT updatet the Office 2010 to 64 bit and it didn't work
Ok, i updatet the JsonBag to version 2,5 and now i have the problem with "Names"
"Set ContractNames = JsRoot.Item(x1).Item("rows").Item(x2).Item("data").Names"
unfortunately after set the object is always ContractNames = nothing
Can you help me please?
json is attached
Hey guys!
our it updated the office to the 64 bit version, so i updated jsonbag to the 2.5 version and now i have a problem with the "names"
Set ContractNames = JsRoot.Item(x1).Item("rows").Item(x2).Item("data").Names
after set is the object ContractNames = nothing
can you tell me, what i am doing wrong? thanks in advance
PS: json is attached
PSS: sorry for my bad english
Names will never return a Collection. The value will either be a simple value type or else a JsonBag instance.
We have no way to guess what your "x1" variable is or what value it has. That makes it very difficult to explore for possible problems.
The Json text in your attachment seems to parse just fine in JsonBag.
I see nothing here to suggest that moving to 64-bit VBA makes any difference. Are you sure this ever worked before in 32-bit VBA?
Hi there,
I'm trying to parse Json data but without any luck with v1.8 on Windows 7 64-bit:
I'm unable to get any readings by:Code:{
"ESP8266": {
"NTC": {
"temperature": 18.03633
},
"DHT11": {
"temperature": 19,
"humidity": 59
},
"SHT30": {
"temperature": 19.48043,
"humidity": 63.17846
},
"BMP180": {
"temperature": 19.7,
"pressure": 997.52
},
"WU": {
"temperature": 1.6,
"humidity": 98,
"pressure": 1006
}
}
}
Also got some error saying:Code:Debug.Print objJson.Item("ESP8266").Item("NTC").Item("temperature")
But, if I check the feeded JSON Object, it's clear reading.Code:Requested Item by key doesn't exist (case mismatch?)
Code:Debug.Print objJson.JSON
So, I don't know what I'm doing wrong.Code:{"ESP8266":{"NTC":{"temperature":18.03633},"DHT11":{"temperature":19,"humidity":58},"SHT30":{"temperature":19.73144,"humidity":62.63981},"BMP180":{"temperature":20.1,"pressure":997.25},"WU":{"temperature":1.6,"humidity":97,"pressure":1006}}}
Please advise!
Kind regards,
Viktor
Anyway, after one and a half day strugling, I figured out that I was destroying the Json Object on the half way! :D
I use the JsonBag 2.5
and this code works perfect for me
Code:Dim J As New JsonBag
J.JSON = Text1.Text
Debug.Print J.Item("ESP8266").Item("NTC").Item("temperature")
Hi there,
Why I'm getting this from the Jeson parser:
when I'm feeding with these values:Code:{
"ESP8266": {
"NTC": {
"temperature": 18.65
},
"DHT11": {
"temperature": 21,
"humidity": 48
},
"SHT30": {
"temperature": 21.59,
"humidity": 56.03
},
"BMP180": {
"temperature": 22.1,
"pressure": 999.06
},
"WU": {
"temperature": 8.6,
"humidity": 77,
"pressure": 1006
}
}
}
So, where are my decimals gone?Code:{
"ESP8266": {
"NTC": {
"temperature": 18.65
},
"DHT11": {
"temperature": 21.00,
"humidity": 48.00
},
"SHT30": {
"temperature": 21.59,
"humidity": 56.03
},
"BMP180": {
"temperature": 22.10,
"pressure": 999.06
},
"WU": {
"temperature": 8.60,
"humidity": 77.00,
"pressure": 1006.00
}
}
}
Kind regards,
Viktor
They are gone because they're supposed to be gone. That isn't from the parser but the serializer.
JSON has just a simple "number" type for numeric values. On decoding these become Double (or optionally Decimal). Don't be confused about the text representation once re-encoded back to JSON. JSONBag serializes numeric values back to a compact form, desirable to keep transmission costs down.
Nothing in the JSON spec requires retaining the original formatting of a value within the parsed JSON text. Even if it did, there are no rules to tell you how to format the value if changed or a new value is added, etc. JSON makes no provision for formatting numeric values any particular way as long as they result in a legal JSON "number."
If you really, really wanted this for some odd reason you would have to add another property to each numeric JSONBag item for "format" though I have no idea how reliable the parser could be at deciding what "format string" to assign when values are parsed.
dilettante, thank you.
This parser is very very necessary thing for a modern format of settings storage.
dilettante:
FWIW:
Just ran your JSON 2.5 Firefox bookmarks.
Stuck in loop and had to use Ctrl-Alt_Delete to exit.
For further discussion see here:
http://www.vbforums.com/showthread.p...lete-Bookmarks
Sounds like you have found a bug. Can you provide sample data that reproduces the problem?
If you break execution in the IDE what line is it on?
dilettante:
Happy New Year. Decided to come off my break early so in response to your questions:
Running your Demo2 from Version 2.5, with my bookmarks.json file.Quote:
If you break execution in the IDE what line is it on?
Everytime I break it end up in Form1:Proc: "DumpText"
At break bookmarks.json values are valid as I search bookmarks file to verify.
Just seems to repeat -- stuck in loop.
This is a tough one as using a copy of my actual bookmarks file.Quote:
Can you provide sample data that reproduces the problem?
See what I can do.
You can try make regexp-replacements of personal data.
As soon as this line of code finishes:
... the parsing is done. So the problem is probably not in JsonBag at all.Code:JB.JSON = JsonData
The rest of that program (mainly JbDump) just tries to walk the JsonBag tree and dump everything.
After that it queries a couple of items and displays than in MsgBox dialogs, but you probably deleted that part since it was specific to the original sample JSON document.
If JbDump has a problem I don't see it. Did you alter it? When you break try View|Call Stack... to walk back and find out where DumpText was called from. What are the values of Name, Level, JB.Count, and ItemIndex?
Without a sample file that produces this problem there isn't a lot we can do remotely.
Dragokas:
Have never worked with regexp so a non-starter.Quote:
You can try make regexp-replacements of personal data.
Was looking at a possible Search / Replace but Not sure amount effort involved.
I would think any Firefox bookmark file would give the same problems as IMHO it is more in their JSON format than in my data.
dilettante
Give me a couple days to see what I can come up with.
If my data agree, if Firefox bookmark format is issue then any Firefox JSON bookmark file should give same error. Firefox appears to use arrays of objects (children) which may be nested fairly deep.Quote:
Without a sample file that produces this problem there isn't a lot we can do remotely.
Quick Followup:
No, other than to substitute path to bookmarks.json which I copied to same directory as the program.Quote:
Did you alter it?
Did three different breaks and followed Call Stack each time to JbDumpQuote:
When you break try View|Call Stack... to walk back and find out where DumpText was called from. What are the values of Name, Level, JB.Count, and ItemIndex?
Checked the values for the variables suggested at each break.
All variables at EACH break had different values, but values look good -- from my bookmarks.json file.
=================
When I run Demo2 using the bookmarks.json file the left side "RTB" is stable and appears to show the bookmarks.json file (source) correctly from a cursory review. the right side "RTB" is the one that scrolls continuously as if stuck in a loop.
==================
After the 3 breaks ran again until appeared locked.
Quote:
IGNORE THE FOLLOWING - POSTED IN ERROR because:
Since I broke on JbTest I would expect JbDump to have "Subscript out of Range" errors
and other variables to be questionable
==================================================
In checking JbDump the key issue appears to be "Subscript out of Range"
The other variables had values of:Code:<< This following line and any other line with JB.Item(ItemIndex)
<< in JbDump shows as "Subscript out of Range"
If TypeOf JB.Item(ItemIndex) Is JsonBag Then
Name = ""
ItemIndex = 0
JB.Count = 8
What if you add two lines to remove the overhead of the control's UI updating?
Code:Set JB = New JsonBag
JB.JSON = JsonData
Show
txtJsonBagDump.Visible = False
JbDump "*anonymous outer JsonBag*", JB
txtJsonBagDump.Visible = True
HomeDump
Thanks for the code and suggestion.
Sadly, let run for 10 minutes and no output in Right Textbox.
This weekend will try and debug and see if I can pinpoint where hangup is occurring.
FWIW: Dumped just the first few lines of the file and grouped them (blank lines between groups)
to get some idea of the format.
Lot of embedding.
Hi, Wonder if anyone can help.
I am using jsonbag and works very well. However, i send a query to a website and expect to get a list of stuff back.
This all works good. However if i send an incorrect code i get a json respone that gives me
P.Item("name") = "Not Found"
If when i check P.Item("name") = "Not Found" everything works and i exit the sub , but when i send a valid query and
everything is ok i get P.Item(Row).Item("xxxxxxx")
How do i check the error raised when P.Item("name") is not even returned.
I am using VB6 and get Runtime error 5 . invalid call or procedure.
i have tried checking Not IsNull(P.Item("name")) and some other variations but the only way i can
see is to use Goto err handler which i did not want to do.
Is there a way to catch this error of an item not being avail.
many thanks
Try turning the circled option on in the IDE:
Attachment 155289
Nice Library. Has anyone used it to serialize a recordset? Any examples?
thanks
Nice Library. Has anyone used it to serialize a recordset? Any examples?
thanks
The problem with this is that something like an ADO Recordset is incredibly far richer than JSON.
JSON is so feature poor it is hard to know where to begin. Just look at data types:
JSON only has one numeric type: "number." That's instead of bytes, 16-bit and 32-bit integers, single-precision and double precision floating point, and more. JSON has no byte array. JSON has no date and time types. The list just goes on and on and on. Most of the culprit here is the incredibly type-poor JavaScript that JSON is based upon.
JSON lacks all kinds of metadata. For example a Recordset tracks whether a row has been modified, which is important when marshalling data back to a server for updating so you can send only the modified rows back... and if you send it all back the server can see which rows are to be updated to the underlying datastore at its end. The Fields within a Recordset also carry lots of metadata like the data type, ActualSize and DefinedSize, NumericScale, Precision, the Value and OriginalValue and UnderlyingValue, and more.
If you really want to serialize ADO Recordsets you may be far better off using one of the two formats it supports natively: ADO's own XML format or its ADTG binary format (far more compact).
Now, if you must have JSON and your needs are really meager you can cobble something up. However it is hard to imagine any generic way of doing this for all Recordsets. You must make massive compromises and those must be chosen for every use case.
Nothing says you can't invent some sort of JSON schema for doing this, much as ADO has its XML schema for representing Recordsets. i haven't seen anyone even attempt it yet though. There just isn't enough demand.
I suspect most people dealing with JSON are also dealing with servers that can't handle a Recordset anyway. So in that case they just use some ad hoc JSON schema that implements some tiny fraction of the metadata, if any at all, and live with the data type limitations.
But in that case there just isn't much to it. Any example would have to imply so many assumptions about the specific application as to be meaningless, probably useless for any other application.
hi. looking to used JsonBag and did an initial test to check the existence of keys.
how can i do the following as below raises an error
i know JB.Exists("sample") works fine, but checking for a 2nd key ie JB.Exists("fudge") does notCode:If JB.Exists("sample").Item("fudge") = True Then
Debug.Print JB.Item("sample").Item("fudge")
End If
thanks
Hello,
Look, I think there is a bug in the Exists method of the last version, copy this code and replace the Exists procedure:
About how to use it in chain:Code:Public Function Exists(ByVal Key As Variant) As Boolean
Dim Name As String
If VarType(Key) = vbString Then
On Error Resume Next
Name = Names.Item(PrefixHash(Key))
Else
On Error Resume Next
Name = Names.Item(Key)
End If
Exists = Err.Number = 0
Err.Clear
End Function
The word .Item is optional. (whether you put it or not it works anyway)Code:If JB.Exists("sample") Then
If JB("sample").Exists("fudge") Then
Debug.Print JB.Item("sample").Item("fudge")
' Or
Debug.Print JB("sample")("fudge")
End If
End If
thanks Eduardo. If JB("sample").Exists("fudge") Then was what i needed. Did not change the Exists though. left it as is and works fine
Code:Public Function Exists(ByVal Key As Variant) As Boolean
Dim Hash As Long
Dim PrefixedKey As String
Dim Name As String
If VarType(Key) = vbString Then
HashData StrPtr(Key), Len(Key) * 2, VarPtr(Hash), 4
PrefixedKey = Right$("0000000" & Hex$(Hash), 8) & Key
On Error Resume Next
Name = Names.Item(PrefixedKey)
Else
On Error Resume Next
Name = Names.Item(Key)
End If
Exists = Err.Number = 0
Err.Clear
End Function
I am looking to load json data to a treeview but don't know how.
can anyone help or give small example to help
many thanks.
I'm not sure how useful something like that is.
Normally you don't expose JSON to users any more than they should be looking at XML, INI, or any other persistence format. These are meant to store things like program settings that seldom change, descriptions of things like user interface layouts, or as data interchange formats.
If you really want this for some weird reason though it seems simple enough, for example:
Attachment 166223
Here I used different icon images to illustrate whether a node contains an "Object," "Array," "Property," or "Element." Blue for parent nodes and red for leaf nodes.
thanks dilettante, that's just what i was looking for. i am trying to make a little app to help me create code that gets the json from web data.
usually i go through the json picking what i want and some times its hard to get the right combination
ie p.item("root").item("blah").item("bitmore")
then sometimes i create a for next to load in arrays of data and type this all manually.
With this i can create a rightclick on a node and poss create the path and bits of code i need to paste into my own apps
saves me typing and trial and error to get the right path.
again , many thanks
Don't suppose you would have any example of syntax highlighting json similar to this
Attachment 166227
again, thanks