Differenz von Wochen und Tagen

Zu Ihrer Motivation möchten Sie eventuell in einem Formular „Noch x Wochen und n Tage bis zum Urlaub!“ ausgeben. Wie aber berechnen Sie die Wochen und Tage, ausgehend vom aktuellen Datum?

Ganz einfach: Legen Sie zu nächst ein ungebundenes Textfeld an und weisen Sie diesem Feld in der Eigenschaft „Steuerelementeinhalt“ die folgende Formel zu:

=“Noch “ & DatDiff(„w“;Jetzt(); Me.UrlStart) & “ Wochen und “ & DatDiff(„t“;Jetzt();Me.UrlStart) Mod 7 & “ Tage bis zum Urlaub!“

„UrlStart“ ersetzen Sie dabei durch den Namen des Feldes, das das Startdatum des Urlaubs speichert. Die Lösung nutzt „DateDiff“, um die Differenz in Tagen und Wochen zum angegebenen Termin zu berechnen. Eine solche Lösung können Sie aber auch einsetzen, um beispielsweise die Rest – zeit bis zur Fälligkeit einer Aufgabe auszugeben.

Die Formel würde dann beispielsweise so aussehen:

=“Noch “ & DatDiff(„w“;Jetzt(); Me.EndeDatum) & “ Wochen und “ & DatDiff(„t“;Jetzt();Me.EndeDatum) Mod 7 & “ Tage bis zum Abschluss!“

„EndeDatum“ ersetzen Sie dabei durch den Namen des Feldes mit dem Zieldatum.

Dialogbox

Dialogbox mit Ja oder Nein

Dim Mldg, Stil, Titel

Mldg = „Die Firma “ & Form_Kundenzufriedenheit!Firma & “ hat die Bewertung “ & Form_Kundenzufriedenheit!Bewertung & “ erhalten!“ & (Chr(13) & Chr(10)) & „Informieren Sie bitte die Geschäftsleitung.“

Stil = vbQuestion + vbYesNo
Titel = „Achtung, WICHTIG!!!“
Antwort = MsgBox(Mldg, Stil, Titel)
If Antwort = vbYes Then
MsgBox „Ja“
Else
MsgBox „Nein“
End If

Noch ein Beispiel:

If IsNull(Art) Then
MsgBox „Das Feld ART darf nicht leer sein!“, vbCritical
Else
End If


MsgBox-Funktion

Zeigt eine Meldung in einem Dialogfeld an und wartet darauf, daß der Benutzer auf eine Schaltfläche klickt. Es wird dann einen Wert vom Typ Integer zurückgegeben, der anzeigt, auf welche Schaltfläche der Benutzer geklickt hat.

Syntax

MsgBox(prompt[, buttons] [, title] [, helpfile, context])

Die Syntax der MsgBox-Funktion verwendet die folgenden benannten Argumente:

Teil

Beschreibung

prompt

Erforderlich. Ein Zeichenfolgenausdruck, der als Meldung im Dialogfeld erscheint. Die Maximallänge von prompt ist – je nach Breite der verwendeten Zeichen – etwa 1024 Zeichen. Wenn prompt aus mehreren Zeilen besteht, müssen Sie die Zeilen mit einem Wagenrücklaufzeichen (Chr(13)), einem Zeilenvorschubzeichen (Chr(10)) oder einer Kombination aus Wagenrücklaufzeichen und Zeilenvorschubzeichen (Chr(13) & Chr(10)) trennen.

buttons

Optional. Ein numerischer Ausdruck, der der Summe der Werte entspricht, die Anzahl und Typ der anzuzeigenden Schaltflächen, die Art des zu verwendenden Symbols sowie die Standardschaltfläche und die Bindung des Dialogfeldes angeben. Wenn Sie buttons nicht angeben, ist der Standardwert 0.

title

Optional. Ein Zeichenfolgenausdruck, der in der Titelleiste des Dialogfeldes angezeigt wird. Wenn Sie title nicht angeben, wird der Anwendungsname in der Titelleiste angezeigt.

helpfile

Ein Zeichenfolgenausdruck, der die Hilfedatei mit der kontextbezogenen Hilfe für das Dialogfeld angibt. Wenn Sie helpfile angeben, müssen Sie auch context angeben.

context

Optional. Ein numerischer Ausdruck mit der Hilfekontextkennung, die der Autor der Hilfe für das entsprechende Hilfethema gegeben hat. Wenn Sie context angeben, müssen Sie auch helpfile angeben.

Einstellungen

Das Argument buttons hat die folgenden Einstellungen:

Konstante Wert Beschreibung

vbOKOnly

0

Nur die Schaltfläche OK anzeigen.

VbOKCancel

1

Schaltflächen OK und Abbrechen anzeigen.

VbAbortRetryIgnore

2

Schaltflächen Abbruch, Wiederholen und Ignorieren anzeigen.

VbYesNoCancel

3

Schaltflächen Ja, Nein und Abbrechen anzeigen.

VbYesNo

4

Schaltflächen Ja und Nein anzeigen.

VbRetryCancel

5

Schaltflächen Wiederholen und Abbrechen anzeigen.

VbCritical

16

Meldung mit Stop-Symbol anzeigen.

VbQuestion

32

Meldung mit Fragezeichen-Symbol anzeigen.

VbExclamation

48

Meldung mit Ausrufezeichen-Symbol anzeigen.

VbInformation

64

Meldung mit Info-Symbol anzeigen.

VbDefaultButton1

0

Erste Schaltfläche ist Standardschaltfläche.

VbDefaultButton2

256

Zweite Schaltfläche ist Standardschaltfläche.

VbDefaultButton3

512

Dritte Schaltfläche ist Standardschaltfläche.

VbDefaultButton4

768

Vierte Schaltfläche ist Standardschaltfläche.

VbApplicationModal

0

An die Anwendung gebunden. Der Benutzer muß auf das Meldungsfeld reagieren, bevor er seine Arbeit mit der aktuellen Anwendung fortsetzen kann.

VbSystemModal

4096

An das System gebunden. Alle Anwendungen werden unterbrochen, bis der Benutzer auf das Meldungsfeld reagiert.

vbMsgBoxHelpButton

16384

Adds Help button to the message box

VbMsgBoxSetForeground

65536

Specifies the message box window as the foreground window

vbMsgBoxRight

524288

Text is right aligned

vbMsgBoxRtlReading

1048576

Specifies text should appear as right-to-left reading on Hebrew and Arabic systems

Die erste Gruppe von Werten (0 – 5) beschreibt die Anzahl und den Typ der im Dialogfeld angezeigten Schaltflächen. Die zweite Gruppe (16, 32, 48, 64) beschreibt die Symbolart. Die dritte Gruppe (0, 256, 512) legt die Standardschaltfläche fest. Die vierte Gruppe (0, 4096) legt fest, in welcher Form das Dialogfeld gebunden ist. Verwenden Sie beim Addieren der Zahlen zu einem Gesamtwert für das Argument buttons nur eine Zahl aus jeder Gruppe.

Anmerkung Diese Konstanten sind durch Visual Basic für Applikationen festgelegt. Daher können die Namen an einer beliebigen Stelle im Code anstelle der tatsächlichen Werte verwendet werden.

Rückgabewerte

Konstante

Wert

Beschreibung

vbOK

1

OK

vbCancel

2

Abbrechen

vbAbort

3

Abbruch

vbRetry

4

Wiederholen

vbIgnore

5

Ignorieren

vbYes

6

Ja

vbNo

7

Nein

Bemerkungen

Wenn sowohl helpfile als auch context angeben werden, kann der Benutzer F1 (Windows) oder HILFE (Macintosh) drücken, um das Hilfethema für context anzuzeigen. Einige Host-Anwendungen, zum Beispiel Microsoft Excel, fügen dem Dialogfeld automatisch die Schaltfläche Hilfe hinzu.

Wenn im Dialogfeld die Schaltfläche Abbrechen angezeigt wird, hat das Drücken von ESC dieselbe Wirkung wie das Klicken auf Abbrechen. Wird im Dialogfeld die Schaltfläche Hilfe angezeigt, wird für das Dialogfeld eine kontextbezogene Hilfe zur Verfügung gestellt. Ein Wert wird aber nur zurückgegeben, wenn auf eine der anderen Schaltflächen geklickt wird.

Anmerkung

Wenn Sie außer dem ersten benannten Argument weitere Argumente angeben möchten, müssen Sie MsgBox in einem Ausdruck verwenden. Wenn Sie einige Argumente mit einer bestimmten Position nicht angeben möchten, müssen Sie dennoch das entsprechende Komma als Trennzeichen angeben.

Datumseingaben prüfen (Gültigkeitsregeln)

Im Tabellen- oder Formularentwurf können Sie Feldern eine Gültigkeitsregel und eine Gültigkeitsmeldung zuordnen, um sicherzustellen, dass Daten im richtigen Format eingegeben werden, und um dem Anwender im Falle eines Fehlers ei nen hilfreichen Hinweis auf die erwartete Eingabe anzuzeigen. Einige wichtige Tipps und Kniffe zu diesem Thema haben wir im Folgenden für Sie zusammengestellt.

Eingabe in ein Feld erzwingen
Um die Eingabe in ein Feld generell zu erzwingen, stellen Sie normalerweise die Eigenschaft „Eingabe erforderlich“ im Tabellenentwurf auf „Ja“ ein. Das führt dazu, dass Access eine wenig hilfreiche Meldung der Art „Feld darf keinen Inhalt der Länge null haben, geben Sie etwas in das Feld ein …“ anzeigt. Alternativ lassen Sie „Eingabe erforderlich“ auf „Nein“ eingestellt und verwenden als Gültigkeitsregel den Ausdruck und als Gültigkeitsmeldung beispielsweise Dadurch wird wie bei „Eingabe erforderlich = Ja“ eine Eingabe erzwungen, aber der Hinweis an den Anwender ist wesentlich hilfreicher.

Bestimmte Feldinhalte prüfen
Oftmals dürfen z. B. in ein Feld für Sachbearbeiternamen nur bestimmte Zeichenfolgen wie z. B. „Müller“, „Meier“, „Schmidt“ und „Krüger“ eingegeben werden. Verwenden Sie folgende Gültigkeitsregel: Dieser Ausdruck löst eine Meldung aus, wenn das Feld nicht leer ist und der Inhalt nicht einem der Namen „Müller“, „Meier“, „Schmidt“ oder „Krüger“ entspricht.

Datumseingaben prüfen
Eine der häufigsten Fehleingaben ist ein Datum in der Zukunft, weil der Anwender beispielsweise bei der Erfassung im August eines Feldes „Erledigt am“ beim Monat irrtümlich „9“ statt „8“ getippt hat. Um solche Fehler abzufangen, verwenden Sie die folgende Gültigkeitsregel: Die Gültigkeitsmeldung wird angezeigt, wenn das Feld nicht leer ist und das eingegebene Datum nicht kleiner oder gleich dem aktuellen, per „Date()“ ermittelten Systemdatum ist.

Postleitzahlen prüfen
Postleitzahlen bestehen immer aus fünf Ziffern. Um eine solche Eingabe sicherzustellen, verwenden Sie normalerweise die Eigenschaft „Eingabeformat“ mit einer Maske „00000“. Das führt dazu, dass Access im Feld Unterstriche anzeigt, die viele Anwender verwirren. Alternativ können Sie folgende Gültigkeitsregel verwenden: Dieser Ausdruck löst die Gültigkeitsmeldung aus, wenn das Feld nicht leer ist und der Inhalt nicht exakt fünf Ziffern entspricht.

Datum mit Kalenderhilfe

Klicken Sie in der Toolbox auf „Weitere Steuerelemente“

Wählen Sie hier den Eintrag Microsoft Date and Time Picker Control 6.0 (SP4)

Ziehen Sie damit ein Feld im Formular auf und ändern Sie dann in den Eigenschaften von diesem Feld den Steuerelementinhalt.

Datum: Alter ermitteln

Problem

Du möchtest das Alter einer Person anhand des Geburtsdatums feststellen.

Lösung

DatDiff(„jjjj“;[Geburtsdatum];Datum())+(Format(Datum();“mmtt“)<Format([Geburtsdatum];“mmtt“))

Erläuterung:
Zuerst werden mit DatDiff die Jahre zwischen den beiden Daten ermittelt.
Dann wird geprüft, ob Tag und Monat des aktuellen Datums kleiner sind als jene des Geburtsdatums.
Wenn dem so ist, muss ein Jahr abgezogen werden.
Ergibt dieser Vergleich Wahr, stellt Access das intern als -1 dar. Bei Falsch als 0.
Deshalb kann man das Ergebnis gleich addieren.

Datensätze verschieben

Bei der Arbeit in Access benötigen Sie häufig eine Routine, die einen Datensatz, z. B. zu Sicherungs- oder Dokumentationszwecken, von einer Tabelle in eine andere verschiebt. Eine Lösungsmöglichkeit wäre hier eine VBA-Routine, aber wesentlich einfacher und flexibler kommen Sie mit SQL-Anweisungen zum Ziel.

Die Datenbank benötigt das Modul „modDSVerschieben“, das Sie nach Installation zunächst in Ihre Datenbank übertragen. Anschließend können Sie die Funktion „DSVerschieben()“ wie unten erläutert einsetzen. Die Funktion „modDSVerschieben“ erwartet in den ersten beiden Parametern „strQuelle“ und „strZiel“ die Namen der Quell- und der Zieltabelle. Der dritte Parameter „strFeldname“ definiert den Namen des Feldes, das nach dem über den vierten Parameter „varFeldwert“ angegebenen Wert durchsucht werden soll. Das eigentliche Verschieben erfolgt in zwei Schritten: Zunächst wird der Datensatz per SQLAnweisung „INSERT INTO…“ kopiert:

strSQL = „INSERT INTO
[“ & strZiel & „] “
strSQL = strSQL & „SELECT
[“ & strQuelle & „].* FROM
[“ & strQuelle & „] “
strSQL = strSQL & „WHERE
[“ & strQuelle & „].
[“ & strFeldname & „] = “
DoCmd.RunSQL strSQL, False


Speichern Sie das Modul unter den Namen „modDSVerschieben“ ab.

Function DSVerschieben(strQuelle As String, _
strZiel As String, _
strFeldname As String, _
varFeldwert As Variant) As Integer

Dim strSQL As String

DSVerschieben = 0
strSQL = „INSERT INTO [“ & strZiel & „] „
strSQL = strSQL & „SELECT [“ & strQuelle & „].* FROM [“ & strQuelle & „] „
strSQL = strSQL & „WHERE [“ & strQuelle & „].[“ & strFeldname & „] = „
If TypeName(varFeldwert) = „String“ Then
strSQL = strSQL & „‚“ & varFeldwert & „‚;“
Else
strSQL = strSQL & varFeldwert & „;“
End If

On Error Resume Next
DoCmd.RunSQL strSQL, False
If Err <> 0 Then
Beep
MsgBox „Fehler beim Übertragen: “ & Err.Description, _
vbOKOnly + vbExclamation, _
„!!! Problem !!!“
DSVerschieben = 1
Exit Function
End If

strSQL = „DELETE * FROM [“ & strQuelle & „] „
strSQL = strSQL & „WHERE [“ & strQuelle & „].[“ & strFeldname & „] = „
If TypeName(varFeldwert) = „String“ Then
strSQL = strSQL & „‚“ & varFeldwert & „‚;“
Else
strSQL = strSQL & varFeldwert & „;“
End If

Err = 0
DoCmd.RunSQL strSQL, False
If Err <> 0 Then
Beep
MsgBox „Fehler beim Löschen: “ & Err.Description, _
vbOKOnly + vbExclamation, _
„!!! Problem !!!“
DSVerschieben = 2
Exit Function
End If

End Function


Datensatznavigation

Zum ersten Datensatz gehen

DoCmd.GoToRecord , , acFirst


Zum letzten Datensatz gehen

DoCmd.GoToRecord , , acLast


Einen Datensatz zurück gehen

DoCmd.GoToRecord , , acPrevious


Einen Datensatz vor gehen

DoCmd.GoToRecord , , acNext


Zum Datensatz Nr. 4 gehen

DoCmd.GoToRecord , , acGoTo, 4


Einen neuen Datensatz

DoCmd.GoToRecord , , acNewRec


Ein geöffnetes Formular: Einen neuen Datensatz:

DoCmd.GoToRecord acDataForm, „Name des Formulars“, acNewRec


Ein geöffnetes Formular: Einen Datensatz zurück:

DoCmd.GoToRecord acDataForm, “ Name des Formulars „, acPrevious


Ein geöffnetes Formular: Einen Datensatz vor:

DoCmd.GoToRecord acDataForm, „Name des Formulars“, acNext


Ein geöffnetes Formular: Zum ersten Datensatz:

DoCmd.GoToRecord acDataForm, „Name des Formulars“, acFirst


Ein geöffnetes Formular: Zum letzten Datensatz:

DoCmd.GoToRecord acDataForm, „Name des Formulars“, acLast


Ein geöffnetes Formular: Zum Datensatz Nr 4:

DoCmd.GoToRecord acDataForm, „Name des Formulars“, acGoTo, 4

Datensätze mit Details kopieren

Datenbank

Viele Datenbank-Lösungen arbeiten mit einer Kombination aus einem Hauptdatensatz in einer Tabelle und einem oder mehreren Detaildatensätzen in einer zweiten Tabelle, wobei die Verknüpfung über einen gemeinsamen Ordnungsbegriff erfolgt. Beispiel Bestellungen: Eine Tabelle „Bestellungen“ enthält hier die Basisdaten wie Kunde, Bestellnummer, Versandform oder Lieferdatum, eine zweite Tabelle „Bestelldetails“ nimmt einen oder mehrere Sätze auf, in der die bestellten Artikel festgehalten sind. Die Verknüpfung erfolgt jeweils über die eindeutige Bestellnummer. Wenn Sie mit solchen Konstruktionen arbeiten, haben Sie sich bestimmt schon oft gewünscht, eine komplette Bestellung kopieren zu können, da ein Kunde gerade fast dieselbe Bestellung wie der Kunde vor ihm aufgegeben hat. Aber auch bei Kunden, die monatlich immer die gleichen Artikel bestellen, wäre eine Kopierfunktion recht hilfreich. Allerdings stellt Access keine Funktionen bereit, um sowohl Hauptdatensatz als auch die dazugehörigen Detaildatensätze kopieren und als neuen Vorgang einfügen zu können. Mit einer VBA-Routine schaffen Sie hier Abhilfe.

In unserer Beispiel-Datenbank DETAILS. finden Sie das Formular „Bestellungen“ mit dem Unterformular „Bestellungen-Unterformular“. Es basiert auf den Tabellen „Bestellungen“, deren Inhalt im Hauptformular angezeigt wird, und „Bestelldetails“, die im Unterformular erscheinen. Um hier einen kompletten Vorgang zu kopieren, sind also ein Datensatz aus „Bestellungen“ und ein oder mehrere Datensätze aus „Bestelldetails“ zu duplizieren, wobei bestimmte Feldinhalte wie „Bestell-, Versand-, Lieferdatum“ oder „Bestellnummer“ angepasst werden müssen.

Dazu enthält das Formular eine Schaltfläche „Bestellung kopieren“, die in der Ereignisprozedur „Beim Klicken“ die folgenden Anweisungen beinhaltet:

Private Sub btnKopieren_Click()
Dim lngBestNr As Long, lngNeueBestNr As Long, strSQL As String
Dim db As DATABASE, rs1 As Recordset, rs2 As Recordset
Dim lngAnzDS As Long, lngAnzFld As Long, I As Integer, J As Integer

On Error Resume Next
lngBestNr = Me.[Bestell-Nr]
If Err <> 0 Then ‚Neuer Satz…
Beep
Exit Sub
End If
On Error GoTo 0

Hier wird zunächst die aktuelle Bestellnummer aus dem Formular ausgelesen. Dabei kommt es eventuell zu einem Fehler, wenn gerade ein neuer Datensatz angelegt wurde und der Anwender aus Versehen auf die Schaltfläche geklickt hat. Die Routine gibt dann einen akustischen Hinweis aus und beendet die Ausführung der Ereignis-Prozedur über „Exit Sub“.

strSQL = „select * from [Bestellungen] where [Bestell-Nr]= “ & lngBestNr
Set db = CurrentDb()
Set rs1 = db.OpenRecordset(strSQL, dbOpenSnapshot)
Set rs2 = db.OpenRecordset(„Bestellungen“, dbOpenDynaset)

Anschließend werden zwei Recordsets geöffnet. „rs1“ ist der aktuelle Datensatz der Bestellung, „rs2“ repräsentiert die Tabelle „Bestellungen“ und wird gleich für das Anlegen eines neuen Datensatzes verwendet. Die Prozedur prüft dann, ob zur Bestellnummer ein Datensatz gefunden wurde. Wenn nicht, hat der Anwender vermutlich die Bestellnummer manuell geändert und der Datensatz wurde noch nicht gesichert. Nach einem Hinweis an den Anwender wird die Routine verlassen.

Sie ermitteln dann über „DMax()“ eine neue Bestellnummer und halten diese in der Variablen „lngNeueBestNr“ für die spätere Zuweisung fest. Dann legt „Add-New“ einen neuen, leeren Hauptdatensatz an, der die Kopie der aktuellen Basisdaten der Bestellung aufnimmt.

‚Daten aus altem Satz in neuen Satz schreiben
lngAnzFld = rs1.Fields.Count – 1
For I = 0 To lngAnzFld
Select Case rs1(I).Name
Case „Bestell-Nr“
rs2(I).Value = lngNeueBestNr
Case „Bestelldatum“, „Versanddatum“, „Lieferdatum“
rs2(I).Value = Now
Case Else
rs2(I).Value = rs1(I).Value
End Select
Next I
rs2.UPDATE
rs1.Close
rs2.Close

In For-Next-Schleifen übertragen wir die Feldinhalte aus dem alten in den neuen Hauptdatensatz. Dabei erfahren die Felder „Bestell-Nr“ und die Felder mit den Datumsangaben eine besondere Behandlung: Die Bestellnummer wird auf die zuvor ermittelte, neue Bestellnummer und die Datumsangaben werden auf das aktuelle Datum gesetzt.

Abschließend werden alle Recordsets geschlossen, da diese nicht mehr benötigt oder für die Übertragung der Detail-Datensätze neu initialisiert werden müssen.

‚— Detail-Datensätze —
strSQL = „select * from [Bestelldetails] where [Bestell-Nr]= “ & lngBestNr
Set rs1 = db.OpenRecordset(strSQL, dbOpenSnapshot)
Set rs2 = db.OpenRecordset(„Bestelldetails“, dbOpenDynaset)
On Error Resume Next
rs1.MoveLast
If Err <> 0 Then
Beep
MsgBox „Fehler bei Zugriff auf Bestelldetails für Bestellung “ & lngBestNr & „!“
GoTo Weiter
End If
lngAnzDS = rs1.RecordCount
rs1.MoveFirst
On Error GoTo 0

Hier werden die Recordsets für die Übertragung der Detail-Datensätze initialisiert und geprüft. Wurden keine Detaildatensätze gefunden, liegt vermutlich eine unvollständige Bestellung vor. Nach einem Hinweis an den Anwender brechen wir an dieser Stelle ab und zeigen weiter unten die neue Bestellung an. In zwei Schleifen kopieren wir dann die Detaildatensätze und deren einzelne Felder, wobei die Bestellnummer auf die zuvor ermittelte, neue Bestellnummer gesetzt wird.

Abschließend aktualisiert die Prozedur die Datenbasis über ein „Requery“, setzt den Fokus auf das Feld „Bestell-Nr“ und positioniert das Formular über „FindRecord“ auf die „neue“ Bestellung.

Hier noch mal die gesamte Programmierung:

Private Sub btnKopieren_Click()
Dim lngBestNr As Long, lngNeueBestNr As Long, strSQL As String
Dim db As DATABASE, rs1 As Recordset, rs2 As Recordset
Dim lngAnzDS As Long, lngAnzFld As Long, I As Integer, J As Integer

On Error Resume Next
lngBestNr = Me.[Bestell-Nr]
If Err <> 0 Then ‚Neuer Satz…
Beep
Exit Sub
End If
On Error GoTo 0

strSQL = „select * from [Bestellungen] where [Bestell-Nr]= “ & lngBestNr
Set db = CurrentDb()
Set rs1 = db.OpenRecordset(strSQL, dbOpenSnapshot)
Set rs2 = db.OpenRecordset(„Bestellungen“, dbOpenDynaset)
On Error Resume Next
rs1.MoveFirst
If Err <> 0 Then
Beep
MsgBox „Fehler bei Zugriff auf Bestellung “ & lngBestNr & „!“
rs1.Close
Exit Sub
End If
On Error GoTo 0

‚— Haupt-Datensatz —
’neue Bestell-Nr ermitteln
lngNeueBestNr = DMax(„[Bestell-Nr]“, „Bestellungen“) + 1
‚Neuen Datensatz anlegen
rs2.AddNew
‚Daten aus altem Satz in neuen Satz schreiben
lngAnzFld = rs1.Fields.Count – 1
For I = 0 To lngAnzFld
Select Case rs1(I).Name
Case „Bestell-Nr“
rs2(I).Value = lngNeueBestNr
Case „Bestelldatum“, „Versanddatum“, „Lieferdatum“
rs2(I).Value = Now
Case Else
rs2(I).Value = rs1(I).Value
End Select
Next I
rs2.UPDATE
rs1.Close
rs2.Close

‚— Detail-Datensätze —
strSQL = „select * from [Bestelldetails] where [Bestell-Nr]= “ & lngBestNr
Set rs1 = db.OpenRecordset(strSQL, dbOpenSnapshot)
Set rs2 = db.OpenRecordset(„Bestelldetails“, dbOpenDynaset)
On Error Resume Next
rs1.MoveLast
If Err <> 0 Then
Beep
MsgBox „Fehler bei Zugriff auf Bestelldetails für Bestellung “ & lngBestNr & „!“
GoTo Weiter
End If
lngAnzDS = rs1.RecordCount
rs1.MoveFirst
On Error GoTo 0

For J = 1 To lngAnzDS
‚Daten aus altem Satz in neuen Satz schreiben
rs2.AddNew
lngAnzFld = rs1.Fields.Count – 1
For I = 0 To lngAnzFld
If rs1(I).Name <> „Bestell-Nr“ Then
rs2(I).Value = rs1(I).Value
Else
rs2(I).Value = lngNeueBestNr
End If
Next I
rs2.UPDATE
rs1.MoveNext
Next J

Weiter:
On Error Resume Next
rs1.Close
rs2.Close

Me.Requery
Me.[Bestell-Nr].SetFocus
DoCmd.FindRecord lngNeueBestNr

End Sub

Dateneingabe ohne Datensatzwechsel

Datenbank

Wenn Sie bei einer Dateneingabe das letzte Feld in einem Formular mit der Tab-, Return– oder einer der Cursor-Tasten verlassen, springt Access normalerweise automatisch zum nächsten Datensatz. Vor allem bei weniger erfahrenen Anwendern kann dieses Verhalten zu Verwirrung führen.

Eine wenig bekannte Formulareinstellung schafft Abhilfe: Mit Hilfe der Eigenschaft „Zyklus“ können Sie festlegen, wie sich der Cursor beim Verlassen des letzten Feldes verhält:

  • Die Standardeinstellung ist „Alle Datensätze“ und entspricht dem bekannten Verhalten: Der Cursor springt nach dem Verlassen des letzten Feldes in den folgenden Datensatz bzw. legt einen neuen Datensatz an.

  • Die Einstellung „Aktueller Datensatz“ sorgt hingegen dafür, dass der Cursor nach dem Verlassen des letzten Feldes wieder zum ersten Feld des aktuellen Datensatzes springt. So lässt sich verhindern, dass Access unkontrolliert den Datensatz wechselt oder womöglich einen neuen, leeren Datensatz anlegt.

  • Für mehrseitige Formulare ist die Einstellung „Aktuelle Seite“ sehr hilfreich: Sie verhindert das automatische Scrollen in den Seiten und setzt den Cursor nach Verlassen des letzten Feldes der aktuellen Formularseite wieder zurück in das erste Feld der aktuellen Formularseite. Wenn sowohl weniger erfahrene als auch fortgeschrittene Anwender mit einer Datenbank arbeiten, empfiehlt es sich, den Zyklus standardmäßig auf „Aktueller Datensatz“ zu setzen, aber eine Umschaltmöglichkeit per Kontrollkästchen vorzusehen. Gehen Sie dazu wie folgt vor:

  1. Legen Sie im Formularfuß ein Kontrollkästchen „cbHalten“ an, dessen Beschriftung Sie auf „Cursor im Datensatz halten“ setzen.

  2. Geben Sie in der Ereignisprozedur „Beim Laden“ des Formulars die folgenden Anweisungen ein:

    Private Sub Form_Load()
    Me.cbHalten = True
    Me.Cycle = 1
    End Sub

  3. Für die Ereignisprozedur „Nach Aktualisierung“ erfassen Sie:

    Private Sub
    cbHalten_AfterUpdate()
    If Me.cbHalten Then
    Me.Cycle = 1
    Else
    Me.Cycle = 0
    End If
    End Sub

Fortgeschrittene Anwender können nun bei Bedarf den „alten“ Zustand durch Deaktivierung des Kontrollkästchen wiederherstellen. Diese Lösung wird im Formular „Kunden“ unserer Beispieldatenbank demonstriert.