Ich möchte gerne zum Ausfüllen eines Formulars, Daten aus dem vorangegangenen Datensatz verwenden um z.B den Zähler hochzuzählen oder Zeiten zu kumulieren.
Dazu habe ich eine Ereignisprozedur geschrieben, die beim Laden des Formulars ausgeführt werden soll.
Die Idee der Prozedur ist zum letzten Datensatz eines Recordsets zu springen, einige Werte dieses Datensatzes in Variablen abzuspeichern, dann einen neuen - leeren - Datensatz zu erzeugen und ihn schon einmal mit ein paar berechneten Werten zu befüllen. Der Rest des Formulars soll dann per Hand ausgefüllt werden.
Meine Prozedur dazu sieht wie folgt aus:
Private Sub Form_Load()
Dim xlog As Integer
Dim xdest As String
Public xairtime As Double
Public xldg As Variant
Dim DB As DAO.Database
Dim rs As DAO.Recordset
Set DB = CurrentDb
Set rs = CurrentDb.OpenRecordset("qryFluege_DEMOA")
rs.MoveLast
xlog = rs!Logz
xdest = rs!Dest
xairtime = rs!Total_Airtime_dez
xldg = rs!TotalLdg
rs.AddNew
Me!Logz = xlog + 1
Me!Dep = "" & xdest & ""
Me!Total_Airtime_dez = xairtime
Me!TotalLdg = xldg
Me!Datum = Datum()
Me!Dep = Null
Me!Dep.SetFocus
rs.Update
Set DB = Nothing
Set rs = Nothing
End Sub
Leider funktioniert das nicht so wie ich erwartet habe. Folgende Probleme bestehen:
1. Ich hätte gerne einige Variablen in anderen Prozeduren verfügbar und habe sie deshalb als "Public" deklariert. Das wird aber vom VBA-Editor beanstandet. Mit Dim läuft es dann. Ist dann aber nur lokal verfügbar - oder?
2. Das Ergebnis der Prozedur ist kein leerer Datensatz, sondern ein Datensatz, der mit den Daten des 1. Datensatzes im Recordset gefüllt ist. Lediglich die übernommenen und berechneten Werte sind anders.
3. Die Vorbelegung des Datums mit DATE() funktioniert nicht. Stattdessen steht in dem Feld das Datum des 1. Datensatzes im Recordset.
Wenn mir einer erklären kann, was ich falsch mache, wäre ich dankbar.
Hi,
nur als Idee für einen anderen Weg, um das Ziel (mit weniger VBA) zu erreichen: die .default.Eigenschaft von Steuerelementen ausnutzen.
Nach dem Motto:
Beim Ereignis "Beim Anzeigen" die default-Eigenschaft setzen und bei der Eingabe eines neuen Datensatzes verwenden.
Harald
Ja, aber ich habe das so verstanden, dass die default Eigenschaft immer dann nützlich ist, wenn man mehrere Datensätze erzeugt, mit gleichen Dateninhalten. Das kann ich z.B. beim Datum auch verstehen und benutzen, bei den anderen Feldern ändern sich die Werte von Datensatz zu Datensatz; da sehe ich noch nicht, wie die eigenschaft mir nutzen soll.
Dennoch danke für den Hinweis. Wenn mir das mit dem VBA über den kopf wächst, werde ich das mal probieren.
Hi,
zu 1)
probier mal die Zeilen
Public xairtime As Double
Public xldg As Variant
aus der sub herauszunehmen und entweder
a) an den Anfang des VBA-Teils des Formulars oder besser
b) an den Anfang eines Moduls
einzufügen.
Variante b) hat den Vorteil, dass die globalen Variablen auch für andere Formulare/Berichte nutzbar sind.
zu 2)
Nach rs.AddNew weist Du den Inhalt vom eingelesenen recordset nicht einem neuen recordset sondern den Steuerelementen vom Formular zu.
Es fehlen Anweisungen wie
rs!Logz = xlog + 1
zu 3)
Was passiert beim Einsatz von
Me!Datum = Date
Der Namen "Datum" für ein Steuerelement ist suboptimal (siehe Namenskonvention).
Besser Datum_Fracht (oder etwas nach Deiner Wahl).
Was sollen & und die " bei
Me!Dep = "" & xdest & ""
Ich bin mir nicht sicher, ob sich das Erzeugen eines neuen Datensatz mit recordset auch auf die Anzeige im Formular auf diese Weise auswirkt.
Harald
Hallo Harald,
ganz herzlichen Dank für die Anmerkungen. Das war wirklich hilfreich!
Verstanden habe ich folgendes:
Zu 1)
Public Variablen müsssen oberhalb einer SUB deklariert werden – macht Sinn und funktioniert auch so!
Zu 2)
Du hast völlig recht, dass es einen Unterschied macht oder machen kann, ob man Werte einem Recordset oder einer Database zuweist. Ich war bislang davon ausgegangen, dass man mit Recordset eine Kopie der DB anlegt. Aber offensichtlich habe ich das Konzept noch nicht verstanden.
Meine Überlegung einen RS anzulegen, Werte aus dem letzten Record dieses RS in eine Form zu kopieren (incl. einiger Berechnungen), die Felder der Form dann händisch zu ergänzen und den Inhalt der gesamten Form in den neuen Record der DB zu kopieren. Das hat ja auch insofern funktioniert, als die kopierten Werte auch korrekt in der Form stehen, nur verstehe ich nicht, warum die restlichen Felder mit Werten aus dem 1. Datensatz des RS gefüllt sind. Wie kommen die in die form und warum gerade die Werte des 1. Datensatzes? Mir scheint, dass ich noch nicht verstanden, wie eine gebundene Form angebunden ist. Ich habe mir das bisher so vorgestellt, dass eine gebundene Form so etwas wie eine Ansicht auf den selektierten Record der DB ist.
Aber Du hast recht; dann wären rs.AddNew und rs.Update falsch, weil sich diese Befehle ja auf den rs und nicht auf die DB beziehen. Oder? Ganz klar ist mir das nicht. Denn mich erstaunt, dass in der Form die Werte der kopierten Variablen korrekt erscheinen, nur der Rest der Form mit Werten aus dem 1. Record des rs gefüllt sind. Wie kommen die in die Form und warum die Werte des 1. Record, wenn ich vorher zum letzten Record gesprungen bin?
Wäre es denn eine bessere Lösung, wenn ich beispielsweise mit DoCmd GoToRecord,,acNewRec zunächst einen neuen leeren Datensatz erzeuge, dann aus dem rs die Werte der Felder aus dem selektierten Record in die Form kopiere und die Form dann update? Ich probiere das mal; bin aber für Hinweise zum Verständnis der Beziehungen dankbar.
Zu 3)
Völlig richtig! ,,Datum" kann missverständlich sein, weil auch interne Funktion u.ä; werde ich ändern
Was sollen & und die " bei Me!Dep = "" & xdest & "" ? Weiß ich auch nicht wirklich. Das habe ich hier aus dem Forum (http://www.access-o-mania.de/forum/index.php?topic=3713.msg18899#msg18899) und auch bei FAQ4.22 von DonKarl steht dieser Ausdruck. Diese Zuweisung funktioniert auch, aber warum man das so angeben soll, habe ich auch nicht verstanden, sondern nur übernommen.
Gruß und danke noch einmal
Bernd
Hallo,
irgenwie hab ich den Verdacht, dass Du den Formular-Recordset mit dem eigenständig erzeugten Recordset in einen Topf wirfst.. Diese beiden Recordsets haben nichts miteinander gemeinsam, außer vielleicht die Daten, wenn beide sich auf dieselbe Datenbasis (Tabelle oder Abfrage) beziehen.
rs.Update und rs.Addnew beziehen sich nur auf die Daten aus der Abfrage "qryFluege_DEMOA" ...
Das Form-Recordset kommt nur und auch nur intern durch die Referenz der gebundenen Steuerelemente ("Me!Logz" z. B.) ins Spiel.
Der Code steht im Load-Ereignis des Form. Zu diesem Zeitpunkt liegt die Position des Form-Recordset (und damit die mit den Steuerelementen (etwas später) angezeigten Daten) auf dem ersten Datensatz. Durch die Zuweisung der Daten aus dem "letzten" RS-Recordset (rs.Movelast) werden eben die aktuell geladenen Daten des Form-Recordsets überschrieben und , weil gebunden, bei nächster Gelegenheit (z. B. Datensatzwechsel) in die Tabelle gespeichert.
Wenn also irgendwelche Daten in einen neuen Formular-Datensatz geschrieben werden sollen, dann muss der Form-Recordset erst auf einen neuen DS gesetzt werden (wie Du selber schon erkannt hast) , z. B.:
Docmd.Gotorecord,,acNewrec
oder man erzeugt einen neuen Recordset aus dem akt. Form-Recordset(Clone) und erstellt diesen dort mit AddNew ...
Franz,
ganz herzlichen Dank! Das hilft mir ein ganzes Stück weiter! In der Tat habe ich die beiden Recordsets in einen Topf geworfen. Jetzt bekomme ich auch eine Ahnung, wozu der .clone Befehl gut ist. In der Tat habe ich heute auch dem Faden weitergesponnen im Form-Recordset zu navigieren und entwickle langsam Verständnis. Tut mir leid, wenn ich mit solchen Anfängerfehlern nerve.
Schönen Abend
Bernd
Hi,
anbei mal ein Vorschlag ohne recordset.
Wenn Du im Formular einen neuen Datensatz anlegst und dort eine Änderung machst, werden die Daten vom zuvor angeschauten Datensatz übernommen (bis auf die Stelle, wo die Änderung gemacht wurde; ist auch noch anders lösbar).
Harald
[Anhang gelöscht durch Administrator]
Harald,
ganz herzlichen Dank! Und sehr elegent. Hilft mir sehr die Logik von Access und VBA zu verstehen. Ich werde versuchen das völlig zu verstehen und diesen Ansatz dann umzusetzen. Deshalb noch einmal ein super Danke für den Denkanstoß!
Aber im Moment knabbere ich erst einmal an dem Problem, wie ich das Ergebnis eines berechneten Feldes einer Form wieder in die Tabelle/Abfrage bekomme. Da das ein andereds Thema ist, werde ich das auch getrennt posten.
Ich werde berichten, ob und wie ich mit Deinem Ansatz weitergekommen bin.
Gruß
Bernd