Im ersten Teil dieser Beitragsreihe haben wir uns angesehen, wie Sie per Webservice einige Informationen Ihrer Bank einlesen und einfache Funktionen wie das Ermitteln einer IBAN aus Kontonummer und Bankleitzahl durchführen. In vorliegenden zweiten Teil gehen wir einen Schritt weiter: Sie erfahren, wie Sie den Kontostand und die Umsätze einlesen und wie Sie überweisungen durchführen können. Dies alles geschieht weiterhin per Webservice, Sie benötigen also nichts außer Ihrer Datenbankanwendung und einer Internetverbindung für diese Funktionen.
Datenbank vorbereiten
Bevor wir in die Onlinebanking-Materie einsteigen, bereiten wir die Beispieldatenbank auf die folgenden Anforderungen vor. Diese sollen beispielsweise die Kontakte speichern (also die eindeutigen Verbindungen zur Bank), die Kontodaten, die Umsätze und weitere Informationen.
Tabellen zum Speichern der Kontakte
Die erste Tabelle heißt dann auch gleich tblKontakte und nimmt die Felder aus Bild 1 auf. Die BLZ, die Benutzerkennung und die Teilnehmernummer (Letztere sind mitunter identisch) können Sie den Unterlagen Ihres Kreditinstituts zum Onlinebanking entnehmen. Die beiden übrigen Felder finden Sie dort nicht vor:
Bild 1: Tabellen zum Speichern der Onlinebanking-Kontakte
- ContactData: Dies ist ein Wert, der nach der erstmaligen Anmeldung mit BLZ, Benutzerkennung, Teilnehmernummer und PIN von der Bank generiert wird und der für weitere Zugriffe benötigt wird.
- Bankinfo: Informationen über die Bank und den abgefragten Kontakt mit den Kontodaten der Konten dieses Kontakts
Ablauf beim Zugriff
Der grundsätzliche Ablauf beim Zugriff über den Webservice sieht so aus, dass in einer ersten Abfrage der Wert von ContactData ermittelt wird, für den die übermittlung der Kontaktdaten (also Bankleitzahl, Benutzerkennung et cetera) erforderlich ist. Diesen Wert können Sie lokal speichern und ihn wiederverwenden oder sie lesen ihn vor jedem Zugriff erneut ein. Bei der Abfrage des Kontostandes, der Umsätze oder bei der Durchführung einer überweisung übergeben Sie dann nur noch die in ContactData verschlüsselten Daten des Kontaktes, sodass diese nicht einfach abgegriffen und einem Konto zugeordnet werden können.
Das Gleiche geschieht später beim Einlesen der Konten: Hier verschlüsselt der Webservice die Kontodaten in einem Element namens AccountId.
Tabelle zum Speichern der Kontodaten
Die Tabelle tblKonten aus Bild 2 speichert die Informationen je Konto. Damit sind wir gleich darauf vorbereitet, dass ein Kontakt einmal mehr als nur ein Konto verwendet – also beispielsweise mehrere Girokonten. Der Sinn der meisten Felder erschließt sich aus der Abbildung. Wichtig ist das Feld AccountId. Dieses nimmt einen eindeutigen Identifizierer auf, der für den Zugriff auf den Kontostand oder die Umsätze sowie für die Durchführung von überweisungen benötigt wird.
Bild 2: Tabellen zum Speichern der Kontodaten
Die Datensätze der Tabelle tblKonten werden über das Feld KontaktID mit der Tabelle tblKontakte verknüpft, jedes Konto kann also logischerweise nur einem einzigen Kontakt zugewiesen werden.
Daten ermitteln
Nachdem wir die Tabellen zum Speichern von Kontakten und Kontodaten erstellt haben, benötigen wir noch ein Formular namens frmKonten, von dem aus wir die Aktionen wie etwa das Einlesen der Kontodaten starten. Das Formular soll zunächst zwei Kombinationsfelder enthalten, von denen das erste der Auswahl des Kontakts dient. Das zweite soll dann alle Konten zu diesem Kontakt zur Auswahl anbieten. Außerdem fügen wir dem Formular bereits zwei Schaltflächen hinzu (s. Bild 3):
Bild 3: Formular zum Verwalten von Kontakten und Konten
- cmdNeuerKontakt: Soll ein Formular zum Eintragen eines neuen Kontakts öffnen.
- cmdKontakteAktualisieren: Soll die Informationen zum aktuellen Kontakt neu einlesen.
Die Schaltfläche cmdNeuerKontakt soll ein weiteres Formular namens frmKontaktdetails öffnen, mit dem der Benutzer einen neuen Kontakt anlegen soll.
Das Formular frmKontaktdetails
Dieses Formular verwendet die Tabelle tblKontakte als Datenherkunft und zeigt die drei Felder BLZ, Benutzerkennung und Teilnehmernummer an (s. Bild 4).
Bild 4: Formular zum Anlegen von Kontakten
Die Schaltfläche cmdOK schließt das Formular lediglich:
Private Sub cmdOK_Click() DoCmd.Close acForm, Me.Name End Sub
Neuen Kontakt anlegen
Um mit dem Formular frmKontaktdetails einen neuen Kontakt anzulegen, soll dieses durch einen Klick auf die Schaltfläche cmdNeuerKontakt des Formulars frmKonten geöffnet werden. Nach dem Schließen des als modaler Dialog geöffneten Formulars aktualisiert das Formular die Liste der Kontakte im Kombinationsfeld cboKontakte:
Private Sub cmdNeuerKontakt_Click() DoCmd.OpenForm "frmKontaktdetails", _ WindowMode:=acDialog, DataMode:=acFormAdd Me!cboKontakte.Requery End Sub
Das Kombinationsfeld cboKontakte zeigt alle Datensätze der Tabelle tblKontakte an, wobei wir fast alle Felder der Tabelle verwenden. Die anzuzeigende Spalte soll einen aus der Bankleitzahl, der Teilnehmernummer und der Benutzerkennung zusammengesetzten Ausdruck liefern. Daher haben wir die Datensatzherkunft für das Kombinationsfeld wie folgt formuliert:
SELECT KontaktID, [BLZ] & "|" & [Teilnehmernummer] & "|" & [Benutzerkennung] AS Kontakt, BLZ, Teilnehmernummer, Benutzerkennung, ContactData FROM tblKontakte;
Damit das Kombinationsfeld nur das zweite Feld der Datensatzherkunft anzeigt, aber die anderen bei Bedarf über das Kombinationsfeld abgefragt werden können, stellen wir die Eigenschaft Spaltenanzahl auf 6 und die Eigenschaft Spaltenbreiten auf 0cm;;0cm;0cm;0cm;0cm ein.
Kontakt aktualisieren
Damit kommen wir zu der Schaltfläche cmdKontenAktualisieren, welche die Informationen zum aktuell im Kombinationsfeld cboKontakte ausgewählten Kontakt ermittelt.
Diese löst die Prozedur aus Listing 1 aus, die lediglich den Wert des Feldes ContactData der Tabelle tblKontakte für den aktuell ausgewählten Kontakt leert. Danach ruft sie die Prozedur cboKontakte_AfterUpdate auf, die außerdem beim Aktualisieren des Wertes des Kombinationsfeldes cboKontakte ausgelöst wird.
Private Sub cmdKontaktAktualisieren_Click() Dim db As DAO.Database Set db = CurrentDb db.Execute "UPDATE tblKontakte SET ContactData = NULL WHERE KontaktID = " _ & Me!cboKontakte, dbFailOnError cboKontakte_AfterUpdate Set db = Nothing End Sub
Listing 1: Start der Aktualisierung eines Kontakts
Diese Prozedur finden Sie in Listing 2.
Private Sub cboKontakte_AfterUpdate() Dim strContactData As String Dim strBLZ As String Dim strCustomerID As String Dim strUserID As String Dim lngKontaktID As Long strBLZ = Me!cboKontakte.Column(2) strCustomerID = Me!cboKontakte.Column(4) strUserID = Me!cboKontakte.Column(3) lngKontaktID = Me!cboKontakte If IsNull(DLookup("ContactData", "tblKontakte", "KontaktID = " & lngKontaktID)) Then strContactData = Anmelden(strBLZ, strCustomerID, strUserID) End If Me!cboKonten.RowSource = "SELECT * FROM qryCboKonten WHERE KontaktID = " & lngKontaktID Me!cboKonten = Me!cboKonten.ItemData(0) cboKonten_AfterUpdate End Sub
Listing 2: Prozedur, die bei der Aktualisierung des aktuellen Kontakts ausgelöst wird
Sie liest zunächst einige Werte aus den nicht sichtbaren Spalten des Kombinationsfeldes aus und speichert diese in Variablen wie strBLZ, strCustomerID, strUserID und lngKontaktID.
Nun folgt eine Prüfung, ob das Feld ContactData für diesen Kontakt leer ist. Dies ist der Fall, wenn die Daten des Kontakts noch nie eingelesen wurden oder der Benutzer zuvor auf die Schaltfläche cmdKontaktAktualisieren geklickt hat, die ja dieses Feld für den aktuellen Kontakt leert.
In diesem Fall ruft die Prozedur eine weitere Funktion namens Anmelden auf, der sie die Bankleitzahl, die Benutzerkennung und die Teilnehmernummer übergibt – mehr dazu weiter unten.
Danach ist jedenfalls die Tabelle tblKonten mit den Konten zu diesem Kontakt gefüllt. Die folgenden Anweisungen filtern dann das Kombinationsfeld cboKonten nach dem soeben ausgewählten beziehungsweise aktualisierten Kontakt, wählen den ersten Eintrag aus und rufen eine weitere Prozedur namens cboKonten_AfterUpdate auf, die auch ausgelöst wird, wenn der Benutzer manuell den Wert des Kombinationsfeldes cboKonten ändert.
Anmelden und Kontaktdaten einlesen
Die Funktion Anmelden aus Listing 3 erwartet die Bankleitzahl, die Benutzernummer und die Teilnehmernummer als Parameter und soll die Kontaktdaten in Form eines XML-Dokuments zurückliefern. Dazu ist zunächst die Abfrage der PIN für diesen Kontakt erforderlich – also die Zeichenfolge, mit der Sie sich auch für Onlinebanking anmelden. Diese fragt die Funktion per InputBox ab und speichert sie in der Variablen strPIN. Danach folgt der Aufruf einer weiteren Funktion namens CreateContactDirectRequest. Diese leistet den eigentlich Zugriff auf den Bankserver und liefert das gewünschte XML-Dokument als String-Variable zurück (Erläuterung zu dieser Funktion siehe weiter unten). Beim Aufruf übergeben wir einige Werte per Parameter, andere Parameter sollen die Rückmeldungen des Webservice an die aufrufende Funktion zurückliefern. Das Ergebnis landet schließlich in der Variablen strContactData.
Public Function Anmelden(strBLZ As String, strCustomerID As String, strUserID As String) _ As String Dim objXML As MSXML2.DOMDocument Dim objNode As MSXML2.IXMLDOMNode Dim db As DAO.Database Dim strContactData As String Dim lngKontaktID As Long Dim strResponse As String Dim strPIN As String Dim strErrorType As String Dim strErrorText As String Dim strErrorCustomerText As String strPIN = InputBox("PIN") strContactData = CreateContactDirectRequest(strBLZ, strUserID, strCustomerID, strPIN, _ strResponse, strErrorType, strErrorText, strErrorCustomerText) If Len(strErrorType) = 0 Then KontenEinlesen strResponse lngKontaktID = DLookup("KontaktID", "tblKontakte", _ "BLZ = ''" & strBLZ & "'' AND Benutzerkennung = ''" _ & strCustomerID & "'' AND Teilnehmernummer = ''" & strUserID & "''") Set objXML = New MSXML2.DOMDocument objXML.loadXML strResponse Set objNode = objXML.selectSingleNode("//CreateContactDirectRequestResult") Set db = CurrentDb db.Execute "UPDATE tblKontakte SET ContactData = ''" & strContactData _ & "'', BankInfo = ''" _ & FormatXML(objNode.XML) & "'' WHERE KontaktID = " & lngKontaktID, dbFailOnError SecurityFunctionsAktualisieren db, objNode, lngKontaktID GeschaeftsvorfaelleAktualisieren db, objNode Anmelden = strContactData Else MsgBox "Fehler: " & vbCrLf & vbCrLf & strErrorCustomerText End If End Function
Listing 3: Anmelden an den Bankserver und ermitteln einiger Daten zum aktuellen Kontakt
Sollte die Funktion CreateContactDirectRequest den Parameter strErrorType mit einem Wert ungleich 0 füllen, ist kein Fehler aufgetreten und die gelieferten Daten können verarbeitet werden.
Die Prozedur ruft dann die Prozedur KontenEinlesen auf, welche die Kontoinformationen einliest und in der Tabelle tblKonten speichert (siehe weiter unten). Dieser übergibt sie den Wert aus strResponse. Wie der Inhalt dieser Variablen aussieht, schauen wir uns ebenfalls weiter unten an.
Dann ermittelt die Prozedur den Primärschlüsselwert des Kontakts, für den soeben die Daten neu eingelesen wurden, und speichert diesen in der Variablen lngKontaktID.
Ein neues DOMDocument-Objekt namens objXML wird mit dem Inhalt der Antwort des Webservice-Aufrufs aus strResponse gespeist. Uns interessiert hier das Element CreateContactDirectRequestResult, das wir in die IXMLDOMNode-Variable objNode einlesen. Dieses Objekt verarbeiten wir aber auch nicht direkt in dieser Prozedur, sondern übergeben es noch an weitere Prozeduren, die jeweils einen Teil des XML-Dokuments analysieren.
Zuvor schreibt die Prozedur dieses aber auf jeden Fall in das Feld ContactData des betroffenen Datensatzes in der Tabelle tblKontakte.
Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...
den kompletten Artikel im PDF-Format mit Beispieldatenbank
diesen und alle anderen Artikel mit dem Jahresabo