Rechnungsverwaltung: Kundendetails

Eine Rechnungsverwaltung, mit der Rechnungen an verschiedene Kunden geschickt werden sollen, benötigt eine Tabelle zum Speichern diese Kunden. Logisch, dass wir dieser Tabelle auch ein Formular zum komfortablen Bearbeiten der Kunden an die Seite stellen. Dieses enthält allerdings nicht nur die reinen Kundendaten, sondern wir wollen damit auch noch die Bestellungen des jeweiligen Kunden in einem Unterformular anzeigen – und darüber die Anzeige der Bestelldetails zu ermöglichen.

Unterformular sfmKundeDetails für die Bestellungen

Wir beginnen direkt mit dem Entwurf des Unterformulars zur Anzeige der Bestellungen des Kunden. Dieses wollen wir sfmKundeDetails nennen. Diesem fügen wir über die Eigenschaft Datensatzquelle gleich die Tabelle tblBestellungen hinzu.

Im Gegensatz zum Unterformular aus dem Beitrag Rechnungsverwaltung: Bestellübersicht (www.access-im-unternehmen.de/****), wo wir alle Bestellungen inklusive der Angabe des jeweiligen Kunden in einem Unterformular darstellen, benötigen wir hier nicht mehr die Anzeige des Kunden – dieser wird ja schon im Hauptformular angezeigt, das wir gleich noch erstellen werden. Also fügen wir nun die Felder Bestellnummer, RechnungAm, Zahlungsziel, BezahltAm und StorniertAm zum Detailbereich des Formularentwurfs hinzu.

Dieser sieht anschließend wie in Bild 1 aus. Damit die Daten in der Datenblattansicht angezeigt werden, legen wir die Eigenschaft Standardansicht dort auf den Wert Datenblatt fest. Außerdem wollen wir, dass der Kunde die Daten in diesem Unterformular nicht direkt bearbeiten kann. Daher legen wir die Eigenschaften Anfügen zulassen, Löschen zulassen und Bearbeitungen zulassen jeweils auf den Wert Nein ein. Damit können wir die Arbeiten an diesem Formular vorerst beenden und dieses schließen.

Entwurf des Unterformulars sfmKundeDetails

Bild 1: Entwurf des Unterformulars sfmKundeDetails

Hauptformular frmKundeDetails anlegen

Danach legen wir ein weiteres Formular namens frmKundeDetails an. Bevor wir diesem das Unterformular sfmKundeDetails hinzufügen, müssen wir die Datensatzquelle für das Hauptformular festlegen. So kann Access direkt erkennen, dass es zwischen den Datensatzquellen von Haupt- und Unterformular eine Beziehung gibt und dies entsprechend in den Eigenschaften Verknüpfen von und Verknüpfen nach des Unterformular-Steuerelements vermerken.

Wenn wir schon die Datensatzquelle definiert haben, können wir auch direkt die gewünschten Felder aus der Feldliste in den Detailbereich des Formulars ziehen. Dabei berücksichtigen wir alle Felder mit Ausnahme des Feldes ID, das nur zu Verknüpfungszwecken gepflegt wird und für den Benutzer unsichtbar bleiben soll (siehe Bild 2).

Entwurf des Hauptformulars frmKundeDetails

Bild 2: Entwurf des Hauptformulars frmKundeDetails

Falls Sie sich wundern, dass in unserem Formular beispielsweise für das Feld AnredeID ein Beschriftungsfeld mit dem Text Anrede angelegt wurde: Wir haben direkt im Tabellenentwurf die für die Bezeichnungsfelder gewünschten Texte für die Eigenschaft Beschriftung der jeweiligen Felder hinterlegt. Mehr dazu erfahren Sie im Beitrag Bezeichnungsfelder im Griff (www.access-im-unternehmen.de/****).

Unterformular zum Hauptformular hinzufügen

Danach teilen wir die Felder auf zwei Spalten auf, sodass wir unten das Unterformular sfmKundeDetails platzieren können. Dieses ziehen wir aus dem Navigationsbereich in den Formularentwurf und erhalten nach wenigen Anpassungen das Ergebnis aus Bild 3. Zu diesen Anpassungen gehört neben der Ausrichtung und der Einstellung der Größe das Festlegen der Eigenschaften Horizontaler Anker und Vertikaler Anker jeweils auf den Wert Beide. Damit wird das Unterformular mit dem Hauptformular vergrößert.

Das Hauptformular frmKundeDetails mit dem Unterformular

Bild 3: Das Hauptformular frmKundeDetails mit dem Unterformular

Gegebenenfalls können Sie sich nun noch davon überzeugen, dass Access automatisch das Primärschlüsselfeld ID der Tabelle tblKunden für die Eigenschaft Verknüpfen nach und das Fremdschlüsselfeld KundeID der Tabelle tblBestellungen für die Eigenschaft Verknüpfen von eingetragen hat. Dies stellt sicher, dass das Unterformular immer nur die Datensätze der Tabelle tblBestellungen anzeigt, die mit dem Datensatz der Tabelle tblKunden aus dem Hauptformlar verknüpft sind.

Da wir bereits einige Beispieldatensätze angelegt haben, wie im Beitrag Rechnungsverwaltung: Beispieldaten (www.access-im-unternehmen.de/****) beschrieben, finden wir beim Wechsel in die Formularansicht bereits einige Beispieldaten vor (siehe Bild 4).

Ein Kunde und seine Bestellungen

Bild 4: Ein Kunde und seine Bestellungen

Validierung im Hauptformular

Damit können wir uns nun um die Validierung der Eingabefelder im Hauptformular kümmern. Hier sind Einschränkungen bei folgenden Feldern nötig:

  • Anrede: Pflichtfeld
  • Vorname, Nachname, Straße, Ort, Land: Pflichtfelder
  • PLZ: Ausgehend von der vereinfachenden Annahme, wir hätten es mit Adressen aus dem Bereich Deutschland, Österreich und der Schweiz zu tun, muss diese fünf Stellen (für Deutschland) oder vier Stellen (für Österreich und Schweiz) aufweisen.
  • E-Mail: Diese soll grob validiert werden, also auf ein enthaltenes @-Zeichen und einen Punkt.
  • Ust-IDNr.: Soll für Deutschland und Österreich geprüft werden auf DE plus neun Ziffern beziehungsweise auf ATU plus acht Ziffern, für Schweiz muss das Feld leer sein.

Da Pflichtfelder nur beim Speichern des kompletten Datensatzes geprüft werden können und dies für die abhängigen Felder ohnehin der Fall ist, können wir uns hier auf das Ereignis Vor Aktualisierung des Formulars konzentrieren.

Für dieses hinterlegen wir die Prozedur aus Listing 1. Das Ereignis wird nur beim Versuch ausgelöst, den Datensatz nach vorherigen Änderungen zu speichern – also etwa beim Wechsel zu einem anderen Datensatz oder beim Speichern mit der Tastenkombination Strg + S.

Private Sub Form_BeforeUpdate(Cancel As Integer)
     If Len(Nz(Me!txtKundennummer, "")) = 0 Then
         MsgBox "Bitte geben Sie eine Kundennummer ein.", vbOKOnly + vbExclamation, "Kundennummer fehlt"
         Me!txtKundennummer.SetFocus
         Cancel = True
         Exit Sub
     End If
     If Nz(Me!cboAnredeID, 0) = 0 Then
         MsgBox "Bitte wählen Sie eine Anrede aus.", vbOKOnly + vbExclamation, "Anredefehlt"
         Me!cboAnredeID.SetFocus
         Cancel = True
         Exit Sub
     End If
     If Len(Nz(Me!txtVorname, "")) = 0 Then
         MsgBox "Bitte geben Sie einen Vornamen ein.", vbOKOnly + vbExclamation, "Vorname fehlt"
         Me!txtVorname.SetFocus
         Cancel = True
         Exit Sub
     End If
     If Len(Nz(Me!txtStrasse, "")) = 0 Then
         MsgBox "Bitte geben Sie eine Straße ein.", vbOKOnly + vbExclamation, "Straße fehlt"
         Me!txtStrasse.SetFocus
         Cancel = True
         Exit Sub
     End If
     If Len(Nz(Me!txtPLZ, "")) = 0 Then
         MsgBox "Bitte geben Sie eine PLZ ein.", vbOKOnly + vbExclamation, "PLZ fehlt"
         Me!txtPLZ.SetFocus
         Cancel = True
         Exit Sub
     End If
     If Len(Nz(Me!txtOrt, "")) = 0 Then
         MsgBox "Bitte geben Sie einen Ort ein.", vbOKOnly + vbExclamation, "Ort fehlt"
         Me!txtOrt.SetFocus
         Cancel = True
         Exit Sub
     End If
     If Len(Nz(Me!cboLand, 0)) = 0 Then
         MsgBox "WählenSie ein Land aus.", vbOKOnly + vbExclamation, "Land fehlt"
         Me!cboLand.SetFocus
         Cancel = True
         Exit Sub
     End If
     If Len(Nz(Me!txtEMail, "")) = 0 Then
         MsgBox "Bitte geben Sie eine E-Mail-Adresse ein.", vbOKOnly + vbExclamation, "E-Mail-Adresse fehlt"
         Me!txtEMail.SetFocus
         Cancel = True
         Exit Sub
     End If
End Sub

Listing 1: Validieren beim Speichern des Datensatzes

Vorab die Information, dass wir alle gebundenen Steuerelemente mit Präfixen versehen haben, in diesem Fall die Textfelder mit txt und die Kombinationsfelder mit cbo. Auf diese Weise kann man sauber zwischen den Feldnamen der Datensatzquelle und den daran gebundenen Steuerelementen unterscheiden.

Diese Prozedur enthält einige If…Then-Bedingungen, die jeweils eine Überprüfung für ein Feld vornehmen. Die erste untersucht beispielsweise, ob das Feld txtFirma leer ist. Ist das der Fall, erscheint eine entsprechende Meldung, der Fokus wird auf das Textfeld eingestellt und der Rückgabeparameter Cancel auf den Wert True.

Außerdem verlassen wir an dieser Stelle mit Exit Sub die Prozedur. Das Einstellen des Parameters Cancel auf True sorgt dafür, dass der Speichern-Vorgang, der das Ereignis Vor Aktualisierung ausgelöst hat, abgebrochen wird.

Validieren der E-Mail-Adresse

Die E-Mail-Adresse können wir direkt nach der Eingabe validieren und den Benutzer darauf hinweisen, falls die E-Mail-Adresse nicht gültig ist. Deshalb reicht es auch aus, dass wir in der Prozedur Form_BeforeUpdate nur auf eine leere Zeichenkette prüfen. Sobald der Benutzer einmal ein Zeichen für die E-Mail eingegeben hat, kann er dieses nur nach Eingabe einer gültigen E-Mail-Adresse verlassen.

Wie Sie die Gültigkeit einer E-Mail-Adresse überprüfen, haben wir im Beitrag E-Mail-Adressen validieren per VBA (www.access-im-unternehmen.de/****) beschrieben. Die dortige Funktion CheckEMailSyntax verwenden wir auch in diesem Formular, um die E-Mails nach der Eingabe zu prüfen. Dazu hinterlegen wir für das Ereignis Vor Aktualisierung des Textfelds txtEMail die Prozedur aus Listing 2.

Private Sub txtEMail_BeforeUpdate(Cancel As Integer)
     Dim strEMail As String
     strEMail = Nz(Me!txtEMail, "")
     If Not CheckEMailSyntax(strEMail) Then
         MsgBox "Die E-Mail-Adresse ''" & strEMail & "'' ist nicht gültig.", vbOKOnly + vbExclamation, "Ungültige E-Mail"
         Cancel = True
     End If
End Sub

Listing 2: Prozedur zum Prüfen von E-Mails direkt nach der Eingabe

Sie haben das Ende des frei verfügbaren Textes erreicht. Möchten Sie ...

TestzugangOder bist Du bereits Abonnent? Dann logge Dich gleich hier ein. Die Zugangsdaten findest Du entweder in der aktuellen Print-Ausgabe auf Seite U2 oder beim Online-Abo in der E-Mail, die Du als Abonnent regelmäßig erhältst:

Schreibe einen Kommentar