Lies diesen Artikel und viele weitere mit einem kostenlosen, einwöchigen Testzugang.
Nach dem Anzeigen der Artikel unseres in Access nachgebildeten Webshops der vorletzten Ausgabe geht es nun an das Bestellen der Produkte bei der ABasics Computer GmbH. Für den hier benötigten Warenkorb, die Kasse und die Bestellvorgänge kommen ganz neue Formulare ins Spiel. Deren Design, Aufbau und Programmierung widmet sich dieser Beitrag, wobei allerlei Tricks und Kniffe nicht zu kurz kommen.
Beispieldatenbank
Die Beispiele dieses Artikels finden Sie in der Datenbank 1610_Web-shopII.zip.
Bestellen im Webshop
Sie möchten im Hauptformular frmShop der Anwendung einen Drucker bestellen. Nach Auswahl der Produktkategorie Drucker im Kombinationsfeld links oben, und nach Markierung der Unterkategorie Tintenstrahler ab A3 im Listenfeld links, füllt sich die Produktliste lstArtikel in der Mitte mit den verfügbaren Produkten. Da Ihnen der Hersteller Hewlett-Packard am vertrauenswürdigsten erscheint, filtern Sie diese Liste über das Kombinationsfeld rechts oben (siehe Bild 1). In dieser Combobox finden sich ausschließlich jene Hersteller, die auch in der Produktliste aufgeführt sind. Ihre Datenherkunft verhält sich also dynamisch in Abhängigkeit von der gewählten Unterkategorie.
Bild 1: So präsentiert sich der Webshop nach dem Start des Formulars frmShop mit eingestellten Kategorien und einem Produkt
Listing 1 zeigt, wie sie bei Auslösen des Ereignisses Nach Aktualisierung des Listenfelds lstKategorien über einen neuen SQL-Select-Ausdruck festgelegt wird. Die RowSource des Steuerelements ist im Prinzip an die Tabelle tblHersteller gebunden. Damit aus dieser aber nur jene Datensätze ausgewählt werden, die in ihrem Feld ID den gleichen Wert aufweisen, der auch in der Kategorienliste markiert ist (lstKategorien.Value), benötigen wir eine Zwischenabfrage, denn die Herstellertabelle kennt selbst keine Kategorien. Das ist ein schönes Beispiel für den Einsatz der IN-Klausel. Aus tblArtikel ermittelt die Select-Abfrage innerhalb der Klammer alle Datensätze, deren Kategorien (IDKategorie) mit dem markierten Eintrag des Listenfelds übereinstimmen und gibt aus ihren nur jeweils die IDHersteller zurück. Befindet sich wiederum eine ID der Herstellertabelle IN diesem Pool, so ist die Bedingung positiv und der Datensatz mitsamt der Herstellerbezeichnung wird ausgegeben, so dass er im Kombinationsfeld erscheinen kann.
Private Sub lstKategorien_AfterUpdate() ... Me!cbHerstellerFilter.RowSource = "SELECT * FROM tblHersteller " & _ "WHERE ID IN(SELECT IDHersteller FROM tblArtikel WHERE IDKategorie=" & _ Me!lstKategorien.Value & ")" ... End Sub
Listing 1: Setzen der Datenherkunft der Hersteller-Combobox cbHersteller
Sie interessieren sich für den Deskjet T730 und haben ihn in der Produktliste markiert. Seine Details gibt nun das Unterformular rechts im Bild wieder. Den Preis finden Sie OK und Sie klicken auf den Button In den Warenkorb. Damit erscheint sogleich in einer Msgbox die Info aus Bild 2. Klicken Sie erneut auf den Button, so zeigt sich eine abweichende Meldung (Bild 3).
Bild 2: Info zum Warenkorb
Bild 3: Info zum Warenkorb bei wiederholtem Hinzufügen
Die beim Klicken auf den Button cmdAdd ausgelöste Prozedur finden Sie in Listing 2.
Private Sub cmdAdd_Click() Dim n As Long Dim ID As Long n = Nz(DLookup("Anzahl", "tblBestellDetails", "ArtikelID=" & Me!ID.Value & _ " AND BestellID=" & BestellID)) If n = 0 Then CurDB.Execute "INSERT INTO tblBestellDetails" & _ " (BestellID,ArtikelID,Anzahl,Netto,Ust)" & _ " VALUES (" & BestellID & "," & Me!ID.Value & ",1," & _ Str(Me!Netto.Value) & "," & Str(Me!USt.Value) & ")" MsgBox "Sie haben '" & Me!Produkt & "' in den Warenkorb gelegt.", vbInformation Else ID = DLookup("ID", "tblBestellDetails", "ArtikelID=" & Me!ID.Value & _ " AND BestellID=" & BestellID) CurDB.Execute "UPDATE tblBestellDetails SET Anzahl=" & (n + 1) & _ " WHERE ID=" & ID MsgBox "Sie haben die Anzahl von '" & Me!Produkt & "' im Warenkorb erhöht." End If Me!cbWarenkorb.Requery End Sub
Listing 2: Das Legen eines Produkts in den Warenkorb über den Button cmdAdd
In der ersten Zeile ermittelt eine DLookup-Funktion zunächst die Anzahl jener Artikel, die sich bereits in der Bestellung befinden, wobei nach dem aktuell ausgewählten Produkt (ArtikelID = Me!ID) und nach der momentanen Bestellung (BestellID) gefiltert wird. Im ersten Betrag wurde erläutert, dass schon beim öffnen des Shop-Formulars ein temporärer Bestelldatensatz in der Tabelle tblBestellDetails angelegt und ein Verweis auf dessen ID in der globalen Variablen BestellID abgespeichert wird. Hier nun kommt diese ID zum Tragen. Ist der Artikel bereits in der Bestellung vorhanden, so gibt DLookup einen von 0 abweichenden Wert zurück und weist diesen der Variablen n zu. Die Prozedur verzweigt jetzt in Abhängigkeit von diesem Wert.
Ist der Artikel neu, was den einfacheren Fall darstellt so findet das Einfügen eines Datensatzes über die INSERT INTO-Anweisung statt. Ihr werden als Feldparameter die aktuelle BestellID, der Preis (Me!Netto) und der Umsatzsteuersatz (Me!Ust) verabreicht. Diese letzten beiden Werte können nicht aus der Artikeltabelle entnommen werden! Denn bald könnte sich der Preis ja ändern, was bei Bearbeitung der Bestellung zu einer erhöhten Summe führen würde.
Hier muss der aktuelle Preis gelten, weshalb er fest in den Bestelldatensatz gespeichert werden muss. Die anschließende MsgBox zeigt nun lediglich das Produkt (Me!Produkt) in einem entsprechenden Text an.
Ist der Artikel in der Bestellung bereits vorhanden, also der Wert von n ungleich 0, so führt sich der nächste Zweig der Prozedur aus. Hier muss erst ermittelt werden, welche ID der betreffende Bestelldatensatz hat, wobei abermals eine DLookup-Funktion verwendet wird. Anschließend erhöht eine SQL-UPDATE-Anweisung den Wert des Felds Anzahl im gefundenen Datensatz. Die Meldung sieht nun geringfügig anders aus.
Auf die Bedeutung der letzten Zeile, die ein Requery auf das Kombinationsfeld cbWarenkorb auslöst, kommen wir gleich zu sprechen.
Die SQL-Anweisungen geschehen übrigens über die Objektvariable CurDB. Das ist tatsächlich eine Funktion, die nur die Access-Eigenschaft CurrentDb ersetzt. Sie befindet sich im Modul mdlShop der Datenbank (Listing 3). Die im Kopf des Moduls deklarierte Objektvariable thisdb bekommt beim ersten Aufruf der Funktion den Inhalt von CurrentDb verpasst. Forthin gibt sie deren Wert zurück. Der Vorteil der Funktion ist, neben kürzerer Schreibweise, eine bessere Performance.
Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...
Testzugang
eine Woche kostenlosen Zugriff auf diesen und mehr als 1.000 weitere Artikel
diesen und alle anderen Artikel mit dem Jahresabo