Lies in den Artikel rein und unten bekommst Du ein unschlagbares Angebot!
Der Umgang mit JSON-Dokumenten wir immer wichtiger, da immer mehr Rest-APIs dieses Format nutzen, um Daten auszutauschen. In einem weiteren Artikel namens Mit JSON arbeiten (www.vbentwickler.de/361) haben wir bereits gezeigt, wie wir JSON-Dokumente möglichst einfach per VBA lesen können. Das ist schon die halbe Miete, aber die Kommunikation mit Rest-APIs ist keine Einbahnstraße: Wir müssen auch immer wieder mal Daten im JSON-Format an eine Rest-API senden. Wir nutzen dazu wiederum die Bibliothek von Tim Hall, die uns eine Funktion namens ConvertToJSON zur Verfügung stellt. Dieser müssen wir nun nur noch die Daten in einem entsprechenden Format übergeben. Wie das gelingt, zeigen wir im vorliegenden Artikel.
Im Artikel Google Calendar per Rest-API programmieren (www.vbentwickler.de/410) hatten wir die Aufgabe, ein JSON-Dokument mit den Daten eines in Google Calendar anzulegenden Ereignisses zu erstellen. Das kann man auf die klassische Art machen, indem man dieses einfach zeilenweise als String in einer Variablen erfasst.
Dafür brauchen wir, wie in Listing 1 zu sehen, keine weiteren Hilfsmittel – der JSON-Ausdruck wird anschließend beispielsweise per Debug.Print wie folgt ausgegeben und kann so auch an die Rest-API geschickt werden:
Public Sub JSONPerString() Dim strJSON As String strJSON = "{" & vbCrLf strJSON = strJSON & " ""start"": {" & vbCrLf strJSON = strJSON & " ""dateTime"": ""2023-11-22T17:00:00""," & vbCrLf strJSON = strJSON & " ""timeZone"": ""Europe/Berlin""" & vbCrLf strJSON = strJSON & " }," & vbCrLf strJSON = strJSON & " ""end"": {" & vbCrLf strJSON = strJSON & " ""dateTime"": ""2023-11-22T18:30:00""," & vbCrLf strJSON = strJSON & " ""timeZone"": ""Europe/Berlin""" & vbCrLf strJSON = strJSON & " }," & vbCrLf strJSON = strJSON & " ""summary"":""Summary""," & vbCrLf strJSON = strJSON & " ""description"":""description""" & vbCrLf strJSON = strJSON & "}" & vbCrLf Debug.Print strJSON End Sub
Listing 1: Beispiel für das Erfassen eines JSON-Dokuments per String-Variable
{ "start": { "dateTime": "2023-11-22T17:00:00", "timeZone": "Europe/Berlin" }, "end": { "dateTime": "2023-11-22T18:30:00", "timeZone": "Europe/Berlin" }, "summary":"Summary", "description":"description" }
Das Problem ist nur: Wenn wir diese Zeilen zusammenstellen wollen, ist das ein erheblicher Aufwand.
Schauen wir uns die folgende Zeile des zu erzeugenden JSON-Dokuments an und gehen wir davon aus, dass wir das Dokument in VBA basierend auf einer Vorlage zusammenstellen wollen:
"dateTime": "2023-11-22T17:00:00",
Dann müssen wir zuerst am Anfang der Zeile strJSON = strJSON & ” voranstellen, hinten ein ” & vbCrLf anfügen und schließlich noch alle enthaltenen Anführungszeichen verdoppeln, damit diese auch als Anführungszeichen innerhalb des Variableninhalts interpretiert werden und nicht als das Ende der Zeichenkette:
strJSON = strJSON & " ""dateTime"": ""2023-11-22T17:00:00""," & vbCrLf
Das ist nicht nur sehr aufwendig, wenn man es von Hand macht, sondern auch noch extrem fehleranfällig.
Stellen wir uns dann vor, wir wollten zwischendrin eine Zeile entfernen – beispielsweise die Zeile mit dem Wert für das Feld description:
strJSON = strJSON & " ""summary"":""Summary""," & vbCrLf strJSON = strJSON & " ""description"":""description""" & vbCrLf strJSON = strJSON & "}" & vbCrLf
Dann müssen wir hier nicht nur die Zeile entfernen, sondern auch in der vorherigen Zeile das Komma, denn sonst wäre das JSON-Dokument fehlerhaft.
Vereinfachung dank JSON-Bibliothek
Hier kommt die Bibliothek beziehungsweise das Modul von Tim Hall ins Spiel, die wir zum Beispiel hier herunterladen können:
https://github.com/VBA-tools/VBA-JSON/blob/master/JsonConverter.bas
Diese bietet einige nützliche Funktionen. Eine davon, ParseJSON, haben wir bereits in dem oben genannten Artikel verwendet, um aus einem JSON-Dokument ein Objekt zu generieren, das alle Elemente des JSON-Dokuments in strukturierter Form als Dictionaries und Collections enthält.
In diesem Artikel zeigen wir auch unsere eigene Erweiterung, mit der wir noch den Code ausgeben, den wir für den Zugriff auf die Elemente verwenden können. Auf die Elemente des obigen, zugegebenermaßen einfach aufgebauten JSON-Dokuments, greifen wir damit wie folgt zu:
objJSON.Item("start").Item("dateTime") objJSON.Item("start").Item("timeZone") objJSON.Item("end").Item("dateTime") objJSON.Item("end").Item("timeZone") objJSON.Item("summary") objJSON.Item("description")
Wie aber können wir nun den umgekehrten Weg gehen – also den, ein JSON-Dokument über Dictionary– und Collection-Elemente zusammenzustellen und daraus dann mit der Funktion ConvertToJSON ein JSON-Dokument im String-Format abzuleiten? Dies schauen wir uns anhand einiger Beispiele an.
Objekte erstellen
Die wichtigste Information vorab:
- Eckige Klammern deuten immer auf die Auflistung von Elementen hin, diese landen in einem Collection-Objekt.
- Geschweifte Klammern weisen auf ein oder mehrere Name-Wert-Paare hin, diese landen in einem Dictionary-Objekt.
Einfachstes Beispiel: Ein Name-Wert-Paar
Im ersten Beispiel wollen wir dieses Dokument erzeugen:
{ "Vorname":"Andre" }
Dazu brauchen wir noch verhältnismäßig viel Code: