André Minhorst, Duisburg
Bei der Arbeit mit Computeranwendungen treten zwangsläufig Eingabefehler auf und es gibt keine Validierung, die hundertprozentig vor nicht gewünschten Eingaben schützt. So auch beim Fahrtenbuch, das in Ausgabe 2/2003 von Access im Unternehmen vorgestellt wurde: Man kann einmal eingegebene Fahrten nicht mehr stornieren, und somit mussten die Daten noch einmal neu eingegeben werden. Um dieses Manko zu beheben, lernen Sie im vorliegenden Beitrag einige Erweiterungen für das Fahrtenbuch kennen.
Die neue Version des Fahrtenbuchs enthält einige änderungen. Die wichtigste änderung ist, dass es von nun an die Möglichkeit gibt, den letzten eingegebenen Datensatz zu stornieren und noch einmal an der Stelle vor Eingabe des letzten Datensatzes zu beginnen.
Außerdem gibt es zwei kleinere änderungen: Wenn man mit der bisherigen Version des Fahrtenbuchs die Fahrten, den Verbrauchsbericht oder die Ausgaben ausgeben wollte, wurde die Berichtsvorschau nur in verkleinerter Ansicht angezeigt. Nun können Sie alle Berichte in beliebiger Größe anzeigen, bevor Sie den Druckvorgang mit der entsprechenden Schaltfläche initiieren. Außerdem zeigte die Verbrauchsübersicht bisher in manchen Fällen den Wert #Fehler an. Auch dieser Fehler ist behoben. Und wenn Sie schon mit der Vorgängerversion des Fahrtenbuchs gearbeitet haben, möchten Sie vermutlich nicht alle Daten erneut mit der neuen Version eingeben. In dem Fall finden Sie eine Import-Funktion für die einfache und schnelle übernahme Ihrer bestehenden Daten.
Die erste Version des Fahrtenbuchs, das Sie im Beitrag Fahrtenbuch in Ausgabe 2/2003 kennen lernen konnten und das auch unter www.access-im-unternehmen.de als Businesslösung zum Download bereitsteht, enthält keine Möglichkeit, einmal getätigte Eingaben zu redigieren. Diese Einstellung hat den Sinn, die Anwendung „finanzamttauglich“ zu machen.
Damit das Fahrtenbuch in elektronischer Form dort anerkannt wird, darf es entweder gar keine Möglichkeit geben, einmal eingegebene Fahrten nachträglich zu manipulieren, oder die änderungen müssen als solche gekennzeichnet werden. Unter der Prämisse, dass eine auffällig gestaltete Sicherheitsabfrage bezüglich der Richtigkeit der Daten ausreichen würde, um Fehleingaben zu vermeiden, wurde damals erstere Variante aufgegriffen.
Im Laufe der Zeit wandelt sich jedoch auch das Bestätigen der Rückfrage vor dem Speichern von Daten in das nervige Wegklicken einer nicht mehr gelesenen Meldung; die erste Eingabe einer Fahrt mit 1000 statt 100 gefahrenen Kilometern lässt nicht mehr lange auf sich warten.
Hinweis
Die erste in Access im Unternehmen 2/2003 vorgestellte Version des Fahrtenbuchs und die unter der Rubrik Businesslösungen auf www.access-im-unternehmen.de veröffentlichte Version unterscheiden sich bereits enorm voneinander. Der vorliegende Beitrag beschreibt die änderungen, die an der letzten Version der Businesslösung vorgenommen werden, um den in diesem Beitrag beschriebenen Stand zu erreichen. Auch die Beschreibung der Routine zum Import bestehender Daten bezieht sich auf den Import von der Fahrtenbuch-Businesslösung. Diese kann aber leicht der Version aus Heft 2/2003 angepasst werden.
Stornieren des letzten Datensatzes
Damit man die Daten nicht nach jedem Eingabefehler erneut in eine blanko Fahrtenbuchdatenbank eingeben muss, enthält die nachfolgend vorgestellte neue Version des Fahrtenbuchs zwei änderungen:
Finanzamttauglichkeit
Die Finanzamttauglichkeit der Anwendung lassen Sie sich am besten vor der Benutzung von Ihrem Finanzamt bestätigen.
Da der letzte eingegebene Datensatz für jedes Fahrzeug storniert werden kann, bedingt dies natürlich eine nachträgliche änderung dieses Datensatzes.
Um den Anforderungen einer finanzamttauglichen Fahrtenbuchanwendung gerecht zu werden und stornierte Datensätze nach wie vor auszugeben und noch dazu als storniert zu kennzeichnen, gehen Sie folgendermaßen vor:
Möglicherweise fragen Sie sich, warum eine neue Tabelle für das Speichern der letzten Fahrt für jedes Fahrzeug herhalten muss und diese nicht direkt in die Tabelle tblFahrten eingetragen wird.
Der Grund ist, dass einmal in die Tabelle tblFahrten eingetragene Fahrten nicht mehr geändert oder gelöscht werden können. Da aber die letzte Fahrt eines jeden Fahrzeugs noch als „Storniert“ gekennzeichnet werden können soll, wird diese in einer separaten Tabelle gespeichert.
Erst wenn der nächste Fahrtdatensatz für ein Fahrzeug eingegeben wurde, wird der aktuelle letzte Datensatz in die Tabelle tblFahrten geschrieben.
Und wenn der letzte Datensatz storniert werden soll, wird zunächst dessen Feld Storniert auf den Wert Ja gesetzt, der Datensatz in die Tabelle tblFahrten kopiert und aus der Tabelle tblLetzteFahrt gelöscht.
Anpassen der Tabelle tblFahrten
Beginnen Sie mit dem ersten Schritt, der Anpassung der Tabelle tblFahrten. Das Hinzufügen des zusätzlichen Feldes stellt keine sonderlich große Hürde dar. Der Entwurf der Tabelle sieht anschließend wie in Bild 1 aus.
Private Sub Form_Open(Cancel As Integer) If IstFormularGeoeffnet("frmFahrten") = 0 Or IsNull(Me.OpenArgs) Then MsgBox "Dieses Formular kann nur vom Hauptformular aus geöffnet werden.", _ vbExclamation + vbOKOnly, "Fahrtenbuch" Cancel = True End If Me.txtFahrzeug = Forms!frmFahrten!txtFahrzeug Me.txtStartDatum = Date Me.txtZielDatum = Date If DCount("FahrtID", "qryFahrten", "Kennzeichen = ''" & Me.txtFahrzeug & "''") = 0 _ Then Me.txtStartkmStand = DLookup("Startkilometerstand", "tblFahrzeuge", _ "Kennzeichen = ''" & Me.txtFahrzeug & "''") Else Me.txtStartkmStand = DMax("ZielkmStand", "qryFahrten", "Kennzeichen = ''" _ & Me.txtFahrzeug & "'' AND Storniert = False") End If End Sub
Quellcode 1
Bild 1: Angepasstes Datenmodell der Tabelle tblFahrten
Tabelle zum Speichern der letzten Fahrt
Die Tabelle tblLetzteFahrt hat die gleichen Felder wie die Tabelle tblFahrten. Der einzige Unterschied ist, dass die Daten der Tabelle nicht vor dem Bearbeiten und Löschen geschützt sind.
Anpassen des Vorgangs zumAnlegen neuer Fahrten
Neue Fahrten werden in der neuen Fassung des Fahrtenbuchs nicht mehr direkt in die Tabelle tblFahrten geschrieben, sondern zunächst in der Tabelle tblLetzteFahrt gespeichert. Dementsprechend muss das Formular zum Anlegen neuer Fahrten angepasst werden.
Das beginnt mit der Prozedur, die beim öffnen des Formulars gestartet wird und die zur Ermittlung des Zielkilometerstands der alten und damit des Startkilometerstands der neuen Fahrt dient. Die Prozedur sieht nun wie in Quellcode 1 aus. Nach dem Eintragen des aktuellen Fahrzeugs sowie des Start- und Enddatums in das Formular überprüft die Prozedur, ob bereits eine Fahrt für das aktuelle Fahrzeug vorhanden ist. Falls nein, wird der Kilometerstand aus der Tabelle tblFahrzeuge bei Aufnahme des Fahrzeugs in das Fahrtenbuch als Startkilometerstand ermittelt. Falls ja, wird der aktuell höchste Kilometerstand für das aktuelle Fahrzeug aus der Abfrage qryFahrten ermittelt. Diese Abfrage ist eine Union-Abfrage und enthält alle Datensätze der Tabelle tblLetzteFahrt und der Tabelle tblFahrten, deren Feld Storniert den Wert False hat.
Speichern einer neuen Fahrt
Die Prozedur zum Speichern kann aus Platzgründen an dieser Stelle nicht abgedruckt werden. Die dortigen änderungen beziehen sich auf den Teil, der den neuen Datensatz speichert. In der neuen Version besteht dieser Speichervorgang aus mehreren Schritten:
Private Sub Form_Open(Cancel As Integer)
Datensatzherkunft des Listenfeldes anpassen
Da die Daten für das Listenfeld zur Anzeige der Fahrten eines Fahrzeuges nunmehr aus zwei Tabellen kommen, müssen Sie natürlich auch die Datensatzherkunft des Listenfeldes anpassen. Da diese per Code beim öffnen des Formulars festgelegt wird, setzen Sie den Hebel in der Prozedur an, die beim öffnen des Formulars frmFahrten ausgelöst wird (s. Quellcode 2). Die Datensatzherkunft besteht nicht mehr nur aus Daten der Tabelle tblFahrten. Zusätzlich kommt noch der Datensatz hinzu, der für das aktuelle Fahrzeug in der Tabelle tblLetzteFahrt gespeichert ist. Dort ist nicht zwangsläufig ein Datensatz für das aktuelle Fahrzeug gespeichert, da beispielsweise entweder noch gar kein Datensatz für dieses Fahrzeug angelegt wurde oder der letzte Datensatz dieser Tabelle storniert und damit in die Tabelle tblFahrten verschoben wurde.
Dim Kennzeichen As String Dim AktuelleFahrtID As Integer Dim IstStorno As Boolean Kennzeichen = AktuellesFahrzeug Me.txtFahrzeug = Kennzeichen If DCount("FahrzeugID", "tblFahrzeuge") = 0 Then Me.cmdNeueFahrt.Enabled = False End If Me.lstFahrten.RowSource = "SELECT Kennzeichen, Fahrer, StartDatum, " _ & "StartkmStand, StartOrt, ZielDatum, ZielkmStand, ZielOrt, " _ & "[ZielkmStand]-[StartkmStand] AS Strecke, Nutzungsart, Fahrtzweck " _ & "FROM tblFahrten WHERE Kennzeichen = ''" & Kennzeichen _ & "'' AND Storniert = False " _ & "UNION " _ & "SELECT Kennzeichen, Fahrer, StartDAtum, StartkmStand, StartOrt, Zieldatum, " _ & "ZielkmStand, ZielOrt, [ZielkmStand] - [StartkmStand] AS Strecke, " _ & "Nutzungsart, Fahrtzweck FROM tblLetzteFahrt WHERE Kennzeichen = ''" _ & Kennzeichen & "''" IstStorno = Nz(DCount("FahrtID", "tblLetzteFahrt", "Kennzeichen = ''" _ & Kennzeichen & "''"), 0) Me.cmdStornieren.Enabled = IstStorno End Sub
Quellcode 2
Außerdem enthält der erste Teil der UNION-Abfrage, der die Daten der Tabelle tblFahrten enthält, nun eine Bedingung, die alle Datensätze ausschließt, deren Feld Storniert den Wert True enthält. Auf diese Weise zeigt das Listenfeld keine stornierten Fahrten an.
Schaltfläche zum Stornieren von Fahrten
Zum Stornieren von Fahrten legen Sie im Formular frmFahrten eine neue Schaltfläche mit
der Beschriftung Letzte Fahrt stornieren an (siehe Bild 2).
Bild 2: übersicht der Fahrten mit neuer „Stornieren“-Schaltfläche
Die Schaltfläche löst die Prozedur aus Quellcode 3 aus. Die Prozedur fragt zunächst den Benutzer, ob er den Datensatz wirklich stornieren möchte. Falls ja, führt die Prozedur folgende Schritte durch:
Private Sub cmdStornieren_Click() If MsgBox("Möchten Sie die letzte in der Liste angezeigt Fahrt wirklich " _ & "stornieren", vbYesNo + vbExclamation, "Fahrt stornieren") = vbYes Then Dim strSQL As String Dim db As Database Dim rst As Recordset Dim AktuelleFahrtID As Integer Dim IstStorno As Boolean Dim Kennzeichen As String On Error GoTo cmdStornieren_Click_Err Kennzeichen = AktuellesFahrzeug Set db = CurrentDb Set rst = db.OpenRecordset("SELECT TOP 1 * FROM tblLetzteFahrt WHERE " _ & "Kennzeichen = ''" & Kennzeichen & "'' ORDER BY FahrtID DESC", dbOpenDynaset) strSQL = "UPDATE tblLetzteFahrt SET Storniert = TRUE WHERE FahrtID = " _ & rst!FahrtID db.Execute strSQL, dbFailOnError strSQL = "INSERT INTO tblFahrten(Kennzeichen, StartDatum, StartkmStand, " _ & "StartOrt, ZielDatum, ZielkmStand, ZielOrt, Fahrer, Nutzungsart, " _ & "Fahrtzweck, Bemerkungen, Storniert) SELECT Kennzeichen, StartDatum, " _ & "StartkmStand, StartOrt, ZielDatum, ZielkmStand, ZielOrt, Fahrer, " _ & "Nutzungsart, Fahrtzweck, Bemerkungen, Storniert FROM tblLetzteFahrt " _ & "WHERE FahrtID = " & rst!FahrtID db.Execute strSQL, dbFailOnError strSQL = "DELETE FROM tblLetzteFahrt WHERE FahrtID = " & rst!FahrtID db.Execute strSQL, dbFailOnError Me.lstFahrten.Requery Me.cmdNeueFahrt.SetFocus IstStorno = DCount("FahrtID", "tblLetzteFahrt", "Kennzeichen = ''" & Kennzeichen _ & "''") > 0 Me.cmdStornieren.Enabled = IstStorno End If cmdStornieren_Click_Exit: rst.Close Set rst = Nothing Set db = Nothing Exit Sub cmdStornieren_Click_Err: Debug.Print Err.Number, Err.Description GoTo cmdStornieren_Click_Exit End Sub
Quellcode 3
Private Sub Detailbereich_Print(Cancel As Integer, _ PrintCount As Integer) If Me!Storniert = True Then If Not Nz(Me.Bemerkungen, "") = "" Then Me.Line (0, 415)-(Me.Width, 415), 0 End If Me.Line (0, 125)-(Me.Width, 125), 0 End If End Sub
Quellcode 4
Ausgabe des Fahrtenbuchs mit Stornierungen
Nachdem die Stornierungen in den Formularen sauber eingegeben und angezeigt werden, fehlt noch deren Anzeige im Bericht und damit der für das Finanzamt relevante Ausdruck.
Sie könnten nun natürlich einfach das Feld Storniert hinzufügen, sodass stornierte Datensätze einfach durch ein Häkchen in diesem Feld als solche markiert werden. Das wäre aber ein wenig zu trivial. Statt dessen werden Sie den Bericht so anpassen, dass die stornierten Fahrten durchgestrichen angezeigt werden (siehe Bild 3).
Bild 3: Das Fahrtenbuch mit einem stornierten Eintrag
Um diese Anpassung vorzunehmen, müssen Sie noch nicht einmal in das Layout des Berichts eingreifen. Die Linie zum Durchstreichen des Fahrtenbucheintrags können Sie nämlich ganz einfach mit der Line-Methode in der Prozedur erstellen, die durch die Ereigniseigenschaft Beim Drucken ausgelöst wird.
Hinweis
Die Line-Methode und verschiedene Möglichkeiten zur Verwendung von Linien und Rechtecken in Berichten finden Sie im Beitrag Malen nach Zahlen in der vorliegenden Ausgabe von Access im Unternehmen.
Genaugenommen benötigen Sie für das Fahrtenbuch unter Umständen zwei Linien – eine zum Durchstreichen der Zeile mit den Fahrtinformationen und eine, falls zu der Fahrt noch eine Bemerkung hinzugefügt wurde, die in der Berichtsausgabe unterhalb des entsprechenden Fahrtenbucheintrags erfolgt. Beides erledigt die Prozedur aus Quellcode 4.
Private Sub cmdImportieren_Click() Dim strFehler As String If Nz(Dir(Me.txtDatei), "") <> "" Then strFehler = ImportFahrtenbuch(Me.txtDatei) MenueleisteAktualisieren If Len(strFehler) > 0 Then MsgBox strFehler Else MsgBox "Der Import war erfolgreich." End If DoCmd.Close acForm, Me.Name Else MsgBox "Die angegebene Datei kann nicht " _ & "gefunden werden." End If End Sub
Quellcode 4
Schließlich müssen Sie noch die Prozedur anpassen, die beim öffnen des Berichts ausgelöst wird.
Hier sind jedoch nur zwei Felder zu der SQL-Anweisung hinzuzufügen, die der Bericht als Datenherkunft verwendet. Für weitere Einzelheiten konsultieren Sie einfach das entsprechende Klassenmodul des Berichts rptFahrtenbuch.
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