{"id":55000634,"date":"2008-10-01T00:00:00","date_gmt":"2021-02-11T21:23:21","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=634"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"Amazon_Webservices_per_VBA_nutzen","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/Amazon_Webservices_per_VBA_nutzen\/","title":{"rendered":"Amazon Webservices per VBA nutzen"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg05.met.vgwort.de\/na\/58c80949f7e64f9d8797b383a80d6488\" width=\"1\" height=\"1\" alt=\"\"><\/p>\n<p><b>Der Amazon Associates Web Service bietet den Zugriff auf die in Amazon gespeicherten Produktdaten an. Dazu geh&ouml;ren l&auml;ngst nicht mehr nur B&uuml;cher, CDs und DVDs, sondern auch Elektroger&auml;te, Kleidung und vieles mehr. Der Zugriff darauf ist nicht nur interessant, wenn man Amazon-Partner ist und die Artikel gegen Provision auf seiner eigenen Webseite feilbietet, sondern auch zum reinen automatischen Einlesen von Produktdaten &#8211; zum Beispiel f&uuml;r die ebenfalls in dieser Ausgabe vorgestellte B&uuml;cherverwaltung.<\/b><\/p>\n<p class=\"zwischen-berschrift-oberer-spaltenrand\">Webservices<\/p>\n<p>Webservices sind Anwendungen, die man &uuml;ber eine URL ansprechen kann und &uuml;ber die man eine Anfrage schickt, um eine bestimmte Information zu erhalten. Prinzipiell kann man diese mit einer Internetseite im Browser vergleichen: Sie tragen die URL in das entsprechende Textfeld ein und erhalten als Antwort eine Internetseite. Webservices sind nun noch eine Stufe einfacher geschnitzt, denn ihre Antwort kommt nicht in Form einer formatierten Webseite, sondern als XML-Dokument, das man noch auswerten muss. Auch ist die Anfrage keine einfache URL, sondern sie enth&auml;lt noch weitere Parameter, welche die eigentliche Anfrage ausmachen. Auch f&uuml;r das Zusammenstellen und Versenden der Anfrage sowie das Empfangen und Auswerten der Antwort muss man selbst durch geeigneten Code Sorge tragen.<\/p>\n<p>Es gibt verschiedene M&ouml;glichkeiten, eine Anfrage zu formulieren; im Falle des Amazon Associates Web Services in Kombination mit Access\/VBA geschieht dies am einfachsten &uuml;ber eine sogenannte REST-Anfrage (Representational State Transfer). Dies bedeutet, dass die Parameter einfach an die URL des Webservice angeh&auml;ngt werden. Die Antwort erh&auml;lt man von Amazon dann in Form eines XML-Dokuments.<\/p>\n<p><b>Amazon Web Services<\/b><\/p>\n<p>Den einfachsten Einstieg in die Amazon Webservices finden Sie &uuml;ber das deutsche Internetangebot unter <b>http:\/\/www.amazon.de<\/b>, wo Sie links im Bereich <b>Entdecken <\/b>einen Eintrag <b>F&uuml;r Entwickler|Amazon Web Services <\/b>finden. Der deutschsprachige Segen findet hier allerdings ein abruptes Ende, denn bereits der Verweis zum Web Services Software Developer&euro;s Kit (<b>http:\/\/www.amazon.com\/webservices<\/b>) f&uuml;hrt zu einer englischsprachigen Seite, die einen &uuml;berdies nicht gerade mit der Nase auf den Download st&ouml;&szlig;t.<\/p>\n<p>Das ist aber auch nicht schlimm, denn wenn man einmal dort ist, besorgt man sich am besten direkt einen <b>Amazon Web Services account<\/b>. Daf&uuml;r brauchen Sie eine E-Mail-Adresse und einige Daten wie Ihre Adresse et cetera. Amazon sendet Ihnen eine Best&auml;tigung des neuen Accounts, der unter anderem einen Link zu einer Seite mit einer Access Key ID enth&auml;lt. Auf dieser Seite finden Sie das wichtigste Element f&uuml;r Ihren Zugang zu den Amazon Web Services (siehe Bild 1).<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2008_04\/Amazon-web-images\/pic001_opt.jpeg\" alt=\"pic001.tif\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 1: F&uuml;r den Zugriff auf die Amazon Web Services ben&ouml;tigen Sie eine Access Key ID.<\/span><\/b><\/p>\n<p>Wenn Sie die Beispieldatenbank mit dem Amazon Associates Web Service ausprobieren m&ouml;chten, m&uuml;ssen Sie sich &uuml;brigens zwangsl&auml;ufig einen eigenen Account besorgen &#8211; die Beispieldatenbanken enthalten keinen g&uuml;ltigen Schl&uuml;ssel.<\/p>\n<p><b>Beispieldatenbank<\/b><\/p>\n<p>Mit dieser ID bewaffnet k&ouml;nnen Sie eine erste Beispieldatenbank erstellen. Die Access Key ID speichern Sie der Einfachheit halber in einer global zug&auml;nglichen Konstanten in einem Standardmodul namens <b>mdlGlobal<\/b>:<\/p>\n<pre>Public Const cDeveloperToken As String = _\r\n\"ABCDEFGHIJ0123456789\"<\/pre>\n<p><b>Bedingungen<\/b><\/p>\n<p>Die Benutzung der Amazon Webservices ist nur unter bestimmten Bedingungen erlaubt und kostenlos. Dazu geh&ouml;rt, dass der Zugriff haupts&auml;chlich dazu gedacht sein muss, Kunden auf die Webseiten von Amazon zu lenken, und dass man die von Amazon gewonnenen Daten nicht ohne schriftliche Genehmigung weiterver&auml;u&szlig;ert oder verteilt oder diese f&uuml;r mobile Endger&auml;te aufbereitet. Au&szlig;erdem ist nur eine Anfrage pro Sekunde pro Access Key ID m&ouml;glich.<\/p>\n<p>Die genauen Nutzungsrechte m&uuml;ssen Sie aber ohnehin bei der Anmeldung an den Amazon Associates Web Service absegnen. Die ebenfalls in dieser Ausgabe von <b>Access im Unternehmen <\/b>vorgestellte B&uuml;cherverwaltung kann daher also nur ein Beispiel f&uuml;r den Zugriff auf den Amazon Associates Web Service sein.<\/p>\n<p><b>Anfragen senden mit REST<\/b><\/p>\n<p>Wenn man eine Anfrage mit REST versenden und das Antwort-XML-Dokument entgegennehmen m&ouml;chte, braucht man nur wenige Zeilen Code. Ein einfacher Test sieht beispielsweise wie folgt aus:<\/p>\n<pre>http:\/\/ecs.amazonaws.de\/onca\/xml\r\nService=AWSECommerceService\r\n&amp;AWSAccessKeyId=ABCDEFGHIJ0123456789\r\n&amp;Operation=ItemSearch\r\n&amp;SearchIndex=Books\r\n&amp;Title=Access\r\n&amp;Version=2008-08-19<\/pre>\n<p>Dieser Aufruf enth&auml;lt zun&auml;chst die URL des Webservices und dahinter eine ganze Reihe Parameter. Der erste Parameter namens <b>Service <\/b>besitzt immer den Wert <b>AWSECommerceService<\/b>. Danach folgt die Access Key ID, die f&uuml;r jeden Benutzer eindeutig sein muss. Wenn Sie am Partnerprogramm von Amazon teilnehmen, sollten Sie auch diese in die URL einflie&szlig;en lassen &#8211; auf diese Weise erhalten Sie im Falle eines Verkaufs die entsprechende Provision. Der passende Parameter lautet <b>AssociateTag<\/b>.<\/p>\n<p><b>Operation <\/b>gibt die gew&uuml;nschte Aktion an, in diesem Falle mit <b>ItemSearch <\/b>die Suche nach einem Artikel. <b>SearchIndex<\/b> legt fest, nach welcher Art von Artikel der Service suchen soll. Hier sind die B&uuml;cher, also <b>Books<\/b>, das Ziel der Anfrage. <b>Title <\/b>markiert nur einen von mehreren m&ouml;glichen Suchparametern und steht f&uuml;r den Titel eines Buchs. Unter <b>Version <\/b>geben Sie die Version des Amazon Associates Web Services an.<\/p>\n<p>Eine REST-Anfrage k&ouml;nnen Sie bequem &uuml;ber den Webbrowser absetzen. Dieser liefert das Antwort-XML-Dokument als neue Seite zur&uuml;ck (siehe Bild 2).<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2008_04\/Amazon-web-images\/pic002_opt.jpeg\" alt=\"pic002.tif\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 3: Anlegen eines Verweises auf die Microsoft XML-Bibliothek<\/span><\/b><\/p>\n<p>Neben den hier sichtbaren XML-Elementen folgen einige weitere mit den eigentlichen Informationen zu den gefundenen Artikeln.<\/p>\n<p><b>Ergebnis beeinflussen mit Response Groups<\/b><\/p>\n<p>Amazon liefert dabei die wichtigsten Informationen wie den Titel, den oder die Autoren oder den Hersteller, aber auch eine Reihe von Links zu verschiedenen produktbezogenen Seiten auf Amazon &#8211; nicht nur zur Produktseite selbst, sondern auch zu Seiten, auf denen Sie das Produkt zu Wunschlisten hinzuf&uuml;gen oder seine Bewertung durch andere K&auml;ufer einsehen k&ouml;nnen.<\/p>\n<p>Diese Informationen k&ouml;nnen Sie erheblich erweitern. Dazu verwenden Sie den ResponseGroup-Parameter mit einer der unter [1] angegebenen Response-Groups.<\/p>\n<p>Wenn die Produktliste beispielsweise Links zu den Produktbildern enthalten soll, f&uuml;gen Sie folgenden Parameter zum REST-Aufruf hinzu:<\/p>\n<pre>&amp;ResponseGroup=Images<\/pre>\n<p>Weitere Response Groups geben Sie durch Komma getrennt wie folgt an:<\/p>\n<pre>&amp;ResponseGroup=Images,Reviews<\/pre>\n<p>Diese Variante w&uuml;rde nicht nur die Links zu Bildern, sondern auch noch die Bewertungstexte anderer K&auml;ufer zur&uuml;ckliefern. Weitere Parameter und ihre Bedeutung finden Sie unter obigem Link.<\/p>\n<p><b>REST-Anfrage per VBA<\/b><\/p>\n<p>F&uuml;r den VBA-Entwickler ist es nat&uuml;rlich viel interessanter, eine REST-Abfrage per VBA abzusetzen und das Ergebnis in verarbeitbarer Form zur&uuml;ckzuerhalten. Die Amazon-Dokumentation liefert leider &uuml;berwiegend Material f&uuml;r andere Programmiersprachen wie die .NET-Sprachen, PHP, Perl oder Java &#8211; Sprachen, denen man gegen&uuml;ber VBA eine weit h&ouml;here Web-Affinit&auml;t einr&auml;umt.<\/p>\n<p>Die Routine aus Listing 1 zeigt beispielhaft, wie das Verwenden einer REST-Anfrage und die Auswertung der Antwort erfolgt. Dabei setzen die ersten Zeilen zun&auml;chst die URL mit den Parametern f&uuml;r die Anfrage zusammen. Hier kommen zun&auml;chst nur die oben angegebenen Parameter zum Einsatz, sp&auml;ter k&uuml;mmern wir uns um weitere Parameter wie etwa zus&auml;tzliche Suchkriterien.<\/p>\n<p class=\"kastentabelleheader\">Listing 1: Ein einfacher Amazon-Request<\/p>\n<pre>Public Sub AmazonRequest()\r\nDim objXML As MSXML2.DOMDocument\r\nDim strRequest As String\r\nDim strDeveloperToken As String\r\nDim strErrorCode As String\r\nDim strErrorDescription As String\r\nDim bolSuccess As Boolean\r\nstrDeveloperToken = cDeveloperToken\r\nstrRequest = \"http:\/\/ecs.amazonaws.de\/onca\/xml&euro;\r\nstrRequest = strRequest &amp; \"Service=AWSECommerceService&euro;\r\nstrRequest = strRequest &amp; \"&amp;AWSAccessKeyId=&euro; &amp; strDeveloperToken\r\nstrRequest = strRequest &amp; \"&amp;Operation=ItemSearch&euro;\r\nstrRequest = strRequest &amp; \"&amp;SearchIndex=Books&euro;\r\nstrRequest = strRequest &amp; \"&amp;Title=Access&euro;\r\nstrRequest = strRequest &amp; \"&amp;Version=2008-08-19&euro;\r\nSet objXML = New MSXML2.DOMDocument\r\nWith objXML\r\n.async = False\r\n.preserveWhiteSpace = False\r\n.validateOnParse = True\r\n.resolveExternals = False\r\nEnd With\r\nbolSuccess = objXML.Load(strRequest)\r\nIf bolSuccess = True Then\r\n    On Error Resume Next\r\n    strErrorCode = objXML. _\r\n    selectSingleNode(\"ItemSearchResponse\/OperationRequest\/Errors\/Error\/Code&euro;).Text\r\n    If Err.Number = 0 Then\r\n        strErrorDescription = objXML. _\r\n        selectSingleNode(\"ItemSearchResponse\/OperationRequest\/Errors\/Error\/Message&euro;).Text\r\n        MsgBox strErrorDescription, vbOKOnly + vbCritical, strErrorCode\r\n    Else\r\n        Debug.Print objXML.XML\r\n    End If\r\nElse\r\n    MsgBox \"Error!&euro; &amp; vbCrLf &amp; objXML.parseError.reason\r\nEnd If\r\nEnd Sub<\/pre>\n<p>Nach dem Erstellen des URL-Strings erzeugt die Routine ein <b>DOMDocument<\/b>-Objekt (MSXML-Bibliothek, Verweis siehe Bild 3) und stellt einige Eigenschaften ein. Die <b>Load<\/b>-Methode dieses Objekts liefert beim Aufruf mit der Anfrage entweder den Wert <b>True <\/b>f&uuml;r eine erfolgreiche Anfrage oder den Wert <b>False <\/b>zur&uuml;ck. Letzterer Fall wird mit einer entsprechenden Meldung inklusive Fehlermeldung quittiert, dies sollte jedoch in der Regel nicht passieren. Eher kann es sein, dass ein fehlerhafter Aufruf ein valides XML-Dokument zur&uuml;ckliefert, das selbst die Fehlerbeschreibung enth&auml;lt. Dies deckt die <b>If&#8230;Then<\/b>-Bedingung ab, welche pr&uuml;ft, ob beim Zugriff auf das Element, das &uuml;blicherweise Fehlerinformationen enth&auml;lt (siehe markierter Bereich in Bild 4), ein Fehler aufgetreten ist. Das Auslesen erfolgt dabei mithilfe eines XPath-Ausdrucks (XPath ist die Abfragesprache f&uuml;r XML-Dokumente). Die &uuml;bergeordnete <b>Errors<\/b>-Auflistung ist nur in einer XML-Response enthalten, wenn der Aufruf fehlerhaft ist, sonst f&auml;llt sie komplett weg. Liefert das Dokument Fehlerinformationen, gibt ein Meldungsfenster die Informationen aus.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2008_04\/Amazon-web-images\/pic003_opt.jpeg\" alt=\"pic003.tif\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 2: Ergebnis einer REST-Anfrage im Internet Explorer<\/span><\/b><\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2008_04\/Amazon-web-images\/pic004_opt.jpeg\" alt=\"pic004.tif\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 4: Ein XML-Dokument mit einer Fehlermeldung weist meist auf eine fehlerhafte Anfrage hin.<\/span><\/b><\/p>\n<p>Liegt kein Fehler vor, enth&auml;lt dieser Teil des XML-Dokuments die Informationen &uuml;ber die gefundenen Produkte. Diese fallen meist wesentlich umfangreicher als Fehlerinformationen aus, dementsprechend haben wir auch deren Verarbeitung zun&auml;chst aus Listing 1 ausgeklammert und nur einen Kommentar platziert, der anzeigt, wo die Verarbeitung stattfindet.<\/p>\n<p><b>Inhalt der XML-Antwort<\/b><\/p>\n<p>Der wesentliche Teil einer fehlerlosen Antwort sieht etwa wie in Listing 2 aus und enth&auml;lt die <b>Items<\/b>-Auflistung als Unterelement des Root-Elements <b>ItemSearchResponse<\/b>. <\/p>\n<p class=\"kastentabelleheader\">Listing 2: Aussehen der Beschreibung eines Buchs<\/p>\n<pre>...\r\n&lt;Items&gt;\r\n&lt;Request&gt;\r\n&lt;IsValid&gt;True&lt;\/IsValid&gt;\r\n&lt;ItemSearchRequest&gt;\r\n&lt;SearchIndex&gt;Books&lt;\/SearchIndex&gt;\r\n&lt;Title&gt;Access&lt;\/Title&gt;\r\n&lt;\/ItemSearchRequest&gt;\r\n&lt;\/Request&gt;\r\n&lt;TotalResults&gt;1051&lt;\/TotalResults&gt;\r\n&lt;TotalPages&gt;106&lt;\/TotalPages&gt;\r\n&lt;Item&gt;\r\n&lt;ASIN&gt;3827322650&lt;\/ASIN&gt;\r\n&lt;DetailPageURL&gt;http:\/\/www.amazon.de\/...&lt;\/DetailPageURL&gt;\r\n&lt;ItemLinks&gt;\r\n&lt;ItemLink&gt;\r\n&lt;Description&gt;Add To Wishlist&lt;\/Description&gt;\r\n&lt;URL&gt;http:\/\/www.amazon.de\/...&lt;\/URL&gt;\r\n&lt;\/ItemLink&gt;\r\n... more &lt;ItemLink&gt;-Elements\r\n&lt;\/ItemLinks&gt;\r\n&lt;ItemAttributes&gt;\r\n&lt;Author&gt;Andre Minhorst&lt;\/Author&gt;\r\n&lt;Creator Role=\"Autor\"&gt;Andre Minhorst&lt;\/Creator&gt;\r\n&lt;Manufacturer&gt;Addison-Wesley, M&uuml;nchen&lt;\/Manufacturer&gt;\r\n&lt;ProductGroup&gt;Book&lt;\/ProductGroup&gt;\r\n&lt;Title&gt;Das Access 2003-Entwicklerbuch&lt;\/Title&gt;\r\n&lt;\/ItemAttributes&gt;\r\n&lt;\/Item&gt;\r\n... more &lt;Item&gt;-Elements\r\n&lt;\/Items&gt;\r\n...<\/pre>\n<p>Diese Auflistung wiederum besteht aus einigen allgemeinen Informationen wie der Wiederholung der in der REST-Anfrage gemachten Angaben sowie der Angabe der Anzahl der Ergebnisse und der Seiten, auf welche die Ergebnisse aufgeteilt sind.<\/p>\n<p>Schlie&szlig;lich folgen einige <b>Item<\/b>-Elemente (standardm&auml;&szlig;ig sind es zehn St&uuml;ck je Seite). Diese enthalten einen Link zur Detailseite bei Amazon, weitere Links zum Hinzuf&uuml;gen des Items zu den verschiedenen Listen und unter <b>ItemAttributes <\/b>die eigentlichen Eigenschaften des <b>Item<\/b>-Elements.<\/p>\n<p>Im Rahmen der B&uuml;cherverwaltung aus Beitrag <b>B&uuml;cherverwaltung <\/b>(s. Shortlink 633) soll der WebService B&uuml;cher liefern, die einem oder mehreren Kriterien entsprechen. Daf&uuml;r brauchen Sie eine spezielle Art der <b>ItemSearch<\/b>-Operation, die nur f&uuml;r B&uuml;cher funktioniert und die den Suchparameter <b>Search <\/b>erwartet. Diesen f&uuml;llt man wiederum mit einem Ausdruck, der die gew&uuml;nschten Suchkriterien enth&auml;lt. Ausgiebige Informationen zu diesem Parameter liefert [2].<\/p>\n<p>Zu Beispielzwecken beschr&auml;nken wir uns hier auf die folgenden Kriterien:<\/p>\n<ul>\n<li class=\"aufz-hlung\"><b>ASIN<\/b>: amazonweit eindeutige Produktnummer, entspricht bei B&uuml;chern der ISBN-Nummer<\/li>\n<li class=\"aufz-hlung\"><b>author<\/b>: Autor des Buchs<\/li>\n<li class=\"aufz-hlung\"><b>keywords<\/b>: Im Titel oder in der Beschreibung eines Buchs vorkommende W&ouml;rter<\/li>\n<li class=\"aufz-hlung\"><b>pubdate<\/b>: Ver&ouml;ffentlichungsdatum<\/li>\n<li class=\"aufz-hlung\"><b>title<\/b>: Im Titel vorkommende W&ouml;rter<\/li>\n<\/ul>\n<p>Sowohl die einzelnen Kriterien als auch die f&uuml;r ein Kriterium angegebenen Schl&uuml;sselbegriffe k&ouml;nnen durch <b>and <\/b>und <b>or <\/b>verkn&uuml;pft werden; auch der Einsatz von Klammern ist m&ouml;glich. Wichtig ist, dass eventuell auftretende Leerzeichen durch den Ausdruck <b>%20 <\/b>ersetzt werden. Dies entspricht dem hexadezimalen Wert f&uuml;r <b>32<\/b>, dem ASCII-Wert des Leerzeichens.<\/p>\n<p><!--30percent--><\/p>\n<p><b>Mehrere Ergebnisseiten<\/b><\/p>\n<p>Die Anzahl der B&uuml;cher &uuml;berschreitet gelegentlich die in einem Zug vom Webservice zur&uuml;ckgelieferten zehn B&uuml;cher. In diesem Fall muss man den gleichen Aufruf mehrere Male durchf&uuml;hren, um Informationen zu allen B&uuml;chern zu erhalten &#8211; mit einer kleinen Ausnahme: Der Aufruf soll jeweils die n&auml;chsten zehn B&uuml;cher zur&uuml;ckliefern.<\/p>\n<p>Dies erledigt der Parameter <b>ItemPage<\/b>, den man per VBA auf die jeweilige Seite einstellt:<\/p>\n<pre>strRequest = strRequest &amp; \"&amp;ItemPage=\" &amp; intPage<\/pre>\n<p>Wie viele Seiten und wie viele Eintr&auml;ge es gibt, erf&auml;hrt man aus zwei Elementen, die sich unterhalb des <b>Items<\/b>-Knotens befinden und etwa wie folgt aussehen:<\/p>\n<pre>&lt;TotalResults&gt;12&lt;\/TotalResults&gt;\r\n&lt;TotalPages&gt;2&lt;\/TotalPages&gt;<\/pre>\n<p>Um alle, auch &uuml;ber mehrere Seiten verteilte B&uuml;cher einzulesen, braucht man also nur eine Schleife von 2 (den ersten Aufruf braucht man, um &uuml;berhaupt die Seitenzahl zu erfahren) bis zur Anzahl der Seiten laufen zu lassen und die enthaltenen Eintr&auml;ge zu verarbeiten.<\/p>\n<p><b>Mehr Eigenschaften<\/b><\/p>\n<p>Im obigen Beispiel liefert das XML-Dokument nur wenige Informationen zu den jeweiligen B&uuml;chern zur&uuml;ck. Viel mehr Informationen erh&auml;lt man, wenn man eine oder mehrere der unter [1] angegebenen Response Groups angibt. Dies geschieht zum Beispiel mit dem folgenden Parameter:<\/p>\n<pre>&amp;ResponseGroup=Medium<\/pre>\n<p><b>Medium <\/b>repr&auml;sentiert bereits eine Zusammenfassung mehrerer anderer Response Groups. Wenn Sie eine andere, individuelle Zusammenstellung von Response Groups w&uuml;nschen, k&ouml;nnen Sie diese durch Kommata getrennt angeben. Die folgenden Elemente entsprechen beispielsweise denen, welche die Response Group <b>Medium <\/b>zusammenfasst:<\/p>\n<pre>&amp;ResponseGroup=EditorialReview,Images,ItemAttributes,OfferSummary,Request,SalesRank,Small<\/pre>\n<p>F&uuml;r unsere Zwecke reicht die Response Group <b>Medium <\/b>voll aus. Sie liefert diese Informationen:<\/p>\n<ul>\n<li class=\"aufz-hlung\">ASIN<\/li>\n<li class=\"aufz-hlung\">DetailPageURL<\/li>\n<li class=\"aufz-hlung\">Diverse Links zu Wishlist, Tell A Friend, All Customer Reviews oder All Offers<\/li>\n<li class=\"aufz-hlung\">Verkaufsrang<\/li>\n<li class=\"aufz-hlung\">Links zu Bilddateien inklusive Abmessungen<\/li>\n<li class=\"aufz-hlung\">Author<\/li>\n<li class=\"aufz-hlung\">Binding<\/li>\n<li class=\"aufz-hlung\">Creator Role<\/li>\n<li class=\"aufz-hlung\">EAN<\/li>\n<li class=\"aufz-hlung\">ISBN<\/li>\n<li class=\"aufz-hlung\">Label<\/li>\n<li class=\"aufz-hlung\">Manufacturer<\/li>\n<li class=\"aufz-hlung\">NumberOfPages<\/li>\n<li class=\"aufz-hlung\">PackageDimensions: Abmessungen des Buchs (L&auml;nge, H&ouml;he, Breite, Gewicht inklusive Einheiten)<\/li>\n<li class=\"aufz-hlung\">ProductGroup<\/li>\n<li class=\"aufz-hlung\">ProductTypeName<\/li>\n<li class=\"aufz-hlung\">PublicationDate<\/li>\n<li class=\"aufz-hlung\">Publisher<\/li>\n<li class=\"aufz-hlung\">Studio<\/li>\n<li class=\"aufz-hlung\">Title<\/li>\n<li class=\"aufz-hlung\">Preise: Neupreis und g&uuml;nstigster Preis f&uuml;r gebrauchtes Buch inklusive W&auml;hrung<\/li>\n<\/ul>\n<p><b>Abfrage und Verarbeitung der Daten<\/b><\/p>\n<p>Eine interessante Frage ist die nach den M&ouml;glichkeiten der Weiterverarbeitung der Daten nach dem Einlesen des XML-Dokuments beziehungsweise der XML-Dokumente.<\/p>\n<p>Da laut Amazon ohnehin nur ein Zugriff pro Access Key ID und Sekunde m&ouml;glich ist, macht es durchaus Sinn, jeweils nur die zehn Eintr&auml;ge des aktuellen Suchergebnisses in einer Liste anzuzeigen und Schaltfl&auml;chen anzubieten, mit denen der Benutzer zwischen den Seiten bl&auml;ttern, einen bestimmten Eintrag in der Detailansicht anzeigen oder diesen zur B&uuml;cherverwaltung hinzuf&uuml;gen kann.<\/p>\n<p>Die Vorgehensweise sieht also etwa so aus: Zun&auml;chst gibt der Benutzer in einem Formular seine Suchbegriffe ein und startet die Abfrage des XML-Dokuments mit den ersten zehn Ergebnissen sowie der Seitenanzahl. Die zehn Ergebnisse werden tempor&auml;r in einer Tabelle gespeichert, deren Inhalt in einem geeigneten Steuerelement &#8211; einem Listenfeld oder einem Unterformular in der Datenblattansicht &#8211; angezeigt wird.<\/p>\n<p>Springt der Benutzer &uuml;ber eine entsprechende Schaltfl&auml;che zur n&auml;chsten Seite, wird auch diese in der tempor&auml;ren Tabelle gespeichert &#8211; freilich ohne die ersten Eintr&auml;ge dieser Suche zu l&ouml;schen. Nun soll das Formular die neuen zehn Eintr&auml;ge anzeigen. Will der Benutzer weitere Eintr&auml;ge sehen, l&auml;dt die Anwendung das XML-Dokument mit den n&auml;chsten zehn Eintr&auml;gen. Will er die vorherigen zehn Eintr&auml;ge sehen, erfolgt keine erneute Abfrage, sondern einfach die Anzeige der bereits gespeicherten B&uuml;cher.<\/p>\n<p>Die folgenden Abschnitte beschreiben nun die folgenden notwendigen Elemente:<\/p>\n<ul>\n<li class=\"aufz-hlung\">die drei Tabellen zum Speichern der gefundenen Informationen,<\/li>\n<li class=\"aufz-hlung\">das Formular zum Eingeben der Suchkriterien und zum Anzeigen des Ergebnisses sowie<\/li>\n<li class=\"aufz-hlung\">die Prozeduren, mit denen die Anwendung die Anfrage an Amazon schickt und das Ergebnis auswertet.<\/li>\n<\/ul>\n<p><b>Datenmodell<\/b><\/p>\n<p>Das kleine Datenmodell zum Speichern der Suchergebnisse umfasst drei Tabellen, wobei die Tabelle <b>tblSearchresults <\/b>die wesentlichen Informationen aufnimmt. Es gibt nur eine Information, die dort nicht so recht reinpasst, und das sind die Autoren. Da es je Buch mehrere Autoren geben und jeder Autor auch mehrere B&uuml;cher geschrieben haben kann, gibt es eine eigene Autorentabelle, die per m:n-Beziehung mit der Tabelle der Suchergebnisse verkn&uuml;ft ist (siehe Bild 5).<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2008_04\/Amazon-web-images\/pic006_opt.jpeg\" alt=\"pic006.tif\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 5: Datenmodell zum Speichern der Suchergebnisse von Amazon-Abfragen<\/span><\/b><\/p>\n<p><b>Formular zur Eingabe von Suchkriterien und Ausgabe der Ergebnisse<\/b><\/p>\n<p>Das Aussehen des Formulars zur Suche nach B&uuml;chern bei Amazon finden Sie in Bild 6. Es enth&auml;lt einige Felder f&uuml;r die Eingabe von Suchkriterien, ein Feld zur Ausgabe des Suchausdrucks, einige Schaltfl&auml;chen sowie ein Unterformular, welches das Suchergebnis anzeigt.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2008_04\/Amazon-web-images\/pic005_opt.jpeg\" alt=\"pic005.tif\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 6: Formular zur Suche nach B&uuml;chern bei Amazon<\/span><\/b><\/p>\n<p>Nach der Eingabe von Text f&uuml;r eines der Suchkriterien soll der Suchausdruck direkt aktualisiert werden. Das hei&szlig;t, dass dieser beim &Ouml;ffnen des Formulars leer ist und mit jedem in eines der Textfelder eingegebenen Buchstaben aktualisiert wird. Dabei erg&auml;nzt das Formular automatisch die f&uuml;r die Abfrage des Amazon-Webservices n&ouml;tigen Ausdr&uuml;cke. Gibt man also unter Autor den Buchstaben <b>M <\/b>ein, soll das Suchfeld direkt den Inhalt <b>Author:M <\/b>anzeigen. Dieser Ausdruck wird dann mit der Eingabe weiterer Zeichen st&auml;ndig aktualisiert.<\/p>\n<p>Damit dies reibungslos funktioniert, gibt es zu jedem Suchfeld ein weiteres unsichtbares Suchfeld (erkennbar in Bild 7), das zun&auml;chst mit dem im sichtbaren Suchfeld eingegebenen Text gef&uuml;llt wird. Au&szlig;erdem ruft die f&uuml;r jedes der sichtbaren Textfelder vorhandene Ereignisprozedur <b>Bei &auml;nderung<\/b> die Routine <b>CreateSearchString<\/b> auf, welche die Inhalte der Suchfelder zu dem gew&uuml;nschten Ausdruck zusammenstellt:<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2008_04\/Amazon-web-images\/pic007_opt.jpeg\" alt=\"pic007.tif\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 7: Entwurfsansicht des Formulars frmSearchAmazon<\/span><\/b><\/p>\n<pre>Private Sub txtISBN_Change()\r\n    Me!txtISBNTemp = Me!txtISBN.Text\r\n    CreateSearchString\r\n    End Sub<\/pre>\n<p>Die Routine <b>CreateSearchString<\/b> sieht wie in Listing 3 aus. Sie durchl&auml;uft die f&uuml;nf Suchfelder und stellt daraus einen Ausdruck wie <b>Title:Access and Author:Minhorst <\/b>zusammen.<\/p>\n<p class=\"kastentabelleheader\">Listing 3: Zusammenstellen des Suchausdrucks<\/p>\n<pre>Private Sub CreateSearchString()\r\n    Dim strSearch As String\r\n    If Len(Me!txtISBNTemp) &gt; 0 Then\r\n        If Len(strSearch) &gt; 0 Then\r\n            strSearch = strSearch &amp; \" and \"\r\n        End If\r\n        strSearch = strSearch &amp; \"ASIN:&euro; &amp; Me!txtISBNTemp\r\n    End If\r\n    If Len(Me!txtTitleTemp) &gt; 0 Then\r\n        If Len(strSearch) &gt; 0 Then\r\n            strSearch = strSearch &amp; \" and \"\r\n        End If\r\n        strSearch = strSearch &amp; \"Title:&euro; &amp; Me!txtTitleTemp\r\n    End If\r\n    ... weitere Kriterien\r\n    If Left(strSearch, 5) = \" and \" Then _\r\n    strSearch = Mid(strSearch, 6)\r\n    Me!txtSearch = strSearch\r\n    Me!cmdSearchAmazon.Enabled = Len(strSearch) &gt; 0\r\n    End Sub<\/pre>\n<p>Warum der Aufwand mit den zus&auml;tzlichen Textfeldern Die Routine <b>CreateSearchString <\/b>k&ouml;nnte doch auch direkt auf die <b>Text<\/b>-Eigenschaft der Textfelder zugreifen Nein, das kann Sie eben nicht: Die Text-Eigenschaft ist nur verf&uuml;gbar, solange ein Steuerelement den Fokus hat. Nun k&ouml;nnte man sicher in der Routine <b>CreateSearchString <\/b>pr&uuml;fen, ob ein Textfeld gerade den Fokus hat und davon abh&auml;ngig entweder die <b>Text<\/b>&#8211; oder, implizit, die <b>Value<\/b>-Eigenschaft auslesen. Aber die L&ouml;sung mit den zus&auml;tzlichen Textfeldern scheint sauberer.<\/p>\n<p>Wie oben erw&auml;hnt, kann man auch mehrere durch <b>And <\/b>oder <b>Or <\/b>verkn&uuml;pfte Ausdr&uuml;cke verwenden. Der Aufwand f&uuml;r das Erstellen einer Eingabemaske, die dies unterst&uuml;tzt, schien uns nicht angemessen.<\/p>\n<p>Daher kann der Benutzer den halbautomatisch erzeugten Suchausdruck nachtr&auml;glich bearbeiten, indem er weitere Ausdr&uuml;cke, <b>And<\/b>&#8211; und <b>Or<\/b>-Operatoren oder Klammern hinzuf&uuml;gt. Aber Vorsicht: Eingaben in die oberen Kriterienfelder setzen manuelle &auml;nderungen im Suchausdruck wieder zur&uuml;ck.<\/p>\n<p><b>Suchformular zur&uuml;cksetzen<\/b><\/p>\n<p>Die Schaltfl&auml;che <b>Suchfelder leeren <\/b>hat die einfachste Aufgabe im Formular: Sie setzt die Suchfelder zur&uuml;ck, l&ouml;scht das angezeigte Suchergebnis und deaktiviert alle anderen Schaltfl&auml;chen im oberen Bereich.<\/p>\n<p><b>Suche starten<\/b><\/p>\n<p>Die wichtigste Aufgabe hat die Schaltfl&auml;che <b>cmdSearchAmazon<\/b>: Sie wertet den eingegebenen Suchausdruck aus, sendet ihn an den Amazon-Webservice, speichert im Erfolgsfall das Suchergebnis in den oben beschriebenen Tabellen und zeigt ihren Inhalt im Unterformular an. Wenn man sich Listing 4 anschaut, sieht das recht einfach aus. Hinter den dortigen Aufrufen verbergen sich jedoch noch einige weitere Routinen.<\/p>\n<p class=\"kastentabelleheader\">Listing 4: Diese Zeilen sind f&uuml;r die B&uuml;chersuche verantwortlich.<\/p>\n<pre>Private Sub cmdSearchAmazon_Click()\r\n    Dim strSearch As String\r\n    Dim objXML As MSXML2.DOMDocument\r\n    strSearch = Replace(Me.txtSearch, \" \", \"%20&euro;)\r\n    If GetPageCount(strSearch, intPages) = True Then\r\n        CurrentDb.Execute \"DELETE FROM tblSearchresults&euro;, _\r\n        dbFailOnError\r\n        If intPages &gt; 0 Then\r\n            intCurrentPage = 1\r\n            intMaxPage = 1\r\n            If GetPage(strSearch, 1, objXML) = True Then\r\n                SaveSearchResults objXML, intCurrentPage\r\n            End If\r\n        End If\r\n    End If\r\n    RequeryControls\r\n    End Sub<\/pre>\n<p>Beginnen wir mit der Routine <b>GetPageCount <\/b>aus Listing 5. Diese soll lediglich ermitteln, aus wie vielen Seiten das Suchergebnis besteht.<\/p>\n<p class=\"kastentabelleheader\">Listing 5: Anzahl der Ergebnisseiten einlesen<\/p>\n<pre>Public Function GetPageCount(strSearch As String, intPages As Integer) As Boolean\r\n    ... Deklaration ...\r\n    If GetRequest(strSearch, 1, strRequest) = True Then\r\n        If SendRequest(strRequest, objXML) = True Then\r\n            If ResponseError(objXML, strErrorCode, strErrorDescription) = True Then\r\n                MsgBox strErrorDescription, vbOKOnly + vbCritical, strErrorCode\r\n            Else\r\n                intPages = objXML.selectSingleNode(\"ItemSearchResponse\/Items\/TotalPages\").Text\r\n                bolSuccess = True\r\n            End If\r\n        Else\r\n            MsgBox \"Error!\" &amp; vbCrLf &amp; objXML.parseError.reason\r\n        End If\r\n    End If\r\n    GetPageCount = bolSuccess\r\n    ... Fehlerbehandlung ...\r\nEnd Function<\/pre>\n<p>Sie ruft zun&auml;chst die Funktion <b>GetRequest <\/b>auf, die aus dem Suchausdruck und den &uuml;brigen, weitgehend feststehenden Parametern einen Request zusammensetzt und diesen &uuml;ber die Variable <b>strRequest <\/b>zur&uuml;ckliefert.<\/p>\n<p>Der n&auml;chste Aufruf auf die Routine <b>SendRequest <\/b>sendet eben diesen Request an den Amazon-Webservice und liefert im Erfolgsfall in <b>objXML <\/b>das XML-Dokument mit dem Ergebnis zur&uuml;ck.<\/p>\n<p>Dieses XML-Dokument wird anschlie&szlig;end von der Routine <b>ResponseError <\/b>dahingehend gepr&uuml;ft, ob ein formeller Fehler, beispielsweise durch einen ung&uuml;ltigen Parameter, aufgetreten ist und im XML-Dokument verzeichnet wurde. Falls ja, erscheint eine entsprechende Fehlermeldung. Sie k&ouml;nnen dies provozieren, indem Sie eine ung&uuml;ltige Access Key ID angeben.<\/p>\n<p>Ist auch diese H&uuml;rde &uuml;berwunden, ermittelt die Routine mittels XPath den Wert des Knotens <b>ItemSearchResponse\/Items\/TotalPages <\/b>und schreibt diesen in die Variable <b>intPages<\/b>. <b>intPages<\/b> ist dabei eine modulweit g&uuml;ltige Variable, die im Folgenden vor allem der Aktivierung und Deaktivierung der beiden Schaltfl&auml;chen zum Vor- und Zur&uuml;ckbl&auml;ttern dient.<\/p>\n<p><b>Request zusammensetzen<\/b><\/p>\n<p>Die oben erw&auml;hnte Routine <b>GetRequest <\/b>finden Sie in Listing 6.<\/p>\n<p class=\"kastentabelleheader\">Listing 6: Zusammensetzen des Webservice-Requests<\/p>\n<pre>Public Function GetRequest(strSearch As String, _\r\n    intPage As Integer, strRequest As String) As Boolean\r\n    Dim strDeveloperToken As String\r\n    strDeveloperToken = cDeveloperToken\r\n    strRequest = \"http:\/\/ecs.amazonaws.de\/onca\/xml&euro;\r\n    strRequest = strRequest &amp; \"Service=AWSECommerceService&euro;\r\n    strRequest = strRequest &amp; \"&amp;AWSAccessKeyId=&euro; &amp; strDeveloperToken\r\n    strRequest = strRequest &amp; \"&amp;Operation=ItemSearch&euro;\r\n    strRequest = strRequest &amp; \"&amp;SearchIndex=Books&euro;\r\n    If intPage &gt; 1 Then\r\n        strRequest = strRequest &amp; \"&amp;ItemPage=&euro; &amp; intPage\r\n    End If\r\n    strRequest = strRequest &amp; \"&amp;Power=&euro; &amp; strSearch\r\n    strRequest = strRequest &amp; \"&amp;ResponseGroup=Medium&euro;\r\n    strRequest = strRequest &amp; \"&amp;Version=2008-08-19&euro;\r\n    GetRequest = True\r\n    ... Fehlerbehandlung ...\r\nEnd Function<\/pre>\n<p>Die Routine erwartet den Suchausdruck <b>strSearch <\/b>sowie die Angabe der Seitenzahl, die ermittelt werden soll, und liefert mit <b>strRequest <\/b>die <b>Request<\/b>-Zeichenfolge zur&uuml;ck.<\/p>\n<p>In diese wird unter anderem die Access Key ID aus der Konstanten <b>cDeveloperToken <\/b>eingearbeitet.<\/p>\n<p class=\"zwischen-berschrift-oberer-spaltenrand\">Request senden<\/p>\n<p>Die Routine <b>SendRequest <\/b>&uuml;bernimmt das Senden des Requests an den Amazon-Webservice (s. Listing 7). Scheitert der Request, weil er beispielsweise eine falsche URL enth&auml;lt, liefert die Routine den Wert <b>False <\/b>zur&uuml;ck, anderenfalls <b>True<\/b>. In letzterem Fall kann die aufrufende Routine das in <b>objXML <\/b>gespeicherte XML-Dokument weiterverwenden.<\/p>\n<p class=\"kastentabelleheader\">Listing 7: Anfrage an den Amazon-Webservice senden<\/p>\n<pre>Public Function SendRequest(strRequest As String, _\r\n    objXML As MSXML2.DOMDocument) As Boolean\r\n    Set objXML = New MSXML2.DOMDocument\r\n    With objXML\r\n    .async = False\r\n    .preserveWhiteSpace = False\r\n    .validateOnParse = True\r\n    .resolveExternals = False\r\n    End With\r\n    SendRequest = objXML.Load(strRequest)\r\nEnd Function<\/pre>\n<p><b>Interne Fehler suchen<\/b><\/p>\n<p>Wenn der Request erfolgreich war und ein XML-Dokument zur&uuml;ckgeliefert hat, kann dieses immer noch eine interne Fehlermeldung enthalten. Diese resultiert, wie bereits oben erw&auml;hnt, beispielsweise aus falschen Parametern (siehe Bild 4). Die Routine <b>ResponseError <\/b>aus Listing 8 k&uuml;mmert sich um solche F&auml;lle. Dabei versucht die Routine zun&auml;chst, den Wert des Knotens <b>ItemSearchResponse\/OperationRequest\/Errors\/Error\/Code <\/b>aus dem Dokument auszulesen, der im Falle eines Fehlers vorhanden ist. Tritt dabei kein Fehler auf, bedeutet dies, dass der Fehlerknoten vorhanden ist und der Request fehlerhafte Parameter enth&auml;lt. In diesem Fall liest die Routine auch noch den Wert von <b>ItemSearchResponse\/OperationRequest\/Errors\/Error\/Message <\/b>aus und liefert die beiden Informationen &uuml;ber die Parameter <b>strErrorCode <\/b>und <b>strErrorDescription <\/b>an die aufrufende Routine zur&uuml;ck.<\/p>\n<p class=\"kastentabelleheader\">Listing 8: Diese Funktion untersucht das Response-Objekt auf Fehlermeldungen.<\/p>\n<pre>Public Function ResponseError(objXML As MSXML2.DOMDocument, strErrorCode As String, _\r\n    strErrorDescription As String) As Boolean\r\n    Dim bolError As Boolean\r\n    ...\r\n    On Error Resume Next\r\n    strErrorCode = objXML.selectSingleNode _\r\n    (\"ItemSearchResponse\/OperationRequest\/Errors\/Error\/Code\").Text\r\n    If Err.Number = 0 Then\r\n        strErrorDescription = objXML.selectSingleNode _\r\n        (\"ItemSearchResponse\/OperationRequest\/Errors\/Error\/Message\").Text\r\n        bolError = True\r\n    Else\r\n        On Error Resume Next\r\n        strErrorCode = objXML.selectSingleNode(\"Errors\/Error\/Code\").Text\r\n        If Err.Number = 0 Then\r\n            strErrorDescription = objXML.selectSingleNode(\"Errors\/Error\/Message\").Text\r\n            bolError = True\r\n        End If\r\n    End If\r\n    ResponseError = bolError\r\n    ...\r\nEnd Function<\/pre>\n<p>Tritt beim Auslesen von <b>ItemSearchResponse\/OperationRequest\/Errors\/Error\/Code<\/b> hingegen ein Fehler auf, ist an dieser Stelle auch keine Fehlermeldung vorhanden. Die Routine forscht dann noch an einer anderen Stelle nach einer Fehlermeldung, und zwar im Element <b>Errors\/Error\/Code<\/b>. Gibt es einen solchen Fehler, liefert <b>Errors\/Error\/Message <\/b>weitere Informationen und die beiden Fehlertexte werden auf dem oben bereits beschriebenen Weg an die aufrufende Prozedur &uuml;bergeben.<\/p>\n<p><b>XML-Dokument auslesen<\/b><\/p>\n<p>Wenn die Anwendung auf diese Art ein fehlerfreies XML-Dokument erhalten und aus diesem die Anzahl der Antwortseiten ausgelesen hat, kann sie endlich die eigentlichen Informationen einlesen.<\/p>\n<p>Dies erledigt die Routine <b>GetPage<\/b>, die prinzipiell wie die Routine <b>GetPageCount <\/b>arbeitet, aber nicht die Anzahl der Seiten liefert, sondern auf Basis der &uuml;bergebenen Seitennummer das passende XML-Dokument mit den Suchergebnissen liefert.<\/p>\n<p><b>XML-Dokument verarbeiten<\/b><\/p>\n<p>Die eigentliche Verarbeitung des so gewonnenen XML-Dokuments erledigt die Routine <b>SaveSearchResults<\/b> (s. Listing 9). Diese durchl&auml;uft alle <b>Item<\/b>-Elemente des Knotens <b>ItemSearchResponse\/Items <\/b>des XML-Dokuments und bedient sich dabei einiger Hilfsfunktionen, die mithilfe von XPath-Abfragen den Wert der in den Item-Elementen enthaltenen Buchinformationen auslesen. Die einzelnen Informationen zu jedem gefundenen Buch werden zun&auml;chst in Variablen wie <b>strISBN <\/b>oder <b>lngSalesRank <\/b>gespeichert und von dort mit einer <b>INSERT INTO<\/b>-Aktionsabfrage als neuer Datensatz zur Tabelle <b>tblSearchresults <\/b>hinzugef&uuml;gt.<\/p>\n<p class=\"kastentabelleheader\">Listing 9: Informationen aus XML-Dokument lesen und in Tabellen schreiben<\/p>\n<pre>Public Function SaveSearchResults(objXML As MSXML2.DOMDocument, intPage As Integer) As Boolean\r\n    ... Deklaration ...\r\n    Set db = CurrentDb\r\n    Set objItems = objXML.selectNodes(\"ItemSearchResponse\/Items\/Item\")\r\n    For i = 0 To objItems.length - 1\r\n        strISBN = GetStringFromXML(objItems.Item(i), \"ASIN\")\r\n        ...\r\n        lngSalesRank = GetNumberFromXML(objItems.Item(i), \"SalesRank\")\r\n        ...\r\n        datPublicationDate = GetStringFromXML(objItems.Item(i), \"ItemAttributes\/PublicationDate\")\r\n        ...\r\n        strSQL = \"INSERT INTO tblSearchresults(ISBN, Title, ...) VALUES(&euro;\" _\r\n        &amp; strISBN &amp; \"&euro;, &euro;\" &amp; Replace(strTitle, \"&euro;\", \"&euro;&euro;\") &amp; \"&euro;, ...)\"\r\n        db.Execute strSQL, dbFailOnError\r\n        lngSearchresultID = db.OpenRecordset(\"SELECT @@IDENTITY\").Fields(0)\r\n        Set objAuthors = objItems.Item(i).selectNodes(\"ItemAttributes\/Author\")\r\n        For j = 0 To objAuthors.length\r\n            On Error Resume Next\r\n            db.Execute \"INSERT INTO tblAutoren(Autor) VALUES(&euro;\" &amp; objAuthors.Item(j).Text &amp; \"&euro;)\"\r\n            If Err.Number = 0 And db.RecordsAffected = 1 Then\r\n                lngAuthorID = db.OpenRecordset(\"SELECT @@IDENTITY\").Fields(0)\r\n            Else\r\n                lngAuthorID = db.OpenRecordset(\"SELECT ID FROM tblAutoren WHERE Autor = &euro;\" _\r\n                &amp; objAuthors.Item(j).Text &amp; \"&euro;\", dbOpenDynaset).Fields(0)\r\n            End If\r\n        Next j\r\n    Next i\r\nEnd Function<\/pre>\n<p>Die Autoren, von denen jedes <b>Item<\/b>-Element unter <b>ItemAttributes\/Author <\/b>keinen, einen oder mehrere enthalten kann, erfahren eine Sonderbehandlung: Sie werden zun&auml;chst einzeln in die Tabelle <b>tblAutoren <\/b>geschrieben, wobei Dubletten durch einen eindeutigen Index auf das Feld <b>Autor <\/b>der Tabelle vermieden werden (eine <b>On Error Resume Next<\/b>-Anweisung beugt hieraus resultierenden Fehlermeldungen vor).<\/p>\n<p>Die Routine ermittelt dann die ID der neuen Datens&auml;tze in <b>tblSearchresults <\/b>und <b>tblAutoren <\/b>und legt einen neuen Datensatz in der Verkn&uuml;pfungstabelle <b>tblSearchresultsAutoren <\/b>an, der die beiden verkn&uuml;pft. Auf diese Weise landen alle ben&ouml;tigten Daten in diesen drei Tabellen.<\/p>\n<p class=\"zwischen-berschrift-oberer-spaltenrand\">Ergebnisse anzeigen<\/p>\n<p>Weiter oben in Listing 4 finden Sie die Routine, die durch die Schaltfl&auml;che <b>cmdSearchAmazon <\/b>ausgel&ouml;st wurde und die beschriebenen Routinen aufruft. Nach dem Speichern der Buchinformationen und dem Aktualisieren der Variablen <b>intCurrentPage <\/b>mit der aktuellen Seite bleibt dieser Prozedur nur noch die Aufgabe, die Anzeige im Formular zu aktualisieren, was sie mithilfe der Routine <b>RequeryControls <\/b>erledigt (s. Listing 10).<\/p>\n<p class=\"kastentabelleheader\">Listing 10: Diese Routine aktualisiert die Steurelemente.<\/p>\n<pre>Private Sub RequeryControls()\r\n    Me!sfmSearchAmazon.Form.Filter = \"Resultpage=\" &amp; intCurrentPage\r\n    Me!sfmSearchAmazon.Form.FilterOn = True\r\n    If intCurrentPage &gt; 1 Then\r\n        Me!cmdPreviousPage.Enabled = True\r\n    Else\r\n        Me!cmdSuchfelderLeeren.SetFocus\r\n        Me!cmdPreviousPage.Enabled = False\r\n    End If\r\n    If intCurrentPage &lt; intPages And Not intPages = 0 Then\r\n        Me!cmdNextPage.Enabled = True\r\n    Else\r\n        Me!cmdSuchfelderLeeren.SetFocus\r\n        Me!cmdNextPage.Enabled = False\r\n    End If\r\n    Me!cmdSearchAmazon.Enabled = Len(Me!txtSearch) &gt; 0\r\n    Me!lblSeite.Caption = Seite &quot; &amp; intCurrentPage &amp; &quot;\/&quot; &amp; intPages\r\n    End Sub<\/pre>\n<p>Diese stellt vor allem den Filter des Unterformulars, das die beiden Felder <b>ISBN <\/b>und <b>Titel <\/b>der gefundenen B&uuml;cher anzeigt, auf die aktuelle und in <b>intCurrentPage <\/b>gespeicherte Antwortseite des Amazon-Webservice ein.<\/p>\n<p>Au&szlig;erdem pr&uuml;ft sie die Variable <b>intCurrentPage <\/b>und weitere Informationen, um die Schaltfl&auml;chen <b>cmdNextPage <\/b>und <b>cmdPreviousPage <\/b>aktivieren beziehungsweise deaktivieren zu k&ouml;nnen &#8211; die Schaltfl&auml;che <b>cmdNextPage <\/b>soll etwa deaktiviert sein, wenn das Formular bereits die letzte Seite des Suchergebnisses anzeigt.<\/p>\n<p>Au&szlig;erdem sorgt die Routine daf&uuml;r, dass der Benutzer eine Information &uuml;ber die aktuelle und die gesamte Seitenzahl erh&auml;lt.<\/p>\n<p><b>Vorherige und n&auml;chste Seite<\/b><\/p>\n<p>Die Schaltfl&auml;che <b>cmdNextPage <\/b>addiert beim Anklicken (s. Listing 11) zun&auml;chst zur Variablen <b>intCurrentPage <\/b>den Wert <b>1 <\/b>hinzu, weil sie ja die n&auml;chste Seite anzeigen soll. Dann pr&uuml;ft sie, ob <b>intCurrentPage <\/b>gr&ouml;&szlig;er als <b>intMaxPage <\/b>ist. <b>intMaxPage <\/b>speichert die gr&ouml;&szlig;te bisher eingelesene Seitenzahl. Wenn <b>intCurrentPage <\/b>gr&ouml;&szlig;er als <b>intMaxPage <\/b>ist, liegt die anzuzeigende Ergebnisseite noch nicht in der Tabelle <b>tblSearchresults <\/b>vor und sie muss durch einen Aufruf von <b>GetPage <\/b>zun&auml;chst ermittelt und ihr Inhalt mit <b>SaveSearchResults <\/b>in der Tabelle <b>tblSearchResults <\/b>gespeichert werden. Falls die Seite schon vorhanden, <b>intCurrentPage <\/b>also kleiner oder gleich <b>intMaxPage <\/b>ist, braucht die Anwendung keine Daten vom Amazon-Webservice einzulesen, sondern nur den Filter des Unterformulars auf die Datens&auml;tze f&uuml;r die aktuelle Seite einzustellen.<\/p>\n<p class=\"kastentabelleheader\">Listing 11: Aufrufen der n&auml;chsten Seite<\/p>\n<pre>Private Sub cmdNextPage_Click()\r\n    Dim strSearch As String\r\n    Dim objXML As MSXML2.DOMDocument\r\n    strSearch = Replace(Me.txtSearch, &quot; &quot;, &quot;%20&quot;)\r\n    intCurrentPage = intCurrentPage + 1\r\n    If intCurrentPage &gt; intMaxPage Then\r\n        intMaxPage = intCurrentPage\r\n        If GetPage(strSearch, intCurrentPage, objXML) = True Then\r\n            SaveSearchResults objXML, intCurrentPage\r\n        End If\r\n    End If\r\n    RequeryControls\r\n    End Sub<\/pre>\n<p><b>Zusammenfassung und Ausblick<\/b><\/p>\n<p>Der Beitrag zeigt, wie Sie Buchdaten &uuml;ber den Webservice von Amazon einlesen und in den Tabellen einer Datenbank speichern k&ouml;nnen. Hat man die grunds&auml;tzliche Vorgehensweise einmal verstanden, kann man prinzipiell auch jeden anderen Webservice von Access aus abfragen und die gewonnen Daten weiterverwenden.<\/p>\n<p>Offen l&auml;sst dieser Beitrag die weitere Verwendung der ermittelten Buchinformationen. Wir lassen Sie aber nicht im Regen stehen: Sie k&ouml;nnen damit beispielsweise eine B&uuml;cherverwaltung f&uuml;ttern. So k&ouml;nnen Sie Ihre B&uuml;cher ganz einfach durch die Angabe einer Eigenschaft wie der ISBN in der Amazon-Datenbank suchen und die dort vorhandenen Informationen zu Ihrer eigenen Datenbank hinzuf&uuml;gen. Wie das geht, zeigt der Beitrag B&uuml;cherverwaltung (Shortlink 633).<\/p>\n<p>Wir weisen an dieser Stelle allerdings nochmals darauf hin, dass der Amazon-Webservice nicht prim&auml;r f&uuml;r solche Zwecke genutzt werden darf! Der Haupteinsatz sollte darin bestehen, Kunden auf die Amazon-Webseiten zu schicken.<\/p>\n<p class=\"zwischen-berschriftquellen\">Literatur<\/p>\n<p class=\"quellen\">[1] Request-Parameter: http:\/\/docs.amazonwebservices.com\/AWSECommerceService\/2008-08-19\/DG\/index.htmlCHAP_ResponseGroupsList.html<\/p>\n<p class=\"quellen\">[2] Search-Paremter: http:\/\/docs.amazonwebservices.com\/AWSECommerceService\/2008-08-19\/DG\/index.htmlCHAP_MakingRequestsandUnderstandingResponses.html<\/p>\n<p class=\"quellen\">[3] Amazon Webservices Startseite: http:\/\/www.amazon.com\/gp\/browse.htmlnode=3435361<\/p>\n<p class=\"quellen\">[4] Amazon Associates Web Service Developer Guide: http:\/\/docs.amazonwebservices.com\/AWSECommerceService\/2008-08-19\/DG\/<\/p>\n<h3>Downloads zu diesem Beitrag<\/h3>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>Buecherverwaltung.mdb<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/189D1805-20FF-410B-9875-A58E09B42953\/aiu_634.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Der Amazon Associates Web Service bietet den Zugriff auf die in Amazon gespeicherten Produktdaten an. Dazu geh&ouml;ren l&auml;ngst nicht mehr nur B&uuml;cher, CDs und DVDs, sondern auch Elektroger&auml;te, Kleidung und vieles mehr. Der Zugriff darauf ist nicht nur interessant, wenn man Amazon-Partner ist und die Artikel gegen Provision auf seiner eigenen Webseite feilbietet, sondern auch zum reinen automatischen Einlesen von Produktdaten &#8211; zum Beispiel f&uuml;r die ebenfalls in dieser Ausgabe vorgestellte B&uuml;cherverwaltung.<\/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":[662008,66052008,44000026,44000030,44000027],"tags":[],"class_list":["post-55000634","post","type-post","status-publish","format-standard","hentry","category-662008","category-66052008","category-Interaktiv","category-Internet","category-Loesungen"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.9 (Yoast SEO v27.4) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Amazon Webservices per VBA nutzen - Access im Unternehmen<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/access-im-unternehmen.de\/Amazon_Webservices_per_VBA_nutzen\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Amazon Webservices per VBA nutzen\" \/>\n<meta property=\"og:description\" content=\"Der Amazon Associates Web Service bietet den Zugriff auf die in Amazon gespeicherten Produktdaten an. Dazu geh&ouml;ren l&auml;ngst nicht mehr nur B&uuml;cher, CDs und DVDs, sondern auch Elektroger&auml;te, Kleidung und vieles mehr. Der Zugriff darauf ist nicht nur interessant, wenn man Amazon-Partner ist und die Artikel gegen Provision auf seiner eigenen Webseite feilbietet, sondern auch zum reinen automatischen Einlesen von Produktdaten - zum Beispiel f&uuml;r die ebenfalls in dieser Ausgabe vorgestellte B&uuml;cherverwaltung.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/Amazon_Webservices_per_VBA_nutzen\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2021-02-11T21:23:21+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/vg05.met.vgwort.de\/na\/58c80949f7e64f9d8797b383a80d6488\" \/>\n<meta name=\"author\" content=\"Andr\u00e9 Minhorst\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Verfasst von\" \/>\n\t<meta name=\"twitter:data1\" content=\"Andr\u00e9 Minhorst\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"27\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Amazon_Webservices_per_VBA_nutzen\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Amazon_Webservices_per_VBA_nutzen\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"Amazon Webservices per VBA nutzen\",\"datePublished\":\"2021-02-11T21:23:21+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Amazon_Webservices_per_VBA_nutzen\\\/\"},\"wordCount\":4275,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Amazon_Webservices_per_VBA_nutzen\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg05.met.vgwort.de\\\/na\\\/58c80949f7e64f9d8797b383a80d6488\",\"articleSection\":[\"2008\",\"5\\\/2008\",\"Interaktiv\",\"Internet\",\"L\u00f6sungen\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Amazon_Webservices_per_VBA_nutzen\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Amazon_Webservices_per_VBA_nutzen\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Amazon_Webservices_per_VBA_nutzen\\\/\",\"name\":\"Amazon Webservices per VBA nutzen - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Amazon_Webservices_per_VBA_nutzen\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Amazon_Webservices_per_VBA_nutzen\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg05.met.vgwort.de\\\/na\\\/58c80949f7e64f9d8797b383a80d6488\",\"datePublished\":\"2021-02-11T21:23:21+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Amazon_Webservices_per_VBA_nutzen\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Amazon_Webservices_per_VBA_nutzen\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Amazon_Webservices_per_VBA_nutzen\\\/#primaryimage\",\"url\":\"http:\\\/\\\/vg05.met.vgwort.de\\\/na\\\/58c80949f7e64f9d8797b383a80d6488\",\"contentUrl\":\"http:\\\/\\\/vg05.met.vgwort.de\\\/na\\\/58c80949f7e64f9d8797b383a80d6488\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Amazon_Webservices_per_VBA_nutzen\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Amazon Webservices per VBA nutzen\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"name\":\"Access im Unternehmen\",\"description\":\"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access\",\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/access-im-unternehmen.de\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\",\"name\":\"Andr\u00e9 Minhorst Verlag\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"contentUrl\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"width\":370,\"height\":111,\"caption\":\"Andr\u00e9 Minhorst Verlag\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\",\"name\":\"Andr\u00e9 Minhorst\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"caption\":\"Andr\u00e9 Minhorst\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Amazon Webservices per VBA nutzen - Access im Unternehmen","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/access-im-unternehmen.de\/Amazon_Webservices_per_VBA_nutzen\/","og_locale":"de_DE","og_type":"article","og_title":"Amazon Webservices per VBA nutzen","og_description":"Der Amazon Associates Web Service bietet den Zugriff auf die in Amazon gespeicherten Produktdaten an. Dazu geh&ouml;ren l&auml;ngst nicht mehr nur B&uuml;cher, CDs und DVDs, sondern auch Elektroger&auml;te, Kleidung und vieles mehr. Der Zugriff darauf ist nicht nur interessant, wenn man Amazon-Partner ist und die Artikel gegen Provision auf seiner eigenen Webseite feilbietet, sondern auch zum reinen automatischen Einlesen von Produktdaten - zum Beispiel f&uuml;r die ebenfalls in dieser Ausgabe vorgestellte B&uuml;cherverwaltung.","og_url":"https:\/\/access-im-unternehmen.de\/Amazon_Webservices_per_VBA_nutzen\/","og_site_name":"Access im Unternehmen","article_published_time":"2021-02-11T21:23:21+00:00","og_image":[{"url":"http:\/\/vg05.met.vgwort.de\/na\/58c80949f7e64f9d8797b383a80d6488","type":"","width":"","height":""}],"author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"27\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/Amazon_Webservices_per_VBA_nutzen\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/Amazon_Webservices_per_VBA_nutzen\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"Amazon Webservices per VBA nutzen","datePublished":"2021-02-11T21:23:21+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Amazon_Webservices_per_VBA_nutzen\/"},"wordCount":4275,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Amazon_Webservices_per_VBA_nutzen\/#primaryimage"},"thumbnailUrl":"http:\/\/vg05.met.vgwort.de\/na\/58c80949f7e64f9d8797b383a80d6488","articleSection":["2008","5\/2008","Interaktiv","Internet","L\u00f6sungen"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/Amazon_Webservices_per_VBA_nutzen\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/Amazon_Webservices_per_VBA_nutzen\/","url":"https:\/\/access-im-unternehmen.de\/Amazon_Webservices_per_VBA_nutzen\/","name":"Amazon Webservices per VBA nutzen - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Amazon_Webservices_per_VBA_nutzen\/#primaryimage"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Amazon_Webservices_per_VBA_nutzen\/#primaryimage"},"thumbnailUrl":"http:\/\/vg05.met.vgwort.de\/na\/58c80949f7e64f9d8797b383a80d6488","datePublished":"2021-02-11T21:23:21+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/Amazon_Webservices_per_VBA_nutzen\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/Amazon_Webservices_per_VBA_nutzen\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/Amazon_Webservices_per_VBA_nutzen\/#primaryimage","url":"http:\/\/vg05.met.vgwort.de\/na\/58c80949f7e64f9d8797b383a80d6488","contentUrl":"http:\/\/vg05.met.vgwort.de\/na\/58c80949f7e64f9d8797b383a80d6488"},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/Amazon_Webservices_per_VBA_nutzen\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"Amazon Webservices per VBA nutzen"}]},{"@type":"WebSite","@id":"https:\/\/access-im-unternehmen.de\/#website","url":"https:\/\/access-im-unternehmen.de\/","name":"Access im Unternehmen","description":"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access","publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/access-im-unternehmen.de\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Organization","@id":"https:\/\/access-im-unternehmen.de\/#organization","name":"Andr\u00e9 Minhorst Verlag","url":"https:\/\/access-im-unternehmen.de\/","logo":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/","url":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","contentUrl":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","width":370,"height":111,"caption":"Andr\u00e9 Minhorst Verlag"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f","name":"Andr\u00e9 Minhorst","image":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","caption":"Andr\u00e9 Minhorst"}}]}},"_links":{"self":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55000634","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/comments?post=55000634"}],"version-history":[{"count":0,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55000634\/revisions"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55000634"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55000634"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55000634"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}