Werte und Grenzen
Wie WKL Office JSON JSON-Werte in VBA-Werte umwandelt und zurück, und wo die Bibliothek an Grenzen stößt. JSON
(RFC 8259) kennt Zeichenfolgen, Zahlen, true/false, null, Objekte und
Arrays; VBA kennt typisierte Variant-Werte. Hier ist jeder Übergang zwischen beiden aufgeführt, zusammen mit dem, was
dabei verloren geht, und dem, was abgelehnt wird. Die Seiten der Member in der
API-Referenz (Englisch) verweisen auf diese Seite.
Von JSON nach VBA
| JSON | Value (natürlicher Typ) | Typisierte Get-Methoden |
|---|---|---|
| Zeichenfolge | String, unverändert | GetString unverändert; GetDate liest ISO 8601 (siehe Datumswerte); GetBoolean liest „true“/„false“ (Groß- und Kleinschreibung beliebig, umgebende Leerzeichen erlaubt); GetLong und die anderen Get-Methoden für Zahlen lesen den Text als Zahl |
Zahl ohne Nachkommastellen oder Exponent, im Long-Bereich | Long | jede Get-Methode für Zahlen; GetString gibt den Text so zurück, wie er geschrieben ist |
Zahl ohne Nachkommastellen oder Exponent, außerhalb des Long-Bereichs | Decimal | GetDecimal |
| Zahl mit Nachkommastellen oder Exponent | Double | GetDecimal, GetCurrency für exakte Werte (siehe Zahlen) |
true / false | Boolean | GetBoolean; GetString gibt „true“/„false“ zurück |
null | Null | eine Get-Methode ohne Ersatzwert löst einen Fehler aus, eine Get-Methode mit Ersatzwert gibt den Ersatzwert zurück; StringValue gibt eine leere Zeichenfolge zurück |
| Objekt, Array | kein Wert: Value löst jeInvalidOperation aus | GetString / StringValue geben kompakten JSON-Text zurück |
Der Ersatzwert einer typisierten Get-Methode wird nach den Umwandlungsregeln von VBA (VariantChangeType) in den Typ
der Get-Methode umgewandelt; ein Ersatzwert, der sich nicht umwandeln lässt (zum Beispiel GetLong(path, "abc")), löst
jeTypeMismatch aus. GetValue gibt seinen Ersatzwert unverändert zurück.
Typisierte Get-Methoden: angenommen, verlustbehaftet, abgelehnt
| Get-Methode | Nimmt an | Verlustbehaftet, ohne Fehler | Abgelehnt mit jeTypeMismatch |
|---|---|---|---|
GetLong | Zahlen und Zahlen-Zeichenfolgen mit ganzzahligem Wert (12.0, 1e3) | – | Nachkommastellen; ein Wert außerhalb von −2.147.483.648 bis 2.147.483.647 |
GetDouble | Zahlen, Zahlen-Zeichenfolgen | auf den nächstgelegenen Double gerundet (15 bis 17 signifikante Stellen: 9007199254740993 wird als 9007199254740992 gelesen); Zahlen mit einem Betrag unter etwa 5E-324 werden zu 0 | ein Wert jenseits von ±1,8E308 (1e400) |
GetCurrency | Zahlen, Zahlen-Zeichenfolgen | auf vier Nachkommastellen gerundet, bei ,5 zur geraden Ziffer (wie CCur); Zahlen mit einem Betrag unter 1E-28 werden zu 0 | ein Wert außerhalb von ±922.337.203.685.477,5807 |
GetDecimal | Zahlen, Zahlen-Zeichenfolgen | auf 28 bis 29 signifikante Stellen gerundet; Zahlen mit einem Betrag unter 1E-28 werden zu 0 | ein Wert jenseits von ±79.228.162.514.264.337.593.543.950.335 |
GetDate | Zeichenfolgen nach ISO 8601 (siehe Datumswerte) | Nachkommastellen der Sekunde nach der siebten werden ignoriert | Zahlen (auch Unix-Zeitstempel), andere Zeichenfolgen, Datumswerte vor dem Jahr 100 |
GetBoolean | true/false; die Zeichenfolgen „true“/„false“ (Groß- und Kleinschreibung beliebig, umgebende Leerzeichen erlaubt); Zahlen | – | andere Zeichenfolgen, Objekte, Arrays |
GetString | jeden Wert; Objekte und Arrays als kompakten JSON-Text | – | – |
Eine Zeichenfolge wird nur dann als Zahl gelesen, wenn ihr Text ohne umgebende Leerzeichen eine JSON-Zahl ist: "42"
und " 4.2 " werden gelesen; "007", "+5", ".5", "12,5" und "1 000" lösen jeTypeMismatch aus – lesen Sie
solche Codes mit GetString. Für GetBoolean ist eine Zahl False, wenn sie nach der Umwandlung in Decimal 0 ist;
das schließt Zahlen unter 1E-28 wie 1e-30 ein (anders als bei CBool), und jede andere Zahl, auch eine jenseits des
Decimal-Bereichs, ist True.
Von VBA nach JSON
Was SetValue, Add, Insert und CreateValue annehmen (Value = … eines Werteknotens nimmt nur die Werte dieser
Tabelle ohne Kindknoten oder einen JValue an; ein Knoten mit Kindknoten, ein Array oder ein JDoc mit einem Objekt
oder Array als Wurzel lösen dort jeInvalidOperation aus, und Value = … auf einem Objekt oder Array löst immer
jeInvalidOperation aus):
| VBA-Wert | JSON |
|---|---|
String | Zeichenfolge |
Byte, Integer, Long, LongLong | Zahl |
Single | Zahl, geschrieben im kürzesten Text des Single (aus 0.1! wird 0.1); NaN und Unendlich lösen jeUnsupportedValue aus |
Double | Zahl; NaN und Unendlich haben keine JSON-Form und lösen jeUnsupportedValue aus |
Currency | Zahl, exakt, ohne nachgestellte Nullen (CCur(12.50) wird als 12.5 geschrieben) |
Decimal | Zahl, exakt, mit ihrer Anzahl an Nachkommastellen (CDec("12.50") wird als 12.50 geschrieben) |
Boolean | true / false |
Date | Zeichenfolge nach ISO 8601 (siehe Datumswerte) |
Empty, Null, Nothing | null |
ein Knoten (JNode, JElement, JArray, JValue) | der Knoten; ein Knoten eines anderen Dokuments wird kopiert |
ein JDoc | eine Kopie seiner Wurzel; ein leeres JDoc ergibt null |
| ein eindimensionales Array | Array, Element für Element nach diesen Regeln; ein Byte()-Array wird zu einem Array aus Zahlen (nicht Base64), ein Array ohne Dimensionen wird zu [] |
ein Array mit mehr Dimensionen (zum Beispiel aus GetRows), jedes andere Objekt, Error, ein fehlendes optionales Argument | abgelehnt mit jeUnsupportedValue |
Zahlen
Eine Zahl behält den Text, mit dem sie gelesen wurde; Json, Save und GetString schreiben diesen Text unverändert,
auch 0.10, 1E3 oder eine Zahl mit 40 Ziffern. Nur die Umwandlung in einen VBA-Typ kann runden oder fehlschlagen:
GetDecimalundGetCurrencywandeln den Text direkt um, nicht überDouble;0.1 + 0.2bleibt daher exakt.Decimalfasst 28 bis 29 signifikante Stellen: Eine Zahl mit mehr Stellen wird ohne Fehler auf diese Genauigkeit gerundet, und eine Zahl, deren Betrag unter 1E-28 liegt (zum Beispiel1e-30), wird ohne Fehler zu 0; lesen Sie solche Werte mitGetDouble.Currencyrundet auf vier Nachkommastellen.Valuegibt für ganze ZahlenLongoderDecimalzurück; eine ganze Zahl jenseits desDecimal-Bereichs (etwa 7,9 × 10^28) wird alsDoublezurückgegeben, mit der Genauigkeit einesDouble.- Eine Zahl jenseits des
Double-Bereichs (1e400) ist gültiges JSON; sie mitValueoderGetDoublezu lesen, löstjeTypeMismatchaus;GetStringgibt ihren Text zurück.
Datumswerte
JSON kennt keinen Datumstyp; Datumswerte werden als Zeichenfolgen übertragen.
Lesen (GetDate, DateValue) nimmt die Formen an, die Webdienste senden (Profil von ISO 8601 nach
RFC 3339): 2026-09-25, 2026-09-25T14:30, 2026-09-25T14:30:15,
Sekundenbruchteile mit Punkt oder Komma (bis zu sieben Ziffern werden gelesen, weitere ignoriert), jeweils wahlweise
gefolgt von Z, +02:00, +0200 oder +02. Ein Leerzeichen statt T wird akzeptiert. Abgelehnt werden
Wochen- und Ordinaldaten, Zeitdauern, die Sekunde 60, 24:00 sowie ein Datum ohne Uhrzeit, das eine Zone trägt. Ein
Datum vor dem Jahr 100, dem ersten Datum, das VBA kennt, löst jeTypeMismatch aus. DateZone des Dokuments legt fest,
was aus einem Zeitstempel mit Zone wird: in Ortszeit umgerechnet (Standard), in UTC umgerechnet oder so, wie er
geschrieben ist (siehe Datums- und Uhrzeitwerte lesen und schreiben). Für die
Ortszeit gelten die Zeitzonenregeln, die Windows für das jeweilige Datum hat.
Schreiben ergibt yyyy-MM-dd für ein Datum um Mitternacht, sonst yyyy-MM-ddTHH:mm:ss, mit .fff, wenn der Wert
Millisekunden hat, immer ohne Zone. Eine VBA-Uhrzeit ohne Datum (#14:30#) wird mit dem Basisdatum von VBA
geschrieben: 1899-12-30T14:30:00.
Dokumente
| Gegenstand | Verhalten |
|---|---|
| Syntax | Strikt nach RFC 8259: Kommentare, Kommas nach dem letzten Eintrag, einfache Anführungszeichen, NaN und führende Nullen sind Fehler mit Zeile und Spalte |
| Verschachtelung | höchstens 512 Ebenen; bei tieferer Verschachtelung geben LoadJson/Load False zurück, mit ParseError.ErrorCode = jeParseError. Ab 2.1.0 gilt die Grenze auch für Dokumente, die per Code aufgebaut werden, und für VBA-Arrays von Arrays: Einfügen über diese Grenze hinaus löst jeInvalidOperation aus |
| Doppelte Schlüssel | erlaubt; der letzte Wert gilt, der Schlüssel behält die Position seines ersten Vorkommens |
| Größe | ab 2.1.0 höchstens MaxInputSize Byte (Vorgabe 256 MB, 0 = unbegrenzt): Bei einer größeren Eingabe geben LoadJson/Load False zurück, mit ParseError.ErrorCode = jeTooLarge; eine größere Datei liest Load gar nicht erst. LoadJson misst den Text in UTF-8-Byte. Ohne Grenze entscheidet der Arbeitsspeicher |
| Unicode | beliebiger Text; ein einzelnes Surrogat (\ud800) wird gelesen und wieder als \u-Escape-Sequenz geschrieben |
Load | UTF-8 ohne Bytereihenfolge-Marke oder UTF-8, UTF-16 oder UTF-32 mit Bytereihenfolge-Marke. Ohne Bytereihenfolge-Marke führt ungültiges UTF-8 dazu, dass Load False zurückgibt, mit ParseError.ErrorCode = jeFileError; mit Bytereihenfolge-Marke werden ungültige Bytes durch U+FFFD ersetzt, und Load ist erfolgreich |
Save | UTF-8 ohne Bytereihenfolge-Marke |
DateZone | ein Wert außerhalb der Enumeration löst jeInvalidOperation aus |
JPath
JPath setzt Syntax und Semantik von RFC 9535 (JSONPath) um. Die Abweichungen:
- Erweiterungen. Ein Pfad ohne
$beginnt am aktuellen Knoten (auf oberster Ebene auch@);-ist in Kurznamen erlaubt ($.first-name); Leerraum um den gesamten Ausdruck wird ignoriert; ein regulärer Ausdruck bricht nach einer Sekunde ab und ergibt dannfalse. - Angenommen, obwohl RFC 9535 einen Fehler verlangt. Funktionsausdrücke, die nicht korrekt typisiert sind (
$[?length(@.*) < 3],$[?length(@.a)],$[?match(@.a,'x') == true]),!unmittelbar vor einem Vergleich,\'in einer Zeichenfolge in doppelten Anführungszeichen, die Indizes-0und01sowie Indizes jenseits von ±(2^53−1). - Abweichende Ergebnisse. Zeichenfolgen werden nach UTF-16-Codeeinheiten geordnet, nicht nach Unicode-Skalarwerten (das macht nur zwischen Zeichen im Bereich U+E000–U+FFFF und Zeichen oberhalb von U+FFFF einen Unterschied). Zahlen werden als
Decimalverglichen: Zahlen unter 1E-28 sind gleich 0, und Zahlen, die sich erst nach der 28. signifikanten Stelle unterscheiden, sind gleich. Eine Funktion vom TypValueType, die als Test verwendet wird, ist für den Wertfalsefalsch. - Reguläre Ausdrücke.
matchundsearchverwenden reguläre Ausdrücke von .NET statt I-Regexp (RFC 9485):.passt auf genau eine UTF-16-Codeeinheit (ein Emoji braucht zwei) und auch auf CR;\d,\w,\s, Rückverweise und Lookaround werden akzeptiert. Ein ungültiges Muster ergibtfalse, wie es RFC 9535, Abschnitt 2.4.6, verlangt. Ab 2.1.0 läuft ein Muster ohne Rückverweise und Lookaround auf einer Engine, deren Laufzeit nur linear mit dem Text wächst; ein Muster mit diesen Konstrukten läuft wie bisher mit dem Zeitlimit von einer Sekunde. - Verschachtelte Ausdrücke. Ab 2.1.0 ergibt ein Ausdruck mit mehr als 256 Ebenen aus Klammern, Negationen, Funktionsargumenten und Filtern in Filtern (ein Filter in einem Filter zählt doppelt) den Fehler
jePathSyntax. - Pfade.
Patheines Knotens gibt den Ausdruck dieser Bibliothek zurück, in Punktschreibweise, wo ein Name sie zulässt, sonst als['name']($.lines[2].no,$['first name']) – nicht die Klammerform eines Normalized Path (RFC 9535, Abschnitt 2.7).
Kompilierte Ausdrücke werden in einem Cache mit 512 Einträgen gehalten.
Threadmodell und Versionen
Die Objekte sind COM-Objekte des Apartment-Modells: Erzeugen und verwenden Sie sie in einem einzigen Thread, wie es VBA tut; für andere Hosts sind sie nicht threadsicher.
Unterstützte Konfiguration: Microsoft 365 Access 16.0 in 32 und 64 Bit (ACCDB, ACCDE und Access Runtime) unter Windows 11. Andere Access-Versionen (2016, 2019, 2021, LTSC) und andere Windows-Versionen werden in diesem Release nicht unterstützt.
Standards
| Quelle | Verwendet für | Abweichung |
|---|---|---|
| RFC 8259, JSON (Internet Standard, 2017) | Syntax, die LoadJson/Load annehmen und Json/Save schreiben | Doppelte Namen: Die RFC lässt das Verhalten offen (Namen SOLLTEN eindeutig sein); hier gilt der letzte Wert |
| RFC 9535, JSONPath (Proposed Standard, 2024) | JPath-Ausdrücke | Erweiterungen, tolerante Annahme, Ordnung von Zeichenfolgen, Vergleich von Zahlen, reguläre Ausdrücke und Path: siehe JPath |
| RFC 9485, I-Regexp (Proposed Standard, 2023) | Die Variante regulärer Ausdrücke, die RFC 9535 vorschreibt | nicht umgesetzt (siehe oben) |
| RFC 3339, Datum und Uhrzeit (2002), Abschnitt 5.6 | Zeitstempel, die GetDate liest | zusätzlich angenommen: ein Leerzeichen statt T, die Zonenangaben +0200/+02, ein Komma als Trennzeichen der Sekundenbruchteile |
| MSXML `loadXML`) | Vorbild für LoadJson: gibt bei ungültigem Text False zurück, die Ursache steht in ParseError | keine |