Datensätze in Tabelle updaten oder neu anfügen
Hallo!
Ich habe einen Code mit dem ich eine Historie des Mitarbeitereinsatzes erstelle. Bei Klick auf einen Button werden die Formularfelder in einer Tabelle (Historie) angefügt.
Das funktioniert soweit reibungslos:
Private Sub Update_Click()
On Error GoTo Err_Update_Click
Dim stDocName As String
Dim ttab1 As DAO.Recordset
Set ttab1 = CurrentDb.OpenRecordset("Select * from HistorieHaupttabelle", dbOpenDynaset)
ttab1.AddNew
ttab1!von = Me!von
ttab1!bis = Me!bis
ttab1!Name = Me!Name
ttab1!Abteilung = Abteilung
ttab1.Update
ttab1.Close
Set ttab1 = Nothing
Forms!Hauptformular!HistorieHauptformular.Form.Requery
Exit_Update_Click:
Exit Sub
Err_Update_Click:
MsgBox Err.Description
Resume Exit_Update_Click
End Sub
Zu meinem Problem:
Ich möchte das nur ein neuer datensatz in der Historie angefügt wird wenn sich an dem "von" oder an dem "bis" im Formular etwas verändert hat.
Wird beispielweise nur die Abteilung geändert (von und bis ändern sich nicht), soll der Datensatz überschrieben werden der das gleiche "von" und "bis" enthält.
Hat da jemand eine Idee? Ich benutze übrigens Access 97
Gruß Inka
Antwort schreiben
Antwort 1 von Marie vom 12.01.2021, 02:35 Options
Mit einer Schleife geht das ganz einfach:
Du durchsuchst zuerst die Tabelle, ob ein Datensatz existiert, der die Kriterien:
ttab1!von = Me!von AND ttab1!bis = Me!bis
erfüllt,
wenn ja, dann überschreibste die Daten
else
Zitat:
Set ttab1 = CurrentDb.OpenRecordset("Select * from HistorieHaupttabelle", dbOpenDynaset)
ttab1.AddNew
ttab1!von = Me!von
ttab1!bis = Me!bis
ttab1!Name = Me!Name
ttab1!Abteilung = Abteilung
ttab1.Update
ttab1.Close
Set ttab1 = Nothing
Forms!Hauptformular!HistorieHauptformular.Form.Requery
end if
Gruß Marie
Antwort 2 von Inka2009 vom 23.01.2021, 11:36 Options
Hallo Marie!
Hab erst jetzt geschafft mir deine Antwort anzuschauen. Leider hilft es mir nicht ganz weiter. Das was du schreibst hab ich mir auch gedacht, nur kann ich es nicht umsetzen. Ich bin halt son typisches Beispiel von "learning by doing", aber ich kann mir aus meinen vorhandene Wissensfetzen keinen brauchbaren Code zusammen basteln. Ich versuch selbst darauf zu kommen, wäre aber schön, wenn du mir das mit der "Schleife" nochmal erklären könntest.
Danke,
Inka!
Antwort 3 von Inka2009 vom 23.01.2021, 13:37 Options
Hallo nochmal
Ich habe versuchte eine if...then-Anweisung zu schreiben:
Private Sub Update_Click()
On Error GoTo Err_Update_Click
If ttab1!von = Me!von And ttab1!bis = Me!bis Then
ttab1!Abteilung = Me!Abteilung
Else
Dim ttab1 As DAO.Recordset
Set ttab1 = CurrentDb.OpenRecordset("Select * from HistorieHaupttabelle", dbOpenDynaset)
ttab1.AddNew
ttab1!von = Me!von
ttab1!bis = Me!bis
ttab1!Name = Me!Name
ttab1!Abteilung = Abteilung
ttab1.Update
ttab1.Close
Set ttab1 = Nothing
Forms!Hauptformular!HistorieHauptformular.Form.Requery
Exit_Update_Click:
Exit Sub
Err_Update_Click:
MsgBox Err.Description
Resume Exit_Update_Click
End If
End Sub
Beim Audführen kommt die Meldung "Mehrfachdeklarationen im Gültigkeitsbereich"
Da mir ein ganzes Stück VBA-Verständnis fehlt ist der Code höchstwarscheinlich totaler Murks. Ich bin schon echt verzweifelt und hoffe, das jemand eine Lösung parat hat, die ich umsetzen kann.
Danke!
Antwort 4 von Inka2009 vom 23.01.2021, 14:05 Options
Hier mal ein Link zu der Datenbank:
http://www.buenn.de/Testdatenbank.mdb
Antwort 5 von lorf55 vom 24.01.2021, 01:04 Options
Hallo,
ich habe mich auch mal dran probiert und es ist das rausgekommen:
Private Sub Update_Click()
On Error GoTo Err_Update_Click
Dim ttab1 As DAO.Recordset
Set ttab1 = CurrentDb.OpenRecordset("Select * from HistorieHaupttabelle", dbOpenDynaset)
ttab1.MoveLast
ttab1.MoveFirst
Do While (Not ttab1.EOF)
If (ttab1.Fields("Name") = Me!Name) Then
If ttab1!von = Me!von And ttab1!bis = Me!bis Then
ttab1.Edit
ttab1!Abteilung = Me!Abteilung
Else
ttab1.AddNew '
ttab1!von = Me!von
ttab1!bis = Me!bis
ttab1!Name = Me!Name
ttab1!Abteilung = Abteilung
End If
ttab1.Update
End If
ttab1.MoveNext
Loop
ttab1.Close
Set ttab1 = Nothing
Forms!Hauptformular!Historieformular.Form.Requery
Exit_Update_Click:
Exit Sub
Err_Update_Click:
MsgBox Err.Description
Resume Exit_Update_Click
End Sub
Damit wird die Historietabelle nach dem Namen im Formular durchsucht. Wird er nicht gefunden, passiert nichts. Wird er gefunden, wird die Abteilung aktualisiert, wenn von und bis gleich sind, sonst wird ein neuer mit gleichem Namen angefügt. Das ist vielleicht noch nicht ganz sauber, aber du wirst die Fehler schon finden.
Gruß
lorf
Antwort 6 von Inka2009 vom 26.01.2021, 09:42 Options
Danke lorf!
Das funktioniert soweti schon mal besser als alles was ich bisher zusammengefummelt habe.
Einen Haken gibt es aber... wenn in der Historie noch kein Datensatz vorhanden ist, dann kommt die meldung "kein aktueller Datensatz". Ist auch logisch, aber eine Lösung habe ich noch nicht. Werd mich damit mal weiter auseinander setzen. Wenn jemand zwischenzeitlich eine Lösung findet -immer her damit!
LG Inka
Antwort 7 von lorf55 vom 26.01.2021, 18:03 Options
Das Problem ist das:
Zitat:
ttab1.MoveLast
ttab1.MoveFirst
Man kann das vielleicht auch weglassen; weiß ich nicht.
Es soll eigentlich nur alles bis zum Ende einlesen.
So ist es sicher besser:
Private Sub Update_Click()
On Error GoTo Err_Update_Click
Dim ttab1 As DAO.Recordset
Set ttab1 = CurrentDb.OpenRecordset("Select * from HistorieHaupttabelle", dbOpenDynaset)
If (Not ttab1.EOF) Then
ttab1.MoveLast
ttab1.MoveFirst
Do While (Not ttab1.EOF)
' Name ist hier nicht gut, besser ist Personalnummer o.ä.,
' um Doppeldeutigkeiten zu vermeiden
If (ttab1.Fields("Name") = Me!Name) Then
If ttab1!von = Me!von And ttab1!bis = Me!bis Then
ttab1.Edit
ttab1!Abteilung = Me!Abteilung
Else
ttab1.AddNew
ttab1!von = Me!von
ttab1!bis = Me!bis
ttab1!Name = Me!Name
ttab1!Abteilung = Abteilung
End If
ttab1.Update
End If
ttab1.MoveNext
Loop
End If
ttab1.Close
Set ttab1 = Nothing
Forms!Hauptformular!Historieformular.Form.Requery
Exit_Update_Click:
Exit Sub
Err_Update_Click:
MsgBox Err.Description
Resume Exit_Update_Click
End Sub
Wie ich oben schon als Kommentar eingefügt habe, ist die Abfrage
auf den Namen nicht so ideal, besser ist eine eindeutige Personalnummer (Bernd Meyer gibts öfters), aber das weißt du sicher selber.
Gruß
lorf
Antwort 8 von RaHi vom 26.01.2021, 21:10 Options
Hallo Inka2009,
die Sache mit der Schleife ist nicht besonders effizient. Da du netter Weise deine MDB ins Netz gestellt hast, hier eine Variante. Ich suche zunächst den Datensatz. habe ich in nicht gefunden (nomatch) gibt es ein .addnew, sonst ein .edit. Ein paar Zeilen habe ich hinter das Exit-Label verschoben, weil auch bei einem Fehler die Tabelle sauber geschlossen werden sollte. Hier der Code:
Private Sub Update_Click()
On Error GoTo Err_Update_Click
Dim ttab1 As DAO.Recordset
Set ttab1 = CurrentDb.OpenRecordset("Select * from HistorieHaupttabelle", dbOpenDynaset)
ttab1.FindFirst ("[von] = #" & Format(Me!von, "mm\/dd\/yyyy") & "# and [bis] = #" & Format(Me!bis, "mm\/dd\/yyyy") & "#")
If ttab1.NoMatch Then
'
' neuer Datensatz, da [von] und [bis] in der Historie nicht vorhanden
'
ttab1.AddNew
ttab1!von = Me!von
ttab1!bis = Me!bis
ttab1!Name = Me!Name
ttab1!Abteilung = Abteilung
Else
'
' Datensatz aktualisieren, da [von] und [bis] in der Historie vorhanden
'
ttab1.Edit
ttab1!Name = Me!Name
ttab1!Abteilung = Abteilung
End If
ttab1.Update
Forms!Hauptformular!HistorieHauptformular.Form.Requery
Exit_Update_Click:
On Error Resume Next
ttab1.Close
Set ttab1 = Nothing
Exit Sub
Err_Update_Click:
MsgBox Err.Description
Resume Exit_Update_Click
End Sub
Insgesamt lässt sich da aber noch mehr optimieren...
Ich benutze Access 2003 unter Vista, was aber kein Problem sein sollte.
Gruß
Ralf
Antwort 9 von Marie vom 27.01.2021, 03:15 Options
Na das ist jetzt exakt das, was ich in der allerersten Antwort bereits am 12.1. geschrieben habe.
Gruß Marie