{"id":55000502,"date":"2026-04-01T00:00:00","date_gmt":"2026-05-16T17:40:44","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=502"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"RestAPIs_mit_VBA_programmieren","status":"publish","type":"post","link":"https:\/\/vbentwickler.de\/RestAPIs_mit_VBA_programmieren\/","title":{"rendered":"Rest-APIs mit VBA programmieren"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg08.met.vgwort.de\/na\/c4168f955ebb478f988815f6e3c6aa93\" width=\"1\" height=\"1\" alt=\"\"><b>Wer mit VBA arbeitet, kommt heute kaum noch daran vorbei: Fast jeder interessante Online-Dienst &#8211; von Wetter- und Geo-Daten &uuml;ber Projektmanagement-Tools bis hin zu KI-Diensten &#8211; bietet eine Rest-API an. Dabei ist das Prinzip immer dasselbe: Du schickst eine HTTP-Anfrage an eine bestimmte URL, und der Dienst antwortet mit strukturierten Daten &#8211; in der Regel im JSON-Format. Ob Du Kundenadressen mit einem CRM abgleichen, Versandetiketten bei DHL anfordern, Aufgaben in Trello anlegen oder Texte mit DeepL &uuml;bersetzen willst &#8211; hinter all diesen Integrationen steckt dieselbe Technik. VBA bringt daf&uuml;r alle n&ouml;tigen Werkzeuge von Haus aus mit: Ein einziger Verweis auf eine Windows-Systembibliothek gen&uuml;gt, um HTTP-Anfragen abzusetzen und die Antworten auszuwerten. Dieser Artikel erkl&auml;rt, was eine Rest-API &uuml;berhaupt ist, welche Grundbegriffe Du kennen musst, um jede beliebige API-Dokumentation selbstst&auml;ndig zu lesen, und wie Du eine wiederverwendbare Funktion baust, die Du als solide Basis f&uuml;r jeden weiteren API-Aufruf einsetzen kannst.<\/b><\/p>\n<h2>Was ist eine Rest-API?<\/h2>\n<p><b>REST<\/b> steht f&uuml;r Representational State Transfer und bezeichnet einen Architekturstil f&uuml;r verteilte Systeme, der auf dem HTTP-Protokoll basiert. Eine Rest-API (Application Programming Interface) stellt Ressourcen &#8211; zum Beispiel Kundendatens&auml;tze, Wetterdaten oder Projektaufgaben &#8211; &uuml;ber eindeutige URLs bereit. Der Zugriff darauf erfolgt mit den bekannten HTTP-Methoden:<\/p>\n<ul>\n<li><b>GET<\/b>: Liest eine Ressource, ohne sie zu ver&auml;ndern.<\/li>\n<li><b>POST<\/b>: Legt eine neue Ressource an.<\/li>\n<li><b>PUT<\/b>: Ersetzt eine vorhandene Ressource vollst&auml;ndig.<\/li>\n<li><b>PATCH<\/b>: Aktualisiert einzelne Felder einer Ressource.<\/li>\n<li><b>DELETE<\/b>: L&ouml;scht eine Ressource.<\/li>\n<\/ul>\n<p>Im Unterschied zu &auml;lteren SOAP-Webservices &#8211; die einen aufwendigen XML-Umschlag ben&ouml;tigen &#8211; verwendet <b>REST<\/b> meist das leichtgewichtige JSON-Format f&uuml;r Anfragen und Antworten. Das macht Rest-APIs deutlich einfacher konsumierbar.<\/p>\n<h2>Aufbau einer Rest-API-URL<\/h2>\n<p>Jede Rest-API-URL besteht aus mehreren Teilen, die wir kennen m&uuml;ssen, bevor wir den ersten VBA-Aufruf absetzen. Nehmen wir als Beispiel eine fiktive Aufgaben-API:<\/p>\n<pre>https:\/\/api.beispiel.de\/v1\/aufgaben?status=offen&limit=10<\/pre>\n<p>Der erste Teil, <b>https:\/\/api.beispiel.de<\/b>, ist die Basis-URL des Dienstes. Das Segment <b>\/v1\/<\/b> bezeichnet die API-Version &#8211; viele Anbieter versionieren ihre API, damit bestehender Code nicht bricht, wenn neue Funktionen hinzukommen. Der Pfad <b>\/aufgaben<\/b> benennt die Ressource. Ab dem Fragezeichen folgen optionale URL-Parameter (auch &#8220;Query-String&#8221; genannt), die mit dem <b>&#038;<\/b>-Zeichen voneinander getrennt werden.<\/p>\n<p>Manche APIs erg&auml;nzen die URL um eine Ressourcen-ID, wenn ein einzelner Datensatz angesprochen wird:<\/p>\n<pre>https:\/\/api.beispiel.de\/v1\/aufgaben\/42<\/pre>\n<p>Das Prinzip ist immer gleich &#8211; und genau das macht Rest-APIs so gut erlernbar.<\/p>\n<h2>HTTP-Header<\/h2>\n<p>Neben der URL tr&auml;gt jede HTTP-Anfrage einen Satz von Headern, also Name-Wert-Paaren, die Metainformationen &uuml;ber den Aufruf &uuml;bermitteln. Die h&auml;ufigsten Header, die wir in VBA selbst setzen, sind:<\/p>\n<ul>\n<li><b>Content-Type<\/b>: Gibt an, in welchem Format wir Daten senden &#8211; in der Regel <b>application\/json<\/b>.<\/li>\n<li><b>Accept<\/b>: Teilt dem Server mit, welches Antwortformat wir erwarten &#8211; ebenfalls meist <b>application\/json<\/b>.<\/li>\n<li><b>Authorization<\/b>: Enth&auml;lt das Authentifizierungs-Token oder den API-Key, mit dem wir uns beim Dienst ausweisen.<\/li>\n<\/ul>\n<p>Wie genau das Authentifizierungs-Token aussieht und wie man es beschafft, ist von Dienst zu Dienst unterschiedlich und Gegenstand eigener Artikel.<\/p>\n<h2>HTTP-Statuscodes<\/h2>\n<p>Die Antwort des Servers enth&auml;lt immer einen dreistelligen Statuscode, der uns sofort sagt, ob der Aufruf erfolgreich war.<\/p>\n<p>Folgende Auflistung zeigt die wichtigsten Codes im &Uuml;berblick:<\/p>\n<ul>\n<li><b>200 &#8211; OK<\/b>: Der Aufruf war erfolgreich. Die Antwort enth&auml;lt die angeforderten Daten.<\/li>\n<li><b>201 &#8211; Created<\/b>: Eine neue Ressource wurde erfolgreich angelegt (typisch bei <b>POST<\/b>).<\/li>\n<li><b>204 &#8211; No Content<\/b>: Der Aufruf war erfolgreich, aber der Server liefert keinen Antwortbody (typisch bei <b>DELETE<\/b>).<\/li>\n<li><b>400 &#8211; Bad Request<\/b>: Die Anfrage ist fehlerhaft, zum Beispiel wegen eines ung&uuml;ltigen JSON-Dokuments.<\/li>\n<li><b>401 &#8211; Unauthorized<\/b>: Die Authentifizierung ist fehlgeschlagen. Token oder API-Key fehlt oder ist abgelaufen.<\/li>\n<li><b>403 &#8211; Forbidden<\/b>: Der Zugriff ist verweigert. Das Token ist g&uuml;ltig, aber die n&ouml;tigen Rechte fehlen.<\/li>\n<li><b>404 &#8211; Not Found<\/b>: Die angeforderte Ressource existiert unter dieser URL nicht.<\/li>\n<li><b>422 &#8211; Unprocessable Entity<\/b>: Die Anfrage ist syntaktisch korrekt, scheitert aber an der inhaltlichen Validierung (zum Beispiel Pflichtfeld fehlt).<\/li>\n<li><b>429 &#8211; Too Many Requests<\/b>: Das Anfrage-Limit (Rate Limit) des Dienstes wurde &uuml;berschritten.<\/li>\n<li><b>500 &#8211; Internal Server Error<\/b>: Auf dem Server ist ein unerwarteter Fehler aufgetreten.<\/li>\n<li><b>503 &#8211; Service Unavailable<\/b>: Der Dienst ist vor&uuml;bergehend nicht erreichbar, zum Beispiel wegen Wartungsarbeiten.<\/li>\n<\/ul>\n<p>Die Codes lassen sich grob in Gruppen einteilen: 2xx steht generell f&uuml;r Erfolg, <b>4xx<\/b> f&uuml;r einen Fehler auf der Client-Seite (zum Beispiel falscher API-Key oder ung&uuml;ltige URL) und <b>5xx<\/b> f&uuml;r einen Fehler auf der Server-Seite. Der Code <b>401<\/b> bedeutet &#8220;nicht autorisiert&#8221; und weist meist auf ein fehlendes oder abgelaufenes Token hin. <b>404<\/b> kennst Du vielleicht schon vom Surfen im Web und bedeutet hier, dass die angeforderte Ressource unter dieser URL nicht existiert.<\/p>\n<h2>Das XMLHTTP-Objekt in VBA<\/h2>\n<p>VBA bringt von Haus aus kein eigenes HTTP-Objekt mit. Wir greifen stattdessen auf die Bibliothek <b>Microsoft XML, v6.0<\/b> zur&uuml;ck, die Windows standardm&auml;&szlig;ig mitliefert. Diese enth&auml;lt das Objekt <b>MSXML2.XMLHTTP60<\/b>, das uns alle n&ouml;tigen Methoden und Eigenschaften f&uuml;r HTTP-Aufrufe bereitstellt.<\/p>\n<p>Alternativ steht <b>MSXML2.ServerXMLHTTP60<\/b> zur Verf&uuml;gung. Der Unterschied: <b>XMLHTTP60<\/b> nutzt die Proxy-Einstellungen des angemeldeten Windows-Benutzers, w&auml;hrend <b>ServerXMLHTTP60<\/b> eine eigene Verbindung ohne Benutzerkontext aufbaut und sich deshalb besser f&uuml;r serverseitige Szenarien oder Situationen eignet, in denen kein Benutzerprofil vorliegt.<\/p>\n<p>F&uuml;r typische Aufgaben am Entwickler-PC sind beide gleichwertig. In diesem Artikel verwenden wir <b>XMLHTTP60<\/b>.<\/p>\n<h2>Verweis hinzuf&uuml;gen<\/h2>\n<p>Damit wir das Objekt mit fr&uuml;her Bindung, also mit voller IntelliSense-Unterst&uuml;tzung, nutzen k&ouml;nnen, m&uuml;ssen wir dem VBA-Projekt einen Verweis auf die XML-Bibliothek hinzuf&uuml;gen.<\/p>\n<p>Dazu &ouml;ffnen wir im VBA-Editor den Dialog &uuml;ber den Befehl <b>Extras|Verweise<\/b> und aktivieren den Eintrag <b>Microsoft XML, v6.0<\/b> (siehe Bild 1).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2026_02\/pic_502_001.png\" alt=\"Den Verweis auf Microsoft XML, v6.0 im Verweise-Dialog aktivieren\" width=\"499,6267\" height=\"393,8742\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Den Verweis auf Microsoft XML, v6.0 im Verweise-Dialog aktivieren<\/span><\/b><\/p>\n<p>Ab sofort k&ouml;nnen wir Variablen als <b>MSXML2.XMLHTTP60<\/b> deklarieren und profitieren von der Typpr&uuml;fung beim Kompilieren.<\/p>\n<h2>Die Kernmethoden von XMLHTTP60<\/h2>\n<p>Das Objekt arbeitet nach einem festen Ablauf, den wir uns merken sollten:<\/p>\n<ul>\n<li><b>Open<\/b>: &Ouml;ffnet eine Verbindung und legt Methode, URL und Synchronit&auml;t fest.<\/li>\n<li><b>setRequestHeader<\/b>: Setzt einen einzelnen HTTP-Header.<\/li>\n<li><b>send<\/b>: Versendet die Anfrage &#8211; optional mit einem Body, zum Beispiel einem JSON-Dokument.<\/li>\n<li><b>status<\/b>: Eigenschaft, die nach dem Aufruf den HTTP-Statuscode enth&auml;lt.<\/li>\n<li><b>responseText<\/b>: Eigenschaft, die die Antwort des Servers als Text enth&auml;lt.<\/li>\n<\/ul>\n<p>Der dritte Parameter von <b>Open<\/b> legt fest, ob der Aufruf asynchron erfolgen soll.<\/p>\n<p>Wir &uuml;bergeben hier immer <b>False<\/b>, damit der Code solange wartet, bis die Antwort eingetroffen ist.<\/p>\n<h2>Eine wiederverwendbare HTTPRequest-Funktion<\/h2>\n<p>Anstatt in jedem Modul das <b>XMLHTTP60<\/b>-Objekt neu aufzubauen, lohnt es sich, eine zentrale Funktion anzulegen, die alle API-Aufrufe kapselt.<\/p>\n<p>Listing 1 zeigt diese Funktion namens <b>HTTPRequest<\/b>.<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>HTTPRequest(strURL<span style=\"color:blue;\"> As String<\/span>, strMethod<span style=\"color:blue;\"> As String<\/span>, strResponse<span style=\"color:blue;\"> As String<\/span>, <span style=\"color:blue;\">Optional<\/span> strData<span style=\"color:blue;\"> As String<\/span>, _\r\n        <span style=\"color:blue;\">Optional<\/span> strAuthorization<span style=\"color:blue;\"> As String<\/span>, <span style=\"color:blue;\">Optional<\/span> strContentType<span style=\"color:blue;\"> As String<\/span> = \"application\/json\")<span style=\"color:blue;\"> As Integer<\/span>\r\n    <span style=\"color:blue;\">Dim <\/span>objHTTP<span style=\"color:blue;\"> As <\/span>MSXML2.XMLHTTP60\r\n    <span style=\"color:blue;\">Set<\/span> objHTTP = <span style=\"color:blue;\">New<\/span> MSXML2.XMLHTTP60\r\n    <span style=\"color:blue;\">With<\/span> objHTTP\r\n        .Open strMethod, strURL, <span style=\"color:blue;\">False<\/span>\r\n        .setRequestHeader \"Accept\", strContentType\r\n        .setRequestHeader \"Content-Type\", strContentType\r\n        <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> <span style=\"color:blue;\">Len<\/span>(strAuthorization) = 0<span style=\"color:blue;\"> Then<\/span>\r\n            .setRequestHeader \"Authorization\", strAuthorization\r\n        <span style=\"color:blue;\">End If<\/span>\r\n        .send strData\r\n        strResponse = .responseText\r\n        HTTPRequest = .status\r\n    End <span style=\"color:blue;\">With<\/span>\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 1: Die Funktion HTTPRequest kapselt alle HTTP-Aufrufe an Rest-APIs.<\/span><\/b><\/p>\n<p>Die Funktion nimmt folgende Parameter entgegen:<\/p>\n<ul>\n<li><b>strURL<\/b>: Der vollst&auml;ndige Endpunkt des API-Aufrufs.<\/li>\n<li><b>strMethod<\/b>: Die HTTP-Methode, zum Beispiel <b>GET<\/b>, <b>POST<\/b>, <b>PUT<\/b> oder <b>DELETE<\/b>.<\/li>\n<li><b>strResponse<\/b>: Eine leere String-Variable, in die die Antwort des Servers geschrieben wird.<\/li>\n<li><b>strData<\/b>: Optionaler Body der Anfrage, zum Beispiel ein JSON-Dokument beim Anlegen einer neuen Ressource.<\/li>\n<li><b>strAuthorization<\/b>: Optionaler Autorisierungsheader, zum Beispiel <b>Bearer <Token><\/b> oder <b>ApiKey <Key><\/b>.<\/li>\n<li><b>strContentType<\/b>: Optionaler Content-Type, Standardwert ist <b>application\/json<\/b>.<\/li>\n<\/ul>\n<p>Als R&uuml;ckgabewert liefert die Funktion den HTTP-Statuscode als <b>Integer<\/b>. Die aufrufende Prozedur kann diesen Wert auswerten und entsprechend reagieren.<\/p>\n<h2>Statuscodes auswerten<\/h2>\n<p>Eine typische Auswertung des Statuscodes sieht wie folgt aus. Der <b>Select Case<\/b>-Block behandelt die h&auml;ufigsten F&auml;lle.<\/p>\n<pre><span style=\"color:blue;\">Dim <\/span>intStatus<span style=\"color:blue;\"> As Integer<\/span>\r\n<span style=\"color:blue;\">Dim <\/span>strResponse<span style=\"color:blue;\"> As String<\/span>\r\nintStatus = HTTPRequest( _\r\n    \"https:\/\/api.beispiel.de\/v1\/daten\", _\r\n    \"GET\", strResponse)\r\nSelect Case intStatus\r\n    <span style=\"color:blue;\">Case <\/span>200, 201\r\n        'Erfolg: Antwort verarbeiten\r\n        <span style=\"color:blue;\">Debug.Print<\/span> strResponse\r\n    <span style=\"color:blue;\">Case <\/span>401\r\n        <span style=\"color:blue;\">MsgBox<\/span> \"Authentifizierung fehlgeschlagen.\" _\r\n            & \" Token pr&uuml;fen.\"\r\n    <span style=\"color:blue;\">Case <\/span>404\r\n        <span style=\"color:blue;\">MsgBox<\/span> \"Endpunkt nicht gefunden.\"\r\n    <span style=\"color:blue;\">Case Else<\/span>\r\n        <span style=\"color:blue;\">MsgBox<\/span> \"Fehler: \" & intStatus _\r\n            & <span style=\"color:blue;\">vbCrLf<\/span> & strResponse\r\n<span style=\"color:blue;\">End Select<\/span><\/pre>\n<p>Beachte, dass die Codes <b>200<\/b> und <b>201 <\/b>beide Erfolg bedeuten: <b>200 <\/b>steht f&uuml;r einen allgemeinen Erfolg, <b>201 <\/b>f&uuml;r das erfolgreiche Anlegen einer neuen Ressource per POST. Viele APIs verwenden beide.<\/p>\n<h2>Beispieldatenbank<\/h2>\n<p>F&uuml;r das folgende Praxisbeispiel ben&ouml;tigen wir keine eigene Datenbank. Wir nutzen den &ouml;ffentlich zug&auml;nglichen Dienst <b>JSONPlaceholder<\/b> unter <b>https:\/\/jsonplaceholder.typicode.com<\/b>. Dieser bietet eine kostenlos nutzbare Testumgebung, die REST-Aufrufe entgegennimmt und mit realistischen JSON-Daten antwortet &#8211; ohne Anmeldung und ohne API-Key. Das macht ihn ideal als ersten Testpartner.<\/p>\n<p>Der Dienst stellt unter anderem diese Ressourcen bereit: <b>posts<\/b> (Blogbeitr&auml;ge), <b>users<\/b> (Benutzerdaten) und <b>todos<\/b> (Aufgaben). Wir verwenden in den folgenden Beispielen die Ressource <b>posts<\/b>. <\/p>\n<p>Aber Achtung: Auch wenn das Anlegen neuer Elemente, das &Auml;ndern oder L&ouml;schen bestehender Elemente als erfolgreich gemeldet wird, werden die &Auml;nderungen nicht tats&auml;chlich durchgef&uuml;hrt.<\/p>\n<h2>GET: Daten lesen<\/h2>\n<p>Mit der Prozedur <b>PostsLesen<\/b> aus Listing 2 lesen wir den ersten Beitrag aus dem Dienst aus. Die URL lautet <b>https:\/\/jsonplaceholder.typicode.com\/posts\/1<\/b> &#8211; die <b>1<\/b> am Ende ist die ID des Datensatzes.<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>PostsLesen()\r\n    <span style=\"color:blue;\">Dim <\/span>intStatus<span style=\"color:blue;\"> As Integer<\/span>\r\n    <span style=\"color:blue;\">Dim <\/span>strURL<span style=\"color:blue;\"> As String<\/span>\r\n    <span style=\"color:blue;\">Dim <\/span>strResponse<span style=\"color:blue;\"> As String<\/span>\r\n    strURL = \"https:\/\/jsonplaceholder.typicode.com\/posts\/1\"\r\n    intStatus = HTTPRequest(strURL, \"GET\", strResponse)\r\n    Select Case intStatus\r\n        <span style=\"color:blue;\">Case <\/span>200\r\n            <span style=\"color:blue;\">Debug.Print<\/span> strResponse\r\n        <span style=\"color:blue;\">Case Else<\/span>\r\n            <span style=\"color:blue;\">MsgBox<\/span> \"Fehler: \" & intStatus\r\n    <span style=\"color:blue;\">End Select<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 2: Abrufen eines einzelnen Datensatzes per GET<\/span><\/b><\/p>\n<p>Wenn wir diese Prozedur starten, erscheint im Direktbereich des VBA-Editors ein JSON-Dokument wie das folgende:<\/p>\n<pre>{\r\n  \"userId\": 1,\r\n  \"id\": 1,\r\n  \"title\": \"sunt aut facere repellat...\",\r\n  \"body\": \"quia et suscipit...\"\r\n}<\/pre>\n<p>Das ist die rohe JSON-Antwort des Servers. Wie wir dieses Dokument in VBA auswerten, zeigen wir im Abschnitt &#8220;JSON-Antworten verarbeiten&#8221;.<\/p>\n<h2>POST: Einen neuen Datensatz anlegen<\/h2>\n<p>Ein <b>POST<\/b>-Aufruf unterscheidet sich von einem <b>GET<\/b>-Aufruf dadurch, dass wir einen Body mitschicken &#8211; also ein JSON-Dokument, das die Daten des neuen Datensatzes enth&auml;lt. Listing 3 zeigt, wie wir einen neuen Beitrag anlegen.<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>PostAnlegen()\r\n    <span style=\"color:blue;\">Dim <\/span>intStatus<span style=\"color:blue;\"> As Integer<\/span>\r\n    <span style=\"color:blue;\">Dim <\/span>strURL<span style=\"color:blue;\"> As String<\/span>\r\n    <span style=\"color:blue;\">Dim <\/span>strData<span style=\"color:blue;\"> As String<\/span>\r\n    <span style=\"color:blue;\">Dim <\/span>strResponse<span style=\"color:blue;\"> As String<\/span>\r\n    strURL = \"https:\/\/jsonplaceholder.typicode.com\/posts\"\r\n    strData = \"{\"\"title\"\":\"\"Mein Titel\"\",\"\"body\"\":\"\"Inhalt des Beitrags\"\",\"\"userId\"\":1}\"\r\n    intStatus = HTTPRequest(strURL, \"POST\", strResponse, strData)\r\n    Select Case intStatus\r\n        <span style=\"color:blue;\">Case <\/span>201\r\n            <span style=\"color:blue;\">Debug.Print<\/span> \"Angelegt: \" & strResponse\r\n        <span style=\"color:blue;\">Case Else<\/span>\r\n            <span style=\"color:blue;\">MsgBox<\/span> \"Fehler: \" & intStatus\r\n    <span style=\"color:blue;\">End Select<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 3: Anlegen eines neuen Datensatzes per POST<\/span><\/b><\/p>\n<p>Das JSON-Dokument in <b>strData<\/b> stellen wir als String direkt im Code zusammen. Dabei verdoppeln wir innere Anf&uuml;hrungszeichen, weil VBA Anf&uuml;hrungszeichen innerhalb von String-Literalen so maskiert. Im fertigen String liefert das g&uuml;ltiges JSON.<\/p>\n<p>Der Dienst antwortet mit dem Statuscode 201 und gibt das angelegte Objekt inklusive der neu vergebenen ID zur&uuml;ck.<\/p>\n<h2>PUT: Einen Datensatz ersetzen<\/h2>\n<p>Ein <b>PUT<\/b>-Aufruf ersetzt einen vorhandenen Datensatz vollst&auml;ndig. Wir &uuml;bergeben die ID in der URL und schicken das vollst&auml;ndige, aktualisierte Objekt als Body mit. Listing 4 zeigt, wie wir den Beitrag mit der ID 1 ersetzen.<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>PostErsetzen()\r\n    <span style=\"color:blue;\">Dim <\/span>intStatus<span style=\"color:blue;\"> As Integer<\/span>\r\n    <span style=\"color:blue;\">Dim <\/span>strURL<span style=\"color:blue;\"> As String<\/span>\r\n    <span style=\"color:blue;\">Dim <\/span>strData<span style=\"color:blue;\"> As String<\/span>\r\n    <span style=\"color:blue;\">Dim <\/span>strResponse<span style=\"color:blue;\"> As String<\/span>\r\n    strURL = \"https:\/\/jsonplaceholder.typicode.com\/posts\/1\"\r\n    strData = \"{\"\"id\"\":1,\"\"title\"\":\"\"Neuer Titel\"\",\"\"body\"\":\"\"Neuer Inhalt\"\",\"\"userId\"\":1}\"\r\n    intStatus = HTTPRequest(strURL, \"PUT\", strResponse, strData)\r\n    Select Case intStatus\r\n        <span style=\"color:blue;\">Case <\/span>200\r\n            <span style=\"color:blue;\">Debug.Print<\/span> \"Ersetzt: \" & strResponse\r\n        <span style=\"color:blue;\">Case Else<\/span>\r\n            <span style=\"color:blue;\">MsgBox<\/span> \"Fehler: \" & intStatus\r\n    <span style=\"color:blue;\">End Select<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 4: Ersetzen eines vorhandenen Datensatzes per PUT<\/span><\/b><\/p>\n<h2>DELETE: Einen Datensatz l&ouml;schen<\/h2>\n<p>Das L&ouml;schen ist der einfachste Aufruf: Wir senden ein <b>DELETE<\/b> an die URL des Datensatzes, ohne einen Body mitzuschicken. Der Dienst antwortet mit dem Statuscode 200 und einem leeren JSON-Objekt, was den erfolgreichen L&ouml;schvorgang best&auml;tigt. Listing 5 zeigt die zugeh&ouml;rige Prozedur.<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>PostLoeschen()\r\n    <span style=\"color:blue;\">Dim <\/span>intStatus<span style=\"color:blue;\"> As Integer<\/span>\r\n    <span style=\"color:blue;\">Dim <\/span>strURL<span style=\"color:blue;\"> As String<\/span>\r\n    <span style=\"color:blue;\">Dim <\/span>strResponse<span style=\"color:blue;\"> As String<\/span>\r\n    strURL = \"https:\/\/jsonplaceholder.typicode.com\/posts\/1\"\r\n    intStatus = HTTPRequest(strURL, \"DELETE\", strResponse)\r\n    Select Case intStatus\r\n        <span style=\"color:blue;\">Case <\/span>200\r\n            <span style=\"color:blue;\">MsgBox<\/span> \"Datensatz gel&ouml;scht.\"\r\n        <span style=\"color:blue;\">Case Else<\/span>\r\n            <span style=\"color:blue;\">MsgBox<\/span> \"Fehler: \" & intStatus\r\n    <span style=\"color:blue;\">End Select<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 5: L&ouml;schen eines Datensatzes per DELETE.<\/span><\/b><\/p>\n<h2>JSON-Antworten verarbeiten<\/h2>\n<p>Nachdem wir die rohe JSON-Antwort in <b>strResponse<\/b> haben, m&uuml;ssen wir sie auslesen. VBA bietet daf&uuml;r keine eingebaute Unterst&uuml;tzung. In der VBE-Artikelreihe haben wir daf&uuml;r die Module <b>mdlJSON<\/b> und <b>mdlJSONDOM<\/b> vorgestellt, die alle n&ouml;tigen Werkzeuge bereitstellen.<\/p>\n<p>Diese haben wir im Detail in den Artikeln <b>Mit JSON arbeiten<\/b> (<b>www.vbentwickler.de\/361<\/b>) und <b>JSON-Dokumente per Objektmodell zusammenstellen<\/b> (<b>www.vbentwickler.de\/412<\/b>) beschrieben.<\/p>\n<p>F&uuml;gen wir dem Projekt die beiden Module hinzu, k&ouml;nnen wir mit der Funktion <b>ParseJson<\/b> die JSON-Zeichenkette in ein VBA-Objekt umwandeln und danach einzelne Felder &uuml;ber ihren Namen ansprechen. Listing 6 zeigt, wie wir die Antwort aus dem <b>GET<\/b>-Beispiel auswerten.<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>PostAuswerten()\r\n    <span style=\"color:blue;\">Dim <\/span>intStatus<span style=\"color:blue;\"> As Integer<\/span>\r\n    <span style=\"color:blue;\">Dim <\/span>strURL<span style=\"color:blue;\"> As String<\/span>\r\n    <span style=\"color:blue;\">Dim <\/span>strResponse<span style=\"color:blue;\"> As String<\/span>\r\n    <span style=\"color:blue;\">Dim <\/span>objJSON<span style=\"color:blue;\"> As Object<\/span>\r\n    strURL = \"https:\/\/jsonplaceholder.typicode.com\/posts\/1\"\r\n    intStatus = HTTPRequest(strURL, \"GET\", strResponse)\r\n    <span style=\"color:blue;\">If <\/span>intStatus = 200<span style=\"color:blue;\"> Then<\/span>\r\n        <span style=\"color:blue;\">Set<\/span> objJSON = ParseJson(strResponse)\r\n        <span style=\"color:blue;\">Debug.Print<\/span> \"id: \" & objJSON.Item(\"id\")\r\n        <span style=\"color:blue;\">Debug.Print<\/span> \"title: \" & objJSON.Item(\"title\")\r\n        <span style=\"color:blue;\">Debug.Print<\/span> \"body: \" & objJSON.Item(\"body\")\r\n    <span style=\"color:blue;\">End If<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 6: Auswerten der JSON-Antwort mit ParseJson.<\/span><\/b><\/p>\n<p>Die Methode <b>Item<\/b> des zur&uuml;ckgegebenen Objekts nimmt den Namen des JSON-Felds entgegen und gibt dessen Wert zur&uuml;ck.<\/p>\n<p>Wie wir mit Arrays und verschachtelten Objekten in JSON umgehen, beschreibt der oben genannte Artikel im Detail.<\/p>\n<h2>URL-Parameter zusammenstellen<\/h2>\n<p>F&uuml;r <b>GET<\/b>-Aufrufe, bei denen wir Filterkriterien &uuml;bergeben wollen, m&uuml;ssen wir die URL-Parameter als Teil der URL zusammenstellen. Das ist einfache String-Manipulation. Der erste Parameter beginnt nach einem Fragezeichen, alle weiteren werden mit dem Et-Zeichen angeh&auml;ngt:<\/p>\n<pre>strURL = \"https:\/\/jsonplaceholder\" _\r\n    & \".typicode.com\/posts\" _\r\n    & \"?userId=1\"<\/pre>\n<p>Wenn die Parameterwerte Sonderzeichen oder Leerzeichen enthalten, m&uuml;ssen sie URL-kodiert werden. Leerzeichen werden zum Beispiel als <b>%20<\/b> &uuml;bertragen. F&uuml;r einfache numerische oder alphanumerische Werte ist das in der Regel kein Thema.<\/p>\n<h2>Hinweis zur Fehlerbehandlung<\/h2>\n<p>In produktivem Code solltest Du den <b>HTTPRequest<\/b>-Aufruf in einem <b>On Error GoTo<\/b>-Block absichern. Netzwerkfehler &#8211; zum Beispiel kein Internetzugang, ein Timeout oder ein ung&uuml;ltiges SSL-Zertifikat &#8211; werfen keine HTTP-Statuscodes, sondern VBA-Laufzeitfehler.<\/p>\n<p>Ohne Fehlerbehandlung bricht die Prozedur mit einer Fehlermeldung ab. Eine robuste L&ouml;sung pr&uuml;ft deshalb sowohl den Statuscode als auch Laufzeitfehler, bevor sie die Antwort weiterverarbeitet.<\/p>\n<h2>Zusammenfassung und Ausblick<\/h2>\n<p>Dieser Artikel hat die Grundlagen f&uuml;r den Zugriff auf Rest-APIs mit VBA gelegt. Wir wissen nun, wie REST funktioniert, welche HTTP-Methoden es gibt, wie wir das <b>XMLHTTP60<\/b>-Objekt einsetzen und wie eine wiederverwendbare <b>HTTPRequest<\/b>-Funktion aussieht.<\/p>\n<p>Mit den vier Beispielen f&uuml;r <b>GET<\/b>, <b>POST<\/b>, <b>PUT <\/b>und <b>DELETE <\/b>haben wir alle grundlegenden Operationen einmal praktisch durchgespielt.<\/p>\n<p>Im n&auml;chsten Artikel zeigen wir, wie wir auf eine echte Rest-API mit Authentifizierung zugreifen &#8211; am Beispiel eines konkreten Dienstes.<\/p>\n<p>Dort kommt dann auch die Verwaltung von API-Keys und Bearer-Tokens zum Einsatz, und wir zeigen, wie wir die Zugangsdaten sicher in der Windows-Registry ablegen.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Wer mit VBA arbeitet, kommt heute kaum noch daran vorbei: Fast jeder interessante Online-Dienst &#8211; von Wetter- und Geo-Daten &uuml;ber Projektmanagement-Tools bis hin zu KI-Diensten &#8211; bietet eine Rest-API an. Dabei ist das Prinzip immer dasselbe: Du schickst eine HTTP-Anfrage an eine bestimmte URL, und der Dienst antwortet mit strukturierten Daten &#8211; in der Regel im JSON-Format. Ob Du Kundenadressen mit einem CRM abgleichen, Versandetiketten bei DHL anfordern, Aufgaben in Trello anlegen oder Texte mit DeepL &uuml;bersetzen willst &#8211; hinter all diesen Integrationen steckt dieselbe Technik. VBA bringt daf&uuml;r alle n&ouml;tigen Werkzeuge von Haus aus mit: Ein einziger Verweis auf eine Windows-Systembibliothek gen&uuml;gt, um HTTP-Anfragen abzusetzen und die Antworten auszuwerten. Dieser Artikel erkl&auml;rt, was eine Rest-API &uuml;berhaupt ist, welche Grundbegriffe Du kennen musst, um jede beliebige API-Dokumentation selbstst&auml;ndig zu lesen, und wie Du eine wiederverwendbare Funktion baust, die Du als solide Basis f&uuml;r jeden weiteren API-Aufruf einsetzen kannst.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[66022026,662026,44000012,44000028],"tags":[],"yst_prominent_words":[],"class_list":["post-55000502","post","type-post","status-publish","format-standard","hentry","category-66022026","category-662026","category-Interaktiv","category-Word_programmieren"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000502","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/comments?post=55000502"}],"version-history":[{"count":0,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000502\/revisions"}],"wp:attachment":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/media?parent=55000502"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/categories?post=55000502"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/tags?post=55000502"},{"taxonomy":"yst_prominent_words","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/yst_prominent_words?post=55000502"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}