{"id":55000461,"date":"2025-06-01T00:00:00","date_gmt":"2025-08-27T21:12:33","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=461"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"eBay_per_VBA_steuern_Angebote_suchen","status":"publish","type":"post","link":"https:\/\/vbentwickler.de\/eBay_per_VBA_steuern_Angebote_suchen\/","title":{"rendered":"eBay per VBA steuern: Angebote suchen"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg08.met.vgwort.de\/na\/85e0e23367ae4268a67883b67825c8b9\" width=\"1\" height=\"1\" alt=\"\"><b>Im ersten Teil der Artikelreihe zum Thema Steuerung von eBay mit VBA haben wir gezeigt, wie man einen Entwickler-Account anlegt, eine neue Anwendung bei eBay erstellt, grundlegende Zugriffsdaten holt und die f&uuml;r die Authentifizierung im Kontext eines bestimmten Benutzerkontos notwendigen Informationen holt &#8211; hier speziell das Authentifizierungstoken. Damit haben wir die Basis geschaffen, um per VBA auf die Rest API von eBay zuzugreifen. Damit fahren wir in diesem Teil fort: Wir wollen den grundlegenden Zugriff auf die Rest-API von eBay herstellen und verwenden dazu einfache Beispiele. Wie sich zeigt, gibt es zwei verschiedene Kontexte, in denen wir hier arbeiten, den Anwendungs- und den Benutzerkontext. Beide beschreiben wir in diesem Artikel.<\/b><\/p>\n<h2>Anwendungs- und Benutzerkontext<\/h2>\n<p>Wir im ersten Teil der Artikelreihe namens <b>eBay per VBA steuern: Zugangsdaten holen <\/b>(<b>www.vbentwickler.de\/460<\/b>) beschrieben, gibt es zwei verschiedene Kontexte, in denen wir auf die Rest-API von eBay zugreifen k&ouml;nnen:<\/p>\n<ul>\n<li><b>Anwendungskontext<\/b>: Dies erlaubt uns die Nutzung allgemein zug&auml;nglicher Informationen &#8211; also beispielsweise solche, die man auch auf der Webseite <b>ebay.com <\/b>als nicht angemeldeter Benutzer einsehen kann. Hier f&uuml;r reicht das im oben genannten Artikel ermittelte Anwendungstoken zur Authentifizierung aus.<\/li>\n<li><b>Benutzerkontext<\/b>: Hiermit k&ouml;nnen wir solche Aktionen durchf&uuml;hren, die man auch als angemeldeter Benutzer erledigen kann. Dazu ben&ouml;tigen wir das Benutzertoken aus dem vorherigen Artikel. Damit wir die Benutzerfunktionen nutzen k&ouml;nnen, muss das Benutzertoken auch im Kontext der Anmeldung des entsprechenden Benutzers geholt werden.<\/li>\n<\/ul>\n<p>Zu beachten ist, dass man je nach der verwendeten API und Funktion keine Authentifizierung, die Anwendungsauthentifizierung oder die Benutzerauthentifizierung ben&ouml;tigt. Wann welche Authentifizierung ben&ouml;tigt wird, erf&auml;hrt man am einfachsten in der API-Dokumentation beziehungsweise im API-Explorer.<\/p>\n<h2>Zurechtfinden im API-Dschungel<\/h2>\n<p>eBay hat einen umfangreichen Bestand an API-Funktionen. Einen ersten &Uuml;berblick findet man auf der folgenden Webseite:<\/p>\n<pre>https:\/\/developer.ebay.com\/develop<\/pre>\n<p>Von hier aus geht es weiter zu den absoluten Grundlagen, zum Entwickeln von Anwendungen zum Verkaufen oder Kaufen oder zu weiteren Themen.<\/p>\n<p>Im Bereich <b>Kaufen <\/b>interessiert uns beispielsweise, wie wir eine Suche nach Artikeln per VBA realisieren k&ouml;nnen. Im Bereich <b>Verkaufen <\/b>w&auml;re es spannend, eigene Artikel voll automatisiert per VBA bei eBay einstellen zu k&ouml;nnen. Oder auch herauszufinden, welche Artikel wir gerade bei eBay anbieten und in welcher Anzahl, um hier gegebenenfalls aufzustocken. Beide Bereiche bieten zahlreiche Funktionen bereit, wir wollen uns jedoch auf den Bereich des Verkaufens konzentrieren.<\/p>\n<p>&Uuml;ber diesen k&ouml;nnen wir uns in den weiterf&uuml;hrenden Artikeln des oben genannten Links einen ersten &Uuml;berblick verschaffen. Diesen finden wir zum Zeitpunkt der Erstellung dieses Artikels unter dem folgenden Link:<\/p>\n<pre>https:\/\/developer.ebay.com\/api-docs\/sell\/static\/selling-ig-landing.html<\/pre>\n<p>Hier finden wir einen &Uuml;berblick &uuml;ber die Unterbereiche zum Thema Verkaufen auf eBay (siehe Bild 1).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_03\/pic_461_001.png\" alt=\"&Uuml;berblick &uuml;ber die eBay Sell API\" width=\"649,627\" height=\"552,1515\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: &Uuml;berblick &uuml;ber die eBay Sell API<\/span><\/b><\/p>\n<h2>Einstellen von Artikeln<\/h2>\n<p>Zum Einstellen von Artikeln finden wir verschiedene Ans&auml;tze:<\/p>\n<ul>\n<li><b>eBay Trading API<\/b>: Diese API ist bereits etwas &auml;lter. Sie ist XML-basiert und bietet beispielsweise Funktionen wie <b>AddItem<\/b>. <\/li>\n<li><b>eBay Inventory API<\/b>: Diese API ist moderner und verwendet JSON f&uuml;r den Datenaustausch.<\/li>\n<\/ul>\n<p>Wir wollen uns in dieser Artikelreihe auf die aktuellen Techniken funktionieren und schauen uns daher die Variante an, welche die <b>eBay Inventory API <\/b>nutzt.<\/p>\n<h2>API-Katalog<\/h2>\n<p>Aufrufe von Rest-API haben wir in diesem Magazin bereits an einigen Beispielen demonstriert. Aber woher beziehen wir im Falle der eBay-API die wirklich wichtigen Informationen wie die folgenden:<\/p>\n<ul>\n<li>Welche Authentifizierungsmethode ben&ouml;tigen wir &#8211; anwendungs- oder benutzerorientiert?<\/li>\n<li>Wie lauten die Endpunkte f&uuml;r die gew&uuml;nschten Aufrufe?<\/li>\n<li>Welche Parameter m&uuml;ssen wir noch &uuml;bermitteln?<\/li>\n<li>Wie werden die JSON-Dokumente aufgebaut, die wir &uuml;bermitteln?<\/li>\n<li>Und wie ist der Aufbau der JSON-Dokumente, die als Ergebnis zur&uuml;ckgeliefert werden?<\/li>\n<li>Welche Statuscodes werden von den verschiedenen Funktionen zur&uuml;ckgeliefert und was bedeuten diese?<\/li>\n<\/ul>\n<p>Antworten auf viele dieser Fragen liefert der API-Katalog, den wir unter dem folgenden Link finden (alternativ suchen wir im Internet nach dem Suchbegriff <b>ebay api explorer<\/b>):<\/p>\n<pre>https:\/\/developer.ebay.com\/my\/api_test_tool?index=0<\/pre>\n<p>Damit landen wir auf der <b>API Explorer<\/b>-Seite (siehe Bild 2). Hier sehen wir verschiedene Elemente.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_03\/pic_461_002.png\" alt=\"Aufrufen einer API-Funktion\" width=\"700\" height=\"518,5607\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 2: Aufrufen einer API-Funktion<\/span><\/b><\/p>\n<p>Wichtig ist erst einmal, dass wir oben die richtige Umgebung ausw&auml;hlen, also <b>Sandbox <\/b>oder <b>Production<\/b>.<\/p>\n<p>Danach w&auml;hlen wir im linken Bereich die zu verwendende Anwendung aus, hier <b>amvBay<\/b>, und die eBay-Seite, die wir untersuchen wollen. Wir m&ouml;chten auf der deutschen Seite suchen und w&auml;hlen deshalb <b>(77) Germany <\/b>aus.<\/p>\n<p>Danach entscheiden wir, welche API wir nutzen wollen. Wir wollen erst einmal Angebote durchsuchen, also w&auml;hlen wir die <b>Browse API<\/b>.<\/p>\n<p>Dies aktualisiert wiederum direkt die Auswahl unter <b>Select an API call<\/b>. Hier w&auml;hlen wir die Funktion <b>search <\/b>aus.<\/p>\n<p>Dadurch wird rechts das Feld <b>Web Service URI (endpoint) <\/b>gef&uuml;llt, in diesem Fall mit dem folgenden Beispielcode:<\/p>\n<pre>https:\/\/api.ebay.com\/buy\/browse\/v1\/item_summary\/search?q=drone&limit=3<\/pre>\n<p>Dies sind die Bestandteile:<\/p>\n<ul>\n<li>Basis-URL <b>https:\/\/api.ebay.com\/buy\/browse\/v1\/<\/b>: Dies ist der Einstiegspunkt f&uuml;r die eBay Browse API, die Informationen zu Artikeln bereitstellt, die auf eBay zum Verkauf stehen.<\/li>\n<li>Endpunkt <b>item_summary\/search<\/b>: Dieser Endpunkt f&uuml;hrt eine Suche nach Artikeln durch und liefert eine Zusammenfassung (<b>item summary<\/b>) der gefundenen Ergebnisse.<\/li>\n<li>Parameter <b>q=drone<\/b>: Dies ist der Suchbegriff. In diesem Fall wird nach Artikeln gesucht, die den Begriff <b>drone <\/b>enthalten. Es durchsucht Titel, Beschreibung und andere relevante Felder der Artikel.<\/li>\n<li>Anzahl der Ergebnisse <b>limit=3<\/b>: Dies legt fest, wie viele Ergebnisse pro Anfrage zur&uuml;ckgegeben werden sollen. In diesem Fall werden maximal drei Artikel zur&uuml;ckgegeben.<\/li>\n<\/ul>\n<p>Wichtig ist auch noch der Inhalt des kleinen K&auml;stchens in der N&auml;he von Call Request, das zum Beispiel <b>GET<\/b>, <b>POST<\/b>, <b>PUT <\/b>oder <b>DELETE <\/b>enthalten kann &#8211; eine Information, die wir sp&auml;ter f&uuml;r den Aufruf der Rest AP ben&ouml;tigen.<\/p>\n<h2>HTTP-Header<\/h2>\n<p>Darunter finden wir den Bereich <b>HTTP Headers<\/b>. Auch hier finden wir wertvolle Informationen, die wir gegebenenfalls in unserem eigenen Aufruf per VBA ber&uuml;cksichtigen m&uuml;ssen. Auch dort haben wir die M&ouml;glichkeit, Header zu &uuml;bersenden. Klicken wir nun auf <b>Execute<\/b>, erhalten wir im unteren Bereich das Ergebnis. Dieses sieht wie in Bild 3 aus.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_03\/pic_461_003.png\" alt=\"Ergebnis der Artikelsuche\" width=\"649,627\" height=\"885,561\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 3: Ergebnis der Artikelsuche<\/span><\/b><\/p>\n<p>Hier sehen wir im oberen Bereich die Response-Header, die f&uuml;r uns weniger interessant sind. Spannender ist das tats&auml;chliche Ergebnis unter <b>Response Body<\/b>.<\/p>\n<p>Hier finden wir im JSON-Format die Eigenschaften der gefundenen Artikel. Unser Ziel ist es, dieses Dokument per VBA auszulesen und es dann auslesen zu k&ouml;nnen. Das erledigen wir in den folgenden Abschnitten.<\/p>\n<h2>Voraussetzung: OAuth Application Token<\/h2>\n<p>Um auf die Api zuzugreifen, ben&ouml;tigen wir das sogenannte OAuth Application Token. Das holen wir uns, nachdem wir die im Artikel <b>eBay per VBA steuern: Zugangsdaten holen <\/b>(<b>www.vbentwickler.de\/460<\/b>) beschriebenen Schritte zum Erstellen eines Entwicklerkontos und einer App durchgef&uuml;hrt haben, mit der VBA-Prozedur <b>GetEbayAppToken<\/b>. Diese rufen wir wie folgt auf, um das Token direkt in der Registry zu speichern:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>GetEbayAppTokenInRegistry()\r\n     <span style=\"color:blue;\">Dim <\/span>strAppToken<span style=\"color:blue;\"> As String<\/span>\r\n     strAppToken = GetEbayAppToken(GetAppSetting(\"AppID\"), _\r\n         GetAppSetting(\"CertID\"), cStrAPIScope)\r\n     SaveAppSetting \"AppToken\", strAppToken\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Voraussetzung ist, dass wir zuvor die &uuml;brigen notwendigen Informationen, also die <b>AppID <\/b>und die <b>CertID <\/b>sowie den <b>APIScope <\/b>wie im oben genannten Artikel ermittelt haben.<\/p>\n<h2>Erster Wurf: Aufruf testen<\/h2>\n<p>In der Prozedur <b>GetItems<\/b> haben wir einen ersten Anlauf zusammengestellt, um eine Liste von Artikeln abzurufen (siehe Listing 1). Wobei erster Anlauf untertrieben ist &#8211; wir haben im Vorfeld bereits einige Versuche unternommen, bis wir eine lauff&auml;hige Variante hatten.<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>GetItems(strResponse<span style=\"color:blue;\"> As String<\/span>)<span style=\"color:blue;\"> As Boolean<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>objXMLHTTP<span style=\"color:blue;\"> As <\/span>MSXML2.XMLHTTP60\r\n     <span style=\"color:blue;\">Dim <\/span>strURL<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strOAuthToken<span style=\"color:blue;\"> As String<\/span>\r\n     strURL = \"https:\/\/api.ebay.com\/buy\/browse\/v1\/item_summary\/search?q=drone&limit=3\"\r\n     strOAuthToken = \"Bearer \" & cStrAppToken\r\n     <span style=\"color:blue;\">Set<\/span> objXMLHTTP = <span style=\"color:blue;\">New<\/span> MSXML2.XMLHTTP60\r\n     objXMLHTTP.Open \"GET\", strURL, <span style=\"color:blue;\">False<\/span>\r\n     \r\n     objXMLHTTP.setRequestHeader \"Authorization\", strOAuthToken\r\n     objXMLHTTP.setRequestHeader \"X-EBAY-C-MARKETPLACE-ID\", \"EBAY_DE\"\r\n     objXMLHTTP.setRequestHeader \"X-EBAY-C-ENDUSERCTX\", _\r\n         \"ffiliateCampaignId=&lt;ePNCampaignId&gt;,affiliateReferenceId=&lt;referenceId&gt;\"\r\n     objXMLHTTP.Send\r\n     strResponse = objXMLHTTP.responseText\r\n     Select Case objXMLHTTP.status\r\n         <span style=\"color:blue;\">Case <\/span>200\r\n             GetItems = <span style=\"color:blue;\">True<\/span>\r\n         <span style=\"color:blue;\">Case Else<\/span>\r\n             <span style=\"color:blue;\">Debug.Print<\/span> objXMLHTTP.status & <span style=\"color:blue;\">vbCrLf<\/span> & objXMLHTTP.responseText\r\n     <span style=\"color:blue;\">End Select<\/span>\r\n     \r\n     <span style=\"color:blue;\">Set<\/span> objXMLHTTP = Nothing\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 1: Erster Aufruf der eBay-Rest API<\/span><\/b><\/p>\n<p>Die Dokumentation des hier verwendeten Endpunkts <b>item_summary\/search <\/b>findest Du hier:<\/p>\n<pre>https:\/\/developer.ebay.com\/api-docs\/buy\/browse\/resources\/item_summary\/methods\/search<\/pre>\n<p>Hier findest Du ausf&uuml;hrlich alle m&ouml;glichen Parameter und wie man sie einsetzt und es wird auch der komplette Output dieses Aufrufs erl&auml;utert.<\/p>\n<p>Die Prozedur deklariert zun&auml;chst eine Variable des Typs <b>MSXML2.XMLHTTP60<\/b>. Um diese verwenden zu k&ouml;nnen, ben&ouml;tigen wir einen Verweis auf die Bibliothek <b>Microsoft XML, v6.0 <\/b>hinzu.<\/p>\n<p>In diesem Zuge addieren wir direkt noch einen Verweis auf Bibliothek <b>Microsoft Scripting Runtime<\/b> (siehe Bild 4).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_03\/pic_461_004.png\" alt=\"Verweise f&uuml;r XML und JSON\" width=\"424,6267\" height=\"334,749\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 4: Verweise f&uuml;r XML und JSON<\/span><\/b><\/p>\n<p>Letzteren ben&ouml;tigen wir f&uuml;r Funktionen f&uuml;r den Zugriff auf die von der Rest API zur&uuml;ckgelieferten JSON-Dokumente.<\/p>\n<p>Wenn Du die Anwendung nachbauen m&ouml;chtest, ben&ouml;tigst Du auf jeden Fall noch die folgenden beiden Module:<\/p>\n<ul>\n<li><b>mdlJSON<\/b>: Enth&auml;lt Funktionen zum Parsen von JSON-Dokumenten ein Objektmodell und zum Erzeugen von JSON-Dateien aus diesem Objektmodell.<\/li>\n<li><b>mdlJSONDOM<\/b>: Enth&auml;lt Funktionen, mit denen wir die Bez&uuml;ge f&uuml;r den Zugriff auf die Elemente des Objektmodells f&uuml;r alle JSON-Dokumente leicht ausgeben und &uuml;bernehmen k&ouml;nnen.<\/li>\n<\/ul>\n<p>Au&szlig;erdem ist auch das Modul <b>mdlZwischenablage <\/b>hilfreich. Dieses enth&auml;lt eine Funktion, mit der wir den Inhalt einer Variablen in die Zwischenablage kopieren k&ouml;nnen.<\/p>\n<p>Das ist hilfreich, wenn wir gr&ouml;&szlig;ere JSON-Dokumente von der Rest-API zur&uuml;ckbekommen, die wir nicht vollst&auml;ndig im Direktbereich ausgeben k&ouml;nnen, ohne das der obere Teil gel&ouml;scht wird. Dann k&ouml;nnen wir solche Texte aus der Zwischenablage in einen Text- oder JSON-Editor kopieren, um sie dort zu analysieren.<\/p>\n<p>Die Prozedur erstellt noch weitere <b>String<\/b>-Variablen. Dann f&uuml;gt sie der Variablen <b>strUrl <\/b>die Adresse unserer Rest API-Funktion hinzu, die wir hier vorerst 1:1 aus dem API Explorer entnommen haben. Danach f&uuml;gt sie das Schl&uuml;sselwort <b>Bearer <\/b>mit dem Anwendungstoken aus der Konstanten <b>cStrAppToken <\/b>zusammen.<\/p>\n<p>Damit erstellt sie nun ein Objekt auf Basis des Typs <b>MSXML2.XMLHTTP60<\/b> und ruft dessen <b>Open<\/b>-Methode auf. Die Parameter sehen wie folgt aus:<\/p>\n<ul>\n<li><b>bstrMethod<\/b>: Gibt die Zugriffsmethode an, zum Beispiel <b>GET, POST<\/b>, <b>PUT <\/b>oder <b>DELETE<\/b><\/li>\n<li><b>bstrURL<\/b>: Gibt die Adresse der Rest API-Funktion an.<\/li>\n<li><b>varAsynch<\/b>: Gibt an, ob der Aufruf asynchron angegeben werden soll. Der Wert <b>False <\/b>legt fest, dass dieser synchron erfolgen soll, das hei&szlig;t, die ausf&uuml;hrende Prozedur wird erst fortgesetzt, wenn der Aufruf<b> <\/b>beendet ist.<\/li>\n<\/ul>\n<p>Danach setzen wir Request-Header, die wir ebenfalls dem entsprechenden Bereich im API Explorer entnehmen k&ouml;nnen.<\/p>\n<p>Diese teilen wir am Doppelpunkt auf und geben den linken Teil in Anf&uuml;hrungszeichen f&uuml;r den Parameter <b>bstrHeader <\/b>an und den rechten als <b>bstrValue<\/b>. So &uuml;bergeben wir das Token und auch weitere Informationen &uuml;ber den Aufruf wie beispielsweise den zu durchsuchenden Markt.<\/p>\n<p>Danach senden wir die Anfrage schlie&szlig;lich mit der <b>Send<\/b>-Methode ab und erhalten verschiedene Ergebnisse, zum Beispiel:<\/p>\n<ul>\n<li>&uuml;ber die Eigenschaft <b>status <\/b>den Status der Anfrage, zum Beispiel mit dem Wert <b>200<\/b> im Erfolgsfall oder <b>404<\/b>, falls die Adresse aus <b>strUrl <\/b>nicht existiert und<\/li>\n<li>&uuml;ber die Eigenschaft <b>responseText<\/b>, die zumindest dann, wenn die URL korrekt war, einen Ergebnistext zur&uuml;ckliefert.<\/li>\n<\/ul>\n<p>Geben wir zum Beispiel das falsche Token an, erhalten wir f&uuml;r <b>status <\/b>den Wert <b>401 <\/b>und f&uuml;r <b>responseText <\/b>diesen Text:<\/p>\n<pre>{\"errors\":\r\n   [\r\n     {      \"errorId\": 1001,      \"domain\": \"OAuth\",      \"category\": \"REQUEST\",      \"message\": \"Invalid access token\",      \"longMessage\": \"Invalid access token. Check the value of the Authorization HTTP request header.\" }\r\n   ]\r\n}<\/pre>\n<p>Im Erfolgsfall hingegen erhalten wir ein JSON-Dokument, das etwa wie in Bild 5 aussieht.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_03\/pic_461_005.png\" alt=\"Ergebnis der Abfrage im JSON-Format\" width=\"700\" height=\"935,2939\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 5: Ergebnis der Abfrage im JSON-Format<\/span><\/b><\/p>\n<p>Hier ist der erste von drei Artikel aus dem Ergebnis der Abfrage abgebildet.<\/p>\n<p>Wie aber wollen wir hier nur gezielt auf einzelne Elemente zugreifen?<\/p>\n<p>W&auml;hrend das gelegentlich rein mit Zeichenkettenfunktionen erledigt wird, indem man beispielsweise nach dem Namen des gew&uuml;nschten Elements sucht, ist das in gr&ouml;&szlig;eren Dokumenten wie diesem hier keine angenehme Aufgabe.<\/p>\n<p>Hier kommen unsere Prozeduren aus den beiden Modulen <b>mdlJSON <\/b>und <b>mdlJSONDOM <\/b>ins Spiel.<\/p>\n<p>Wir bauen eine Prozedur zum Aufrufen der Funktion <b>GetItems <\/b>und zum Auswerten des Ergebnisses. Diese sieht zun&auml;chst wie folgt aus:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>Test_GetItems()\r\n     <span style=\"color:blue;\">Dim <\/span>strJSON<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     \r\n     strJSON = GetItems()\r\n     <span style=\"color:blue;\">Set<\/span> objJSON = ParseJson(strJSON)\r\n     <span style=\"color:blue;\">Debug.Print<\/span> GetJSONDOM(strJSON, <span style=\"color:blue;\">True<\/span>)\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Die Variable <b>strJSON<\/b> soll das JSON-Dokument als Zeichenkette aufnehmen.<\/p>\n<p>Die Variable <b>objJSON <\/b>f&uuml;llen wir mit dem Ergebnis der Funktion <b>ParseJson <\/b>mit dem Parameter <b>strResponse<\/b> und erhalten ein Objektmodell, dass alle Elemente des JSON-Dokuments enth&auml;lt und aus verschachtelten <b>Dictionary<\/b>&#8211; und <b>Collection<\/b>-Elementen besteht.<\/p>\n<p>Wie aber erfahren wir nun, wie wir gezielt auf die einzelnen Informationen zugreifen k&ouml;nnen &#8211; oder wie wir beispielsweise in einer Schleife durch die zur&uuml;ckgelieferten Artikel laufen k&ouml;nnen?<\/p>\n<p>Die Grundlage dazu liefert die Funktion <b>GetJSONDOM<\/b>. Dieser &uuml;bergeben wir den kompletten Inhalt des JSON-Dokuments und mit dem zweiten Parameter den Wert <b>True<\/b>, damit nicht nur die Ausdr&uuml;cke, die zu den Werten f&uuml;hren, ausgegeben, sondern auch die Werte selbst.<\/p>\n<p>Die Funktion durchl&auml;uft alle Elemente und tr&auml;gt sie in einer Zeichenkette zusammen. Diese k&ouml;nnen wir entweder im Direktbereich ablegen oder wir speichern sie in der Zwischenablage.<\/p>\n<p>Der Inhalt sieht wie in Listing 2 aus. Der linke Teil enth&auml;lt jeweils das Objekt <b>objJSON<\/b>, dahinter folgt der Ausdruck, mit dem man den Wert f&uuml;r das entsprechende Element auslesen kann.<\/p>\n<pre>objJSON.Item(\"href\"):https:\/\/api.ebay.com\/buy\/browse\/v1\/item_summary\/search?q=drone&limit=3&offset=0\r\nobjJSON.Item(\"total\"):6081\r\nobjJSON.Item(\"next\"):https:\/\/api.ebay.com\/buy\/browse\/v1\/item_summary\/search?q=drone&limit=3&offset=3\r\nobjJSON.Item(\"limit\"):3\r\nobjJSON.Item(\"offset\"):0\r\nobjJson.Item(\"itemSummaries\").Item(1).Item(\"itemId\"): v1|145588822372|0\r\nobjJson.Item(\"itemSummaries\").Item(1).Item(\"title\"): \r\n     Refurbished ATOM Fly More Combo GPS Drone 4K Kamera 3-Achsen-Gimbal Kameradrohne\r\nobjJson.Item(\"itemSummaries\").Item(1).Item(\"leafCategoryIds\").Item(1): 179697\r\nobjJson.Item(\"itemSummaries\").Item(1).Item(\"categories\").Item(1).Item(\"categoryId\"): 179697\r\nobjJson.Item(\"itemSummaries\").Item(1).Item(\"categories\").Item(1).Item(\"categoryName\"): Kamera-Drohnen\r\nobjJson.Item(\"itemSummaries\").Item(1).Item(\"categories\").Item(2).Item(\"categoryId\"): 625\r\nobjJson.Item(\"itemSummaries\").Item(1).Item(\"categories\").Item(2).Item(\"categoryName\"): Foto & Camcorder\r\nobjJson.Item(\"itemSummaries\").Item(1).Item(\"image\").Item(\"imageUrl\"): \r\n     https:\/\/i.ebayimg.com\/images\/g\/7ssAAOSw18hlvKY6\/s-l225.jpg\r\nobjJson.Item(\"itemSummaries\").Item(1).Item(\"price\").Item(\"value\"): 309.99\r\nobjJson.Item(\"itemSummaries\").Item(1).Item(\"price\").Item(\"currency\"): EUR\r\nobjJson.Item(\"itemSummaries\").Item(1).Item(\"itemHref\"): https:\/\/api.ebay.com\/buy\/browse\/v1\/item\/v1%7C145588822372%7C0\r\nobjJson.Item(\"itemSummaries\").Item(1).Item(\"seller\").Item(\"username\"): potensic_store\r\nobjJson.Item(\"itemSummaries\").Item(1).Item(\"seller\").Item(\"feedbackPercentage\"): 99.3\r\nobjJson.Item(\"itemSummaries\").Item(1).Item(\"seller\").Item(\"feedbackScore\"): 3262\r\nobjJson.Item(\"itemSummaries\").Item(1).Item(\"seller\").Item(\"sellerAccountType\"): BUSINESS\r\nobjJson.Item(\"itemSummaries\").Item(1).Item(\"condition\"): Zertifiziert - Refurbished\r\nobjJson.Item(\"itemSummaries\").Item(1).Item(\"conditionId\"): 2000\r\nobjJson.Item(\"itemSummaries\").Item(1).Item(\"thumbnailImages\").Item(1).Item(\"imageUrl\"): \r\n     https:\/\/i.ebayimg.com\/images\/g\/7ssAAOSw18hlvKY6\/s-l1600.jpg\r\nobjJson.Item(\"itemSummaries\").Item(1).Item(\"shippingOptions\").Item(1).Item(\"shippingCostType\"): FIXED\r\nobjJson.Item(\"itemSummaries\").Item(1).Item(\"shippingOptions\").Item(1).Item(\"shippingCost\").Item(\"value\"): 0.00\r\nobjJson.Item(\"itemSummaries\").Item(1).Item(\"shippingOptions\").Item(1).Item(\"shippingCost\").Item(\"currency\"): EUR\r\nobjJson.Item(\"itemSummaries\").Item(1).Item(\"buyingOptions\").Item(1): FIXED_PRICE\r\nobjJson.Item(\"itemSummaries\").Item(1).Item(\"epid\"): 28063837524\r\nobjJson.Item(\"itemSummaries\").Item(1).Item(\"itemWebUrl\"): \r\n     https:\/\/www.ebay.de\/itm\/145588822372?_skw=drone&hash=item21e5c52164:g:7ssAAOSw18hlvKY6&amdata=enc...\r\nobjJson.Item(\"itemSummaries\").Item(1).Item(\"itemLocation\").Item(\"postalCode\"): 55***\r\nobjJson.Item(\"itemSummaries\").Item(1).Item(\"itemLocation\").Item(\"country\"): DE\r\nobjJson.Item(\"itemSummaries\").Item(1).Item(\"additionalImages\").Item(1).Item(\"imageUrl\"): \r\n     https:\/\/i.ebayimg.com\/images\/g\/GRIAAOSwzfFlvKam\/s-l225.jpg\r\n...\r\nobjJson.Item(\"itemSummaries\").Item(1).Item(\"adultOnly\"): Falsch\r\nobjJson.Item(\"itemSummaries\").Item(1).Item(\"unitPricingMeasure\"): Einheit\r\nobjJson.Item(\"itemSummaries\").Item(1).Item(\"unitPrice\").Item(\"value\"): 309.99\r\nobjJson.Item(\"itemSummaries\").Item(1).Item(\"unitPrice\").Item(\"currency\"): EUR\r\nobjJson.Item(\"itemSummaries\").Item(1).Item(\"legacyItemId\"): 145588822372\r\nobjJson.Item(\"itemSummaries\").Item(1).Item(\"availableCoupons\"): Falsch\r\nobjJson.Item(\"itemSummaries\").Item(1).Item(\"itemCreationDate\"): 2024-02-02T08:28:06.000Z\r\nobjJson.Item(\"itemSummaries\").Item(1).Item(\"topRatedBuyingExperience\"): Wahr\r\nobjJson.Item(\"itemSummaries\").Item(1).Item(\"priorityListing\"): Wahr\r\nobjJson.Item(\"itemSummaries\").Item(1).Item(\"listingMarketplaceId\"): EBAY_DE\r\nobjJson.Item(\"itemSummaries\").Item(2).Item(\"itemId\"): v1|285778132279|0<\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 2: Ausdr&uuml;cke f&uuml;r den Zugriff auf den Inhalt des JSON-Dokuments<\/span><\/b><\/p>\n<p>F&uuml;r den Titel des Artikels verwenden wir:<\/p>\n<pre><span style=\"color:blue;\">Debug.Print<\/span> objJson.Item(\"itemSummaries\").Item(1).Item(\"title\")<\/pre>\n<p>Auf &auml;hnliche Weise k&ouml;nnen wir auf die &uuml;brigen Elemente zugreifen.<\/p>\n<p>Noch spannender ist die Frage, wie wir Elemente in Schleifen durchlaufen k&ouml;nnen, die mehrmals vorkommen. Dazu schauen wir uns erst einmal an, um welche Elemente es hier geht.<\/p>\n<p>Die drei Artikel, die unser Ergebnis zur&uuml;ckliefert, k&ouml;nnen wir grunds&auml;tzlich &uuml;ber diese Ausdr&uuml;cke referenzieren:<\/p>\n<pre>objJson.Item(\"itemSummaries\").Item(1) ...\r\nobjJson.Item(\"itemSummaries\").Item(2) ...\r\nobjJson.Item(\"itemSummaries\").Item(3) ...<\/pre>\n<p>Um diese in einer Schleife zu durchlaufen, deklarieren wir eine Z&auml;hlervariable:<\/p>\n<pre><span style=\"color:blue;\">Dim <\/span>i<span style=\"color:blue;\"> As Integer<\/span><\/pre>\n<p>Au&szlig;erdem ben&ouml;tigen wir eine Variable, in der wir das jeweilige Hauptelement f&uuml;r den aktuellen Artikel speichern:<\/p>\n<pre><span style=\"color:blue;\">Dim <\/span>objItem<span style=\"color:blue;\"> As Object<\/span><\/pre>\n<p>Danach beginnen wir, die Elemente in einer <b>For&#8230;Next<\/b>-Schleife zu durchlaufen. Der erste Indexwert ist offensichtlich der Wert <b>1<\/b>. Den letzten Indexwert ermitteln wir mit dem Ausdruck <b>objJSON.Item(&#8220;itemSummaries&#8221;).Count <\/b>und erhalten die folgende <b>For&#8230;Next<\/b>-Schleife:<\/p>\n<pre>For i = 1 To objJSON.Item(\"itemSummaries\").Count\r\n     <span style=\"color:blue;\">Set<\/span> objItem = objJSON.Item(\"itemSummaries\").Item(i)\r\n     <span style=\"color:blue;\">Debug.Print<\/span> objItem.Item(\"itemId\"), _\r\n         objItem.Item(\"title\")\r\n<span style=\"color:blue;\">Next<\/span> i<\/pre>\n<p>In der Schleife referenzieren wir das aktuelle Objekt <b>objJSON.Item(&#8220;itemSummaries&#8221;).Item(i) <\/b>mit der Variablen <b>objItem <\/b>und k&ouml;nnen dar&uuml;ber bequem auf die enthaltenen Elemente zugreifen &#8211; zum Beispiel <b>objItem.Item(&#8220;itemId&#8221;) <\/b>f&uuml;r die Artikelnummer und <b>objItem.Item(&#8220;title&#8221;) <\/b>f&uuml;r die Bezeichnung des Artikels.<\/p>\n<p>Das Ergebnis sieht in diesem Beispiel wie in Bild 6 aus.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_03\/pic_461_006.png\" alt=\"Ergebnis der Abfrage mit den wichtigsten Informationen\" width=\"700\" height=\"130,3119\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 6: Ergebnis der Abfrage mit den wichtigsten Informationen<\/span><\/b><\/p>\n<p>Unsere Prozedur zum Aufruf der Funktion <b>GetItems<\/b> enth&auml;lt nun den Code aus Listing 3.<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>Test_GetItems()\r\n     <span style=\"color:blue;\">Dim <\/span>strJSON<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     <span style=\"color:blue;\">Dim <\/span>objItem<span style=\"color:blue;\"> As Object<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>i<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strResponse<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">If <\/span>GetItems(strResponse) = <span style=\"color:blue;\">True<\/span><span style=\"color:blue;\"> Then<\/span>\r\n         Inzwischenablage strResponse\r\n         <span style=\"color:blue;\">Set<\/span> objJSON = ParseJson(strResponse)\r\n         <span style=\"color:blue;\">Debug.Print<\/span> GetJSONDOM(strResponse, <span style=\"color:blue;\">True<\/span>)\r\n         For i = 1 To objJSON.Item(\"itemSummaries\").Count\r\n             <span style=\"color:blue;\">Set<\/span> objItem = objJSON.Item(\"itemSummaries\").Item(i)\r\n             <span style=\"color:blue;\">Debug.Print<\/span> objItem.Item(\"itemId\"), objItem.Item(\"title\")\r\n         <span style=\"color:blue;\">Next<\/span> i\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 3: Prozedur zum Verarbeiten der Artikel<\/span><\/b><\/p>\n<p>Aktuell geben wir nur die <b>ItemID<\/b> und den Titel aus. Spannend w&auml;re zum Beispiel, auch noch die Preise zu ermitteln. So k&ouml;nnten wir uns einen eigenen Preisalarm bauen, der alle Angebote eines bestimmten Produkts mit einem bestimmten Artikelnamen ausliest und uns dazu die aktuellen Preise liefert. Dazu schauen wir uns einfach die Ausgabe an und finden im ersten Angebot diese beiden Elemente:<\/p>\n<pre>objJson.Item(\"itemSummaries\").Item(3).Item(\"unitPrice\").Item(\"value\"): 269.99\r\nobjJson.Item(\"itemSummaries\").Item(3).Item(\"unitPrice\").Item(\"currency\"): EUR<\/pre>\n<p>In unser Beispiel k&ouml;nnen wir den Preis dann wie folgt integrieren:<\/p>\n<pre><span style=\"color:blue;\">Debug.Print<\/span> \"Preis: \" & objItem.Item(\"unitPrice\").Item(\"value\") & \" \" & objItem.Item(\"unitPrice\").Item(\"currency\")<\/pre>\n<p>Allerdings laufen wir damit in einen Fehler, denn das <b>unitPrice<\/b>-Element ist nicht in jedem Angebot enthalten.<\/p>\n<p>Wir m&uuml;ssen also pr&uuml;fen, ob dieses Element &uuml;berhaupt vorhanden ist. Das erledigen wir wie folgt:<\/p>\n<pre><span style=\"color:blue;\">Set<\/span> objUnitPrice = Nothing\r\nOn Error Resume <span style=\"color:blue;\">Next<\/span>\r\n<span style=\"color:blue;\">Set<\/span> objUnitPrice = objItem.Item(\"unitPrice\")\r\n<span style=\"color:blue;\">On Error GoTo<\/span> 0\r\n<span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> objUnitPrice Is Nothing<span style=\"color:blue;\"> Then<\/span>\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"Preis: \" _\r\n         & objItem.Item(\"unitPrice\").Item(\"value\") & \" \" _\r\n         & objItem.Item(\"unitPrice\").Item(\"currency\")\r\n<span style=\"color:blue;\">End If<\/span><\/pre>\n<p>Damit geben wir zumindest die <b>unitPrice<\/b>-Angaben f&uuml;r die Angebot aus, wo diese vorhanden sind, und erhalten keine Fehler. Aber warum haben manche Angebote keinen <b>unitPrice<\/b>?<\/p>\n<h2>Dokumentation nach unitPrice durchsuchen<\/h2>\n<p>Um dies herauszufinden, k&ouml;nnen wir die Dokumentation unter dem folgenden Link nutzen:<\/p>\n<pre>https:\/\/developer.ebay.com\/api-docs\/buy\/browse\/resources\/item_summary\/methods\/search<\/pre>\n<p>Hier scrollen wir nach unten zum Bereich <b>Output<\/b>. Unter <b>Response payload <\/b>finden wir alle m&ouml;glichen Elemente der Antwort f&uuml;r die Anfrage.<\/p>\n<p>Im Screenshot aus Bild 7 haben wir bereits die Stelle zum <b>unitPrice <\/b>herausgesucht. Hier sehen wir allerdings nur die Struktur und die verschiedenen Elemente samt Einheit und in manchen F&auml;llen noch Beispiele f&uuml;r die Werte, wie bei den W&auml;hrungen zu sehen.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_03\/pic_461_007.png\" alt=\"Durchsuchen des Outputs einer Abfrage in der Dokumentation\" width=\"700\" height=\"390,3528\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 7: Durchsuchen des Outputs einer Abfrage in der Dokumentation<\/span><\/b><\/p>\n<p>Um mehr zu erfahren, k&ouml;nnen wir die einzelnen Elemente auch noch anklicken und gelangen zu einem weiteren Bereich der Dokumentation f&uuml;r diese Funktion auf der gleichen Seite, wo wir detaillierte Informationen finden (siehe Bild 8).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_03\/pic_461_008.png\" alt=\"Beschreibung der einzelnen Elemente der Antwort\" width=\"700\" height=\"390,9603\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 8: Beschreibung der einzelnen Elemente der Antwort<\/span><\/b><\/p>\n<p>Hier k&ouml;nnen wir unter <b>Occurrence<\/b> gleich entnehmen, dass es sich bei <b>unitPrice <\/b>um ein optionales Element handelt.<\/p>\n<p>In der Erkl&auml;rung erfahren wir au&szlig;erdem, dass der Preis pro Einheit nur dazu da ist, dass man die Einzelpreise gut vergleichen kann.<\/p>\n<p>Steigen wir tiefer in die Dokumentation ein, sehen wir, dass es f&uuml;r den Preis ohnehin noch das Feld <b>Price<\/b> gibt, das wir ebenfalls auslesen k&ouml;nnen. Also &auml;ndern wir unseren Code wie folgt:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>Test_GetItems()\r\n     ...\r\n     <span style=\"color:blue;\">Dim <\/span>objPrice<span style=\"color:blue;\"> As Object<\/span>\r\n     ...\r\n    <span style=\"color:blue;\">If <\/span>GetItems(strResponse) = <span style=\"color:blue;\">True<\/span><span style=\"color:blue;\"> Then<\/span>\r\n         Inzwischenablage strResponse\r\n         <span style=\"color:blue;\">Set<\/span> objJSON = ParseJson(strResponse)\r\n         For i = 1 To objJSON.Item(\"itemSummaries\").Count\r\n             <span style=\"color:blue;\">Set<\/span> objItem = _\r\n                 objJSON.Item(\"itemSummaries\").Item(i)\r\n             <span style=\"color:blue;\">Debug.Print<\/span> objItem.Item(\"itemId\"), _\r\n                 objItem.Item(\"title\")\r\n             <span style=\"color:blue;\">Set<\/span> objPrice = objItem.Item(\"price\")\r\n             <span style=\"color:blue;\">Debug.Print<\/span> \"Preis: \" _\r\n                 & objPrice.Item(\"value\") & \" \" _\r\n                 & objPrice.Item(\"currency\")\r\n         <span style=\"color:blue;\">Next<\/span> i\r\n     <span style=\"color:blue;\">End If<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Damit erhalten wir beispielsweise:<\/p>\n<pre>v1|145588822372|0           Refurbished ATOM Fly More Combo GPS Drone 4K Kamera 3-Achsen-Gimbal Kameradrohne\r\nPreis: 289.99 EUR\r\nv1|385601774390|0           Parrot AR Drone 2.0 Quadcopter 720p HD Kamera Drohne Schwarz\r\nPreis: 34.99 EUR\r\nv1|285778132279|0           Potensic ATOM SE GPS Drohne mit 4K Kamera Drone 4KM FPV &Uuml;bertragung Quadrocopter\r\nPreis: 269.99 EUR<\/pre>\n<h2>Parameter der search-Funktion<\/h2>\n<p>Bisher haben wir nur die beiden Parameter <b>q<\/b> und <b>limit <\/b>verwendet. Die Funktion bietet aber noch einige weitere Parameter, und auch zu den bisher verwendeten Parametern gibt es noch weitere Erl&auml;uterungen. Eine &Uuml;bersicht der Parameter finden wir in der Dokumentation wie in Bild 9.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_03\/pic_461_009.png\" alt=\"Parameter der search-Funktion\" width=\"599,6265\" height=\"308,404\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 9: Parameter der search-Funktion<\/span><\/b><\/p>\n<p>Schauen wir uns die einige wichtige Parameter an:<\/p>\n<ul>\n<li><b>q<\/b>: Dient zur Angabe des Suchbegriffs. Man kann einen oder mehrere Suchbegriffe angeben. Wenn man mehr als einen Suchbegriff angibt, die mit <b>UND <\/b>verkn&uuml;pft werden sollen, m&uuml;ssen diese durch ein Leerzeichen getrennt werden, zum Beispiel: <b>Apple iPhone 512<\/b>. Dies liefert nur Angebote, die alle Suchbegriffe enthalten. Wenn die Suchbegriffe durch <b>ODER <\/b>verkn&uuml;pft werden sollen, geben wir diese in Klammern eingefasst und durch Kommata getrennt an, zum Beispiel: <b>(Apple, iPhone, iPad)<\/b>. Dieser Parameter ist  optional, man kann alternativ auch <b>gtin <\/b>oder <b>epid <\/b>angeben.<\/li>\n<li><b>gtin<\/b>: F&uuml;r diesen Parameter k&ouml;nnen wir die sogenannte <b>Global Trade Item Number <\/b>angeben. Das ist ein 14-stelliger Code, der hier genauer erl&auml;utert wird: <b>https:\/\/www.gtin.info\/<\/b>. Auch diesen k&ouml;nnen wir zur Suche verwenden. Allerdings haben wir damit keine Treffer landen k&ouml;nnen.<\/li>\n<li><b>charity_ids<\/b>: nur in USA und UK unterst&uuml;tzt<\/li>\n<li><b>fieldgroups<\/b>: Gibt an, wie umfangreich die gelieferten Ergebnisse aussehen sollen. Standard ist <b>MATCHING_ITEMS <\/b>und entspricht den bisher beschriebenen Ergebnissen. Mit weiteren Schl&uuml;sselw&ouml;rtern k&ouml;nnen wir bestimmte zus&auml;tzliche Informationen in das Suchergebnis ein schlie&szlig;en. Alle m&ouml;glichen Informationen erhalten wir mit <b>FULL<\/b>. F&uuml;r genaue Informationen siehe Dokumentation.<\/li>\n<li><b>auto_correct<\/b>: Gibt an, ob eBay automatisch Rechtschreibfehler oder Tippfehler in der Suchabfrage finden soll. Dazu m&uuml;ssen wir diesem Parameter den Wert <b>KEYWORD <\/b>&uuml;bergeben. Achtung: Das ist kein Platzhalter, sondern gibt an, dass die mit dem Parameter <b>q <\/b>&uuml;bergebenen Keywords auf potenzielle Rechtschreibfehler untersucht werden sollen.<\/li>\n<li><b>category_ids<\/b>: Hier k&ouml;nnen wir eine kommaseparierte Liste von Kategorienummern angeben, auf die wir die Suche konzentrieren wollen. Dazu ben&ouml;tigt man allerdings erst einmal die Kategorienummern. Wie wir diese erhalten, zeigen wir in einem weiteren Artikel.<\/li>\n<li><b>filter<\/b>: Hier k&ouml;nnen wir gezielt Filterausdr&uuml;cke f&uuml;r verschiedene Eigenschaften angeben. So l&auml;sst sich beispielsweise der Preis einschr&auml;nken (mit <b>filter=price:[1..100] <\/b>beispielsweise auf einen Preis zwischen einem und 100 Euro, mit <b>filter=conditionIs:{1000,3000} <\/b>auf Zust&auml;nde wie neu oder gebraucht). Beim Filtern nach einem Preisbereich sollte man auch die W&auml;hrung noch angeben, beispielsweise <b>price:[1..100],priceCurrency:EUR<\/b>. Mehrere Filter k&ouml;nnen wir durch Kommata getrennt aneinanderh&auml;ngen.<\/li>\n<li><b>sort<\/b>: Hiermit k&ouml;nnen wir nach verschiedenen Kriterien sortieren, zum Beispiel mit <b>sort=price <\/b>aufsteigend nach dem Preis, mit <b>sort=price desc <\/b>absteigend nach dem Preis.<\/li>\n<li><b>limit<\/b>: Damit legen wir die Anzahl der zur&uuml;ckgegebenen Artikel pro Antwort fest. Beispiel: <b>limit=100<\/b>. Standard ist <b>50<\/b>.<\/li>\n<li><b>offset<\/b>: Gibt an, ab welcher Position die Suchergebnisse geliefert werden sollen. Kombiniert mit <b>limit <\/b>k&ouml;nnen wir so in einer ersten Abfrage die ersten 50 Elemente erhalten und mit <b>offset=51 <\/b>dann die n&auml;chsten 50 und so weiter.<\/li>\n<li><b>aspect_filter<\/b>: Hiermit lassen sich eBay-spezifische Eigenschaften filtern. Beispiel: <b>aspect_filter=Brand:{Apple}<\/b>.<\/li>\n<li><b>epid<\/b>: Liefert nur Produkte, die eine spezielle eBay-Artikel-ID aufweisen.<\/li>\n<\/ul>\n<h2>Suche parametrisieren<\/h2>\n<p>Wenn Du diese Parameter nutzen m&ouml;chtest, sind jeweils die folgenden Schritte durchzuf&uuml;hren:<\/p>\n<ul>\n<li>Du erweiterst die Funktion <b>GetItems <\/b>um den entsprechenden Parameter, damit Du diesen &uuml;ber die aufrufende Prozedur &uuml;bergeben kannst. Am besten verwendest Du hier optionale Parameter, so wie wir es mit den ersten Parametern auch erledigt haben.<\/li>\n<li>Du passt den Aufruf der Funktion <b>GetItems <\/b>so an, dass der neue Parameter &uuml;bergeben wird.<\/li>\n<li>Du f&uuml;gst der Funktion <b>GetItems<\/b> jeweils einen Abschnitt wie den folgenden hinzu:<\/li>\n<\/ul>\n<pre>...\r\n<span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> <span style=\"color:blue;\">Len<\/span>(strPARAMETER) = 0<span style=\"color:blue;\"> Then<\/span>\r\n     strParameters = strParameters & \"&PARAMETERNAME=\" _\r\n         & strPARAMETER\r\n<span style=\"color:blue;\">End If<\/span>\r\n...<\/pre>\n<p>Wir pr&uuml;fen hier also, ob der Parameter vorhanden ist und falls ja, h&auml;ngen wir diesen an die Liste der Parameter an.<\/p>\n<h2>Fehlermeldungen besser verarbeiten<\/h2>\n<p>Wir haben die Funktion <b>GetItems<\/b> um die R&uuml;ckgabe der Fehlermeldung erweitert, damit wir im Fehlerfall direkt entsprechende Informationen erhalten.<\/p>\n<p>Die Funktion f&uuml;r den Testaufruf haben wir wie folgt erweitert:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>Test_GetItems()\r\n     ...\r\n     <span style=\"color:blue;\">Dim <\/span>strMessage<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>lngStatus<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strStatustext<span style=\"color:blue;\"> As String<\/span>\r\n     ...\r\n     If GetItems(strQ, strGTIN, bolAutoCorrect, _\r\n             strResponse, strMessage, lngStatus, _\r\n             strStatustext) = <span style=\"color:blue;\">True<\/span> Then\r\n         ...\r\n     <span style=\"color:blue;\">Else<\/span>\r\n         <span style=\"color:blue;\">MsgBox<\/span> \"Fehler beim Aufruf.\" & <span style=\"color:blue;\">vbCrLf<\/span> _\r\n             & \"Status: \" & lngStatus & <span style=\"color:blue;\">vbCrLf<\/span> _\r\n             & \"Statusmeldung: \" & strStatustext _\r\n             & <span style=\"color:blue;\">vbCrLf<\/span> _\r\n             & \"Fehler: \" & strMessage\r\n     <span style=\"color:blue;\">End If<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Wir haben also die drei Parameter <b>strMessage<\/b>, <b>lngStatus <\/b>und <b>strStatusmessage <\/b>deklariert und &uuml;bergeben diese an <b>GetItems<\/b>. Au&szlig;erdem fragen wir nun den R&uuml;ckgabewert von <b>GetItems <\/b>ab. Damit wir die gew&uuml;nschten Werte erhalten, passen wir <b>GetItems <\/b>wie folgt an:<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>GetItems(<span style=\"color:blue;\">Optional<\/span> strQ<span style=\"color:blue;\"> As String<\/span>, _\r\n         <span style=\"color:blue;\">Optional<\/span> strGTIN<span style=\"color:blue;\"> As String<\/span>, _\r\n         <span style=\"color:blue;\">Optional<\/span> bolAutoCorrect<span style=\"color:blue;\"> As Boolean<\/span>, _\r\n         <span style=\"color:blue;\">Optional<\/span> strResponse<span style=\"color:blue;\"> As String<\/span>, _\r\n         <span style=\"color:blue;\">Optional<\/span> strMessage<span style=\"color:blue;\"> As String<\/span>, _\r\n         <span style=\"color:blue;\">Optional<\/span> lngStatus<span style=\"color:blue;\"> As Long<\/span>, _\r\n         <span style=\"color:blue;\">Optional<\/span> strStatustext<span style=\"color:blue;\"> As String<\/span>)<span style=\"color:blue;\"> As Boolean<\/span>\r\n     ...\r\n     objXMLHTTP.send\r\n     strResponse = objXMLHTTP.responseText\r\n     Select Case objXMLHTTP.status\r\n         <span style=\"color:blue;\">Case <\/span>200\r\n             GetItems = <span style=\"color:blue;\">True<\/span>\r\n         <span style=\"color:blue;\">Case Else<\/span>\r\n             <span style=\"color:blue;\">Set<\/span> objJSON = ParseJson(strResponse)\r\n             strMessage = objJSON.Item(\"errors\").Item(1). _\r\n                 Item(\"message\")\r\n             lngStatus = objXMLHTTP.status\r\n             strStatustext = objXMLHTTP.statusText\r\n             GetItems = <span style=\"color:blue;\">False<\/span>\r\n     <span style=\"color:blue;\">End Select<\/span>\r\n     <span style=\"color:blue;\">Set<\/span> objXMLHTTP = Nothing\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p>Wir deklarieren hier die Parameter <b>strMessage<\/b>, <b>lngStatus <\/b>und <b>lngStatusmessage<\/b>. Diese f&uuml;llen wir, falls <b>status <\/b>nicht den Wert <b>200 <\/b>liefert, mit den Werten der Eigenschaften <b>status<\/b> und <b>statusText <\/b>sowie mit dem Ergebnis der JSON-Response. Au&szlig;erdem geben wir dann den Wert <b>False <\/b>als Funktionsergebnis zur&uuml;ck.<\/p>\n<h2>Vollst&auml;ndige Funktion zum Aufrufen von GetItems<\/h2>\n<p>In Listing 4 siehst Du noch einmal das vollst&auml;ndige Listing f&uuml;r den Aufruf der Funktion <b>GetItems <\/b>namens <b>SearchItems<\/b>. Diese erwartet den Suchbegriff als Parameter.<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>SearchItems(strSearch<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     <span style=\"color:blue;\">Dim <\/span>i<span style=\"color:blue;\"> As Long<\/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>bolAutoCorrect<span style=\"color:blue;\"> As Boolean<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strItemID<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strTitle<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strPrice<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>curPrice<span style=\"color:blue;\"> As Currency<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>db<span style=\"color:blue;\"> As <\/span>DAO.Database\r\n     <span style=\"color:blue;\">Set<\/span> db = CurrentDb\r\n     \r\n     db.Execute \"DELETE FROM tblItems\", dbFailOnError\r\n     bolAutoCorrect = <span style=\"color:blue;\">True<\/span>\r\n     <span style=\"color:blue;\">If <\/span>GetItems(strSearch, \"\", bolAutoCorrect, strResponse) = <span style=\"color:blue;\">True<\/span><span style=\"color:blue;\"> Then<\/span>\r\n         Inzwischenablage strResponse\r\n         <span style=\"color:blue;\">Set<\/span> objJSON = ParseJson(strResponse)\r\n         <span style=\"color:blue;\">Debug.Print<\/span> GetJSONDOM(strResponse, <span style=\"color:blue;\">True<\/span>)\r\n         <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> objJSON.Item(\"total\") = 0<span style=\"color:blue;\"> Then<\/span>\r\n             For i = 1 To objJSON.Item(\"itemSummaries\").Count\r\n                 strItemID = objJSON.Item(\"itemSummaries\").Item(i).Item(\"itemId\")\r\n                 <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Left<\/span>(strItemID, 3) = \"v1|\"<span style=\"color:blue;\"> Then<\/span>\r\n                     strItemID = <span style=\"color:blue;\">Mid<\/span>(strItemID, 4)\r\n                     <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> <span style=\"color:blue;\">InStr<\/span>(1, strItemID, \"|\") = 0<span style=\"color:blue;\"> Then<\/span>\r\n                         strItemID = <span style=\"color:blue;\">Left<\/span>(strItemID, <span style=\"color:blue;\">InStr<\/span>(1, strItemID, \"|\") - 1)\r\n                     <span style=\"color:blue;\">End If<\/span>\r\n                 <span style=\"color:blue;\">End If<\/span>\r\n                 \r\n                 strTitle = objJSON.Item(\"itemSummaries\").Item(i).Item(\"title\")\r\n                 strPrice = objJSON.Item(\"itemSummaries\").Item(i).Item(\"price\").Item(\"value\")\r\n                 curPrice = CCur(<span style=\"color:blue;\">Replace<\/span>(strPrice, \".\", \",\"))\r\n                 db.Execute \"INSERT INTO tblItems(ItemID, Title, Price) VALUES(''\" & strItemID & \"'', ''\" & strTitle _\r\n                     & \"'', \" & <span style=\"color:blue;\">Replace<\/span>(curPrice, \",\", \".\") & \")\", dbFailOnError\r\n             <span style=\"color:blue;\">Next<\/span> i\r\n         <span style=\"color:blue;\">Else<\/span>\r\n             <span style=\"color:blue;\">MsgBox<\/span> \"Keine Angebote gefunden.\"\r\n         <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">Else<\/span>\r\n         <span style=\"color:blue;\">MsgBox<\/span> \"Fehler beim Aufruf.\" & <span style=\"color:blue;\">vbCrLf<\/span> & \"Status: \" & lngStatus & <span style=\"color:blue;\">vbCrLf<\/span> & \"Statusmeldung: \" & strStatustext _\r\n             & <span style=\"color:blue;\">vbCrLf<\/span> & \"Fehler: \" & strMessage\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 4: Die Funktion SearchItems<\/span><\/b><\/p>\n<p>Sie soll auch von einem Formular aus aufgerufen werden, das wir nachfolgend vorstellen, und die Ergebnis in eine Tabelle namens <b>tblItems <\/b>schreiben. Diese Tabelle sieht im Entwurf wie in Bild 10 aus.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_03\/pic_461_010.png\" alt=\"Tabelle zum Speichern der Suchergebnisse\" width=\"700\" height=\"145,7081\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 10: Tabelle zum Speichern der Suchergebnisse<\/span><\/b><\/p>\n<p>Die Funktion l&ouml;scht beim Starten der Suche alle in der Tabellen enthaltenen Datens&auml;tze.<\/p>\n<p>Den Parameter <b>bolAutoCorrect <\/b>stellen wir auf <b>True <\/b>ein, damit wir auch zu unscharfen Begriffen Suchergebnisse erhalten. Danach folgt bereits der Aufruf der Funktion <b>GetItems<\/b>, wobei wir mit <b>strSearch <\/b>den Suchbegriff, <b>bolAutoCorrect <\/b>sowie einige leere Variablen f&uuml;r die R&uuml;ckgabewerte als Parameter &uuml;bergeben. Das Ergebnis aus <b>strResponse <\/b>speichern wir in der Zwischenablage, sodass wir es gegebenenfalls sp&auml;ter ansehen k&ouml;nnen. Die Funktion <b>GetItems <\/b>gibt <b>True <\/b>zur&uuml;ck, wenn die Suche erfolgreich war. In diesem Fall tritt der <b>If<\/b>-Teil der <b>If&#8230;Then<\/b>-Bedingung ein.<\/p>\n<p>Wir wandeln das JSON-Ergebnis aus <b>strResponse <\/b>in ein Objekt um. Au&szlig;erdem geben wir die Ausdr&uuml;cke, mit der wir auf die Elemente in diesem Objekt zugreifen k&ouml;nnen, im Direktbereich aus, damit wir diese gegebenenfalls noch anpassen oder zum Code hinzuf&uuml;gen, wenn noch weitere Informationen au&szlig;er <b>ID<\/b>, <b>Titel <\/b>und <b>Preis <\/b>des Angebots ben&ouml;tigt werden.<\/p>\n<p>Danach pr&uuml;fen wir den Wert des Elements <b>total<\/b>, das die Anzahl der Fundstellen zur&uuml;ckgibt. Ist dieses nicht <b>0<\/b>, durchlaufen wir in einer <b>For&#8230;Next<\/b>-Schleife die Elemente f&uuml;r alle zur&uuml;ckgelieferten Suchergebnisse.<\/p>\n<p>Hier tragen wir f&uuml;r jedes Element die Werte der Eigenschaften <b>itemID<\/b>, <b>title <\/b>und <b>price <\/b>in entsprechende Variablen ein. F&uuml;r <b>itemID <\/b>wird gegebenenfalls ein Wert wie der folgende zur&uuml;ckgegeben:<\/p>\n<pre>v1|1234567890|1212121212<\/pre>\n<p>Aus diesem lesen wir die erste ID aus. Den Titel &uuml;bernehmen wir direkt. Beim Preis, der zum Beispiel <b>1.23 <\/b>lautet, ersetzen wir zuerst den Punkt als Dezimaltrenner durch das Komma und konvertieren dann in <b>Currency<\/b>.<\/p>\n<p>Dann legen wir einen neuen Datensatz mit den entsprechenden Werten an.<\/p>\n<p>Sollte der Aufruf nicht erfolgreich sein, wird der <b>Else<\/b>-Teil der Bedingung ausgef&uuml;hrt. Hier greifen wir auf die mit den Parametern <b>strStatus<\/b>, <b>strStatustext <\/b>und <b>strMessage <\/b>gelieferten Informationen zu und geben eine Meldung aus, welche diese zusammenstellt.<\/p>\n<h2>Vollst&auml;ndige Funktion GetItems<\/h2>\n<p>In Listing 5 sehen wir noch einmal die vollst&auml;ndige Version der Funktion <b>GetItems<\/b>, wie wir sie von der zuvor beschriebenen Funktion aus aufrufen k&ouml;nnen.<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>GetItems(<span style=\"color:blue;\">Optional<\/span> strQ<span style=\"color:blue;\"> As String<\/span>, <span style=\"color:blue;\">Optional<\/span> strGTIN<span style=\"color:blue;\"> As String<\/span>, <span style=\"color:blue;\">Optional<\/span> bolAutoCorrect<span style=\"color:blue;\"> As Boolean<\/span>, _\r\n         <span style=\"color:blue;\">Optional<\/span> strResponse<span style=\"color:blue;\"> As String<\/span>, <span style=\"color:blue;\">Optional<\/span> strMessage<span style=\"color:blue;\"> As String<\/span>, <span style=\"color:blue;\">Optional<\/span> lngStatus<span style=\"color:blue;\"> As Long<\/span>, _\r\n         <span style=\"color:blue;\">Optional<\/span> strStatustext<span style=\"color:blue;\"> As String<\/span>)<span style=\"color:blue;\"> As Boolean<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>objXMLHTTP<span style=\"color:blue;\"> As <\/span>MSXML2.XMLHTTP60\r\n     <span style=\"color:blue;\">Dim <\/span>strURL<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strParameters<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strOAuthToken<span style=\"color:blue;\"> As String<\/span>\r\n     strURL = \"https:\/\/api.ebay.com\/buy\/browse\/v1\/item_summary\/search\"\r\n     <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> <span style=\"color:blue;\">Len<\/span>(strQ) = 0<span style=\"color:blue;\"> Then<\/span>\r\n         strParameters = strParameters & \"&q=\" & URLEncode(strQ)\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> <span style=\"color:blue;\">Len<\/span>(strGTIN) = 0<span style=\"color:blue;\"> Then<\/span>\r\n         strParameters = strParameters & \"&gtin=\" & strGTIN\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">If <\/span>bolAutoCorrect = <span style=\"color:blue;\">True<\/span><span style=\"color:blue;\"> Then<\/span>\r\n         strParameters = strParameters & \"\"\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     \r\n     <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> <span style=\"color:blue;\">Len<\/span>(strParameters) = 0<span style=\"color:blue;\"> Then<\/span>\r\n         strURL = strURL & \"?\" & <span style=\"color:blue;\">Mid<\/span>(strParameters, 2)\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     strOAuthToken = \"Bearer \" & GetAppSetting(\"AppToken\")\r\n     <span style=\"color:blue;\">Set<\/span> objXMLHTTP = <span style=\"color:blue;\">New<\/span> MSXML2.XMLHTTP60\r\n     objXMLHTTP.Open \"GET\", strURL, <span style=\"color:blue;\">False<\/span>\r\n     objXMLHTTP.setRequestHeader \"Authorization\", strOAuthToken\r\n     objXMLHTTP.setRequestHeader \"X-EBAY-C-MARKETPLACE-ID\", \"EBAY_DE\"\r\n     objXMLHTTP.setRequestHeader \"X-EBAY-C-ENDUSERCTX\", \"ffiliateCampaignId=&lt;ePNCampaignId&gt;,affiliateReferenceId=&lt;referenceId&gt;\"\r\n     objXMLHTTP.send\r\n     strResponse = objXMLHTTP.responseText\r\n     Select Case objXMLHTTP.status\r\n         <span style=\"color:blue;\">Case <\/span>200\r\n             GetItems = <span style=\"color:blue;\">True<\/span>\r\n         <span style=\"color:blue;\">Case Else<\/span>\r\n             <span style=\"color:blue;\">Set<\/span> objJSON = ParseJson(strResponse)\r\n             strMessage = objJSON.Item(\"errors\").Item(1).Item(\"message\")\r\n             lngStatus = objXMLHTTP.status\r\n             strStatustext = objXMLHTTP.statusText\r\n             GetItems = <span style=\"color:blue;\">False<\/span>\r\n     <span style=\"color:blue;\">End Select<\/span>\r\n     <span style=\"color:blue;\">Set<\/span> objXMLHTTP = Nothing\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 5: Die Funktion GetItems in der neuen Version<\/span><\/b><\/p>\n<p>Zu den Parametern sind solche hinzugekommen, mit denen wir Informationen &uuml;ber das Ergebnis beim Fehlschlagen des Aufrufs zur&uuml;ckgeben.<\/p>\n<p>Wir stellen im Folgenden die URL aufgrund der &uuml;bergebenen Parameter zusammen. Danach f&uuml;hren wir den Aufruf durch. Ein Unterschied zu der zu Beginn vorgestellten Version ist, dass wir zur&uuml;ckgegebene <b>status<\/b>-Werte, die sich von <b>200 <\/b>unterscheiden und die f&uuml;r einen fehlerhaften Aufruf stehen, anders behandeln. In diesem Fall weisen wir den R&uuml;ckgabeparametern <b>strMessage<\/b>, <b>lngStatus <\/b>und <b>strStatustext <\/b>die entsprechenden Werte zu. Den Wert f&uuml;r <b>strMessage <\/b>lesen wir dabei aus dem Element <b>errors\/message <\/b>der JSON-R&uuml;ckgabe aus.<\/p>\n<h2>Formular f&uuml;r die Ausgabe der Ergebnisse<\/h2>\n<p>Um die Funktionen komfortable zu testen, f&uuml;gen wir der Anwendung noch ein Formular namens <b>frmItemsSuchen <\/b>hinzu. Dieses sieht im Entwurf wie in Bild 11 aus.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_03\/pic_461_011.png\" alt=\"Entwurf des Formulars frmItemsSuchen\" width=\"549,6265\" height=\"494,334\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 11: Entwurf des Formulars frmItemsSuchen<\/span><\/b><\/p>\n<p>Hier sehen wir ein Textfeld zur Eingabe des Suchbegriffs sowie zwei Schaltfl&auml;chen. Au&szlig;erdem haben wir ein Unterformular, dass den Inhalt der Tabelle <b>tblItems <\/b>anzeigt.<\/p>\n<p>Die Schaltfl&auml;che <b>cmdSucheStarten <\/b>l&ouml;st die folgende Prozedur aus:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>cmdSucheStarten_Click()\r\n     <span style=\"color:blue;\">Dim <\/span>strSearch<span style=\"color:blue;\"> As String<\/span>\r\n     strSearch = Nz(Me.txtSuche, \"\")\r\n     <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> <span style=\"color:blue;\">Len<\/span>(strSearch) = 0<span style=\"color:blue;\"> Then<\/span>\r\n         <span style=\"color:blue;\">Call<\/span> SearchItems(strSearch)\r\n         Me.sfmItemsSuchen.Form.Requery\r\n     <span style=\"color:blue;\">Else<\/span>\r\n         <span style=\"color:blue;\">MsgBox<\/span> \"Bitte geben Sie einen Suchbegriff ein.\", _\r\n             vbOKOnly + vbExclamation, \"Suchbegriff fehlt\"\r\n         Me.txtSuche.SetFocus\r\n     <span style=\"color:blue;\">End If<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Wenn ein Suchbegriff in das Textfeld <b>txtSuche <\/b>eingegeben wurde, ruft die Prozedur die Funktion <b>SearchItems <\/b>mit diesem Suchbegriff als Parameter auf. Nach der Suche und dem Eintragen der gefundenen Angebote in die Tabelle werden diese im Unterformular angezeigt.<\/p>\n<p>Ein Klick auf die Schaltfl&auml;che <b>cmdInEBayAnzeigen <\/b>ruft die folgende Prozedur auf, die das aktuell markierte Angebot direkt in eBay im Browser anzeigt.<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>cmdInEBayAnzeigen_Click()\r\n     <span style=\"color:blue;\">Dim <\/span>strItemID<span style=\"color:blue;\"> As String<\/span>\r\n     strItemID = _\r\n         Me.sfmItemsSuchen.Form.ItemID\r\n     FollowHyperlink _        \"https:\/\/www.ebay.de\/itm\/\" _\r\n         & strItemID\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Das Formular sehen wir in Bild 12.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_03\/pic_461_012.png\" alt=\"Formularansicht des Formulars frmItemsSuchen\" width=\"549,6265\" height=\"249,3829\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 12: Formularansicht des Formulars frmItemsSuchen<\/span><\/b><\/p>\n<h2>Zusammenfassung und Ausblick<\/h2>\n<p>Damit haben wir unsere eBay-L&ouml;sung um eine Funktion zum Abfragen von Angeboten erweitert und auch noch ein Formular zum Ausprobieren der Funktionen hinzugef&uuml;gt. <\/p>\n<p>In weiteren Teil sehen wir uns an, wie die Kategorien von eBay aufgebaut sind und wie wir diese auslesen und als weiteres Kriterium f&uuml;r die Suche nutzen k&ouml;nnen. Au&szlig;erdem ben&ouml;tigen wir Kategorien, um selbst Artikel per VBA einstellen zu k&ouml;nnen.<\/p>\n<p>Schlie&szlig;lich werden wir in einem weiteren Artikel zeigen, wie man ein neues Angebot bei eBay einstellt.<\/p>\n<h2>Downloads zu diesem Beitrag<\/h2>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>eBayPerVBASteuern.accdb<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/5BB674DD-5DD6-4510-A071-F4D4F63A3209\/vbe_461.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Im ersten Teil der Artikelreihe zum Thema Steuerung von eBay mit VBA haben wir gezeigt, wie man einen Entwickler-Account anlegt, eine neue Anwendung bei eBay erstellt, grundlegende Zugriffsdaten holt und die f&uuml;r die Authentifizierung im Kontext eines bestimmten Benutzerkontos notwendigen Informationen holt &#8211; hier speziell das Authentifizierungstoken. Damit haben wir die Basis geschaffen, um per VBA auf die Rest API von eBay zuzugreifen. Damit fahren wir in diesem Teil fort: Wir wollen den grundlegenden Zugriff auf die Rest-API von eBay herstellen und verwenden dazu einfache Beispiele. Wie sich zeigt, gibt es zwei verschiedene Kontexte, in denen wir hier arbeiten, den Anwendungs- und den Benutzerkontext. Beide beschreiben wir in diesem Artikel.<\/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":[662025,66032025,44000035,44000027,44000012],"tags":[],"yst_prominent_words":[],"class_list":["post-55000461","post","type-post","status-publish","format-standard","hentry","category-662025","category-66032025","category-COMDLLs_programmieren","category-Excel_programmieren","category-Interaktiv"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000461","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=55000461"}],"version-history":[{"count":0,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000461\/revisions"}],"wp:attachment":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/media?parent=55000461"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/categories?post=55000461"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/tags?post=55000461"},{"taxonomy":"yst_prominent_words","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/yst_prominent_words?post=55000461"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}