Hallo,
ich möchte in einem Unterformular mit
- einem Kombinationsfeld und 2 Textfeldern
mit VBA einen Datensatz für dieses Unterformular anlegen und in der zugehörigen Tabelle speichern.
Dabei erhalte ich an der Stelle
- vProtokollTyp = Forms!ProtokollNotizUF.txtProtokollTyp
- Fehlermeldung: Laufzeitfehler '2450'
- Microsoft Access kann das Formular 'ProtokollNotizUF' nicht finden, auf das verwiesen wird
Folgende Umgebung:
- Formular: TeilnehmerAdressdatenF
- Unterformular: ProtokollNotizUF
- Tabelle, in die gespeichert wird: ProtokollT
- Das Unterformular ist korrekt mit dem Hauptformular verknüpft
Vielen Dank für die Hilfe!
Public Sub AddRecordProtokollT()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim vProtokollTyp As Integer
Dim vSubject As String
Dim vBody As String
Dim vTeilnehmerID As Integer
Dim vDateTime As Date
Set db = CurrentDb
Set rs = db.OpenRecordset("ProtokollT", dbOpenDynaset)
Forms!TeilnehmerAdressdatenF!ProtokollNotizUF.SetFocus
vProtokollTyp = Forms!ProtokollNotizUF.txtProtokollTyp
vSubject = Forms!ProtokollNotizUF.txtSubject
vBody = Forms!ProtokollNotizUF.txtBody
vTeilnehmerID = Forms!ProtokollNotizUF.TeilnehmerID
vDateTime = Now
rs.AddNew
rs!ProtokollTypID = vProtokollTyp
rs!Subject = vSubject
rs!Body = vBody
rs!TeilnehmerID = vTeilnehmerID
rs!DateTime = vDateTime
rs.Update
rs.Close
Set rs = Nothing
Set db = Nothing
End Sub
Hallo,
wenn Hafo und UFO verknüpft sind, sind die Formulare doch gebunden.
Dann kannst du doch direkt in die Felder schreiben, da braucht man doch keinen Code.
Vielen Dank für die Antwort.
Das könnte ich natürlich machen...ich will aber oberhalb des Endlos-Formulars Datensätze eintragen und diese abspeichern. Die Datensätze im Unterformular werden dann auch so sortiert, dass der neueste Datensatz oben steht...die Datensatzliste ist auch sehr lang... für den Anwender ist die Eingabe über die Felder oberhalb des Formulars wesentlich angenehmer als unten am Ende der Liste...und der aktuellste Datensatz steht dann sofort wieder oben im Blickfeld.
Hallo,
warum so kompliziert ?
Stelle das Ufo für einen neuen Datensatz auf Daten eingeben=Ja (per Button im Kopf des Ufos).
Dann gibt es nur einen leeren Datensatz für die neue Eingabe.
Nach Abschluss der Eingabe (Nach Aktualisierung) wieder Daten eingeben=Nein, dann noch ein Me.Requery und alle DS in der Sortierreihenfolg sind da, auch der neue Datensatz.
Das sind 3 Zeilen Code für den Button.
Ansonsten musst Du beim Namen des Ufos den Namen des Ufosteuerlements verwenden. Siehe Eigenschaften des Ufos.
Vielen Dank an alle, die geholfen haben :)
mir persönlich gefällt die Lösung mit den separaten Eingabefeldern besser, weil ich damit aus dem Bereich des Endlos-Formulars bleiben kann. Das ist aber eine Geschmackfrage.
Ich bin jetzt direkt über den Button eingestiegen und konnte dann Me. verwenden. Damit war die Bezugsproblematik gelöst.
Der Code sieht jetzt so aus:
Private Sub cmdOrdnerAnlegen_Click()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim vProtokollTyp As Integer
Dim vSubject As String
Dim vBody As String
Dim vTeilnehmerID As Integer
Dim vDateTime As Date
Set db = CurrentDb
Set rs = db.OpenRecordset("ProtokollT", dbOpenDynaset)
If vProtokollTyp = 0 Or vSubject = "" Or vBody = "" Then
MsgBox "Bitte Werte eintragen"
Exit Sub
End If
vProtokollTyp = Me.txtProtokollTyp
vSubject = Me.txtSubject
vBody = Me.txtBody
vTeilnehmerID = Me.TeilnehmerID
vDateTime = Now
rs.AddNew
rs!ProtokollTypID = vProtokollTyp
rs!Subject = vSubject
rs!Body = vBody
rs!TeilnehmerID = vTeilnehmerID
rs!DateTime = vDateTime
rs.Update
Me.Requery
rs.Close
Set rs = Nothing
Set db = Nothing
End Sub
@Umbauwfb Zitatmir persönlich gefällt die Lösung mit den separaten Eingabefeldern besser
Warum dann ein Endlosform?
Ich mache das bei manchen Formularen ähnlich, verwende aber ein Einzelform
mit gebundenen Eingabefeldern. Die Datensätze zeige ich in einem Listfeld
mit der gleichen DS-Herkunft wie das UFo an. Dann kannst du einerseits den
Vorschlag von Klaus umsetzen, und andererseits über einen Klick auf die Liste
den ausgewählten DS zum editieren anzeigen/freigeben.
Zitatdie Datensatzliste ist auch sehr lang
Hier hättest du mit dem Listfeld und weiteren geeigneten Controls die Mög-
lichkeit die Liste zu vorzufiltern, was mit deinem UFo natürlich auch geht.
gruss ekkehard
Zuerst einmal vielen Dank für die Rückmeldungen und die Vorschläge.
Ich muss jetzt noch einmal dazu sagen, dass ich Anfänger bin und noch sehr viel Zeit brauche, wenn sich irgendwo Hindernisse auftun...insofern bin ich sehr froh, dass ich mit meiner jetzigen Lösung eigentlich schon am Ziel bin. Eure Vorschläge wende ich gerne im Anschluss an. Ich habe ein Hauptformular, für das ich einige UFs benötige.
Bisher habe ich auch noch nicht erwähnt, dass ich die UFs unter einem Registersteuerelement einbaue...vielleicht hat da meine Ansprache auch nicht ganz gestimmt...weil ich das Registersteuerelement in der Ansprache nicht berücksichtigt habe...(konnte...)
Ich bin jetzt aber so weit, dass die Erfassung mit der jetzigen Lösung einwandfrei funktioniert...SOBALD DER ERSTE DATENSATZ ERFASST WAR...ist noch kein Datensatz erfasst, bricht der Code am Requery ab
- Laufzeitfehler 3101...der gerade erfasste Datensatz ist nicht komplett abgespeichert.
Wenn ich den Debug beende und den nächsten Hauptdatensatz anwähle, wieder zurückgehe, ist der Datensatz gespeichert.
Mit welchem Befehl bekomme oich den Datensatz gespeichert? Ich kämpfe da jetzt schon den ganzen Tag mit rum...
Vielen Dank für Ratschläge und Hilfe...
Der Code sieht jetzt so aus:
Private Sub cmdDatensatzSpeichern_Click()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim vProtokollTyp As Integer
Dim vSubject As String
Dim vBody As String
Dim vTeilnehmerID As Integer
Dim vDateTime As Date
Set db = CurrentDb
Set rs = db.OpenRecordset("ProtokollT", dbOpenDynaset)
'If vProtokollTyp = 0 Or vSubject = "" Or vBody = "" Then
' MsgBox "Bitte Werte eintragen"
' Exit Sub
'End If
Me.TeilnehmerID = Forms!TeilnehmerAdressdatenF.ID
vProtokollTyp = Me.txtProtokollTyp
vSubject = Me.txtSubject
vBody = Me.txtBody
vTeilnehmerID = Me.TeilnehmerID
vDateTime = Now
rs.AddNew
rs!ProtokollTypID = vProtokollTyp
rs!Subject = vSubject
rs!Body = vBody
rs!TeilnehmerID = vTeilnehmerID
rs!DateTime = vDateTime
rs.Update
rs.Close
Me.Requery
Me.txtSubject = ""
Me.txtBody = ""
Set rs = Nothing
Set db = Nothing
End Sub
Gelöst...mit einem einfachen "ESC" im Code... :)
Private Sub cmdOrdnerAnlegen_Click()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim vProtokollTyp As Integer
Dim vSubject As String
Dim vBody As String
Dim vTeilnehmerID As Integer
Dim vDateTime As Date
Set db = CurrentDb
Set rs = db.OpenRecordset("ProtokollT", dbOpenDynaset)
'If vProtokollTyp = 0 Or vSubject = "" Or vBody = "" Then
' MsgBox "Bitte Werte eintragen"
' Exit Sub
'End If
Me.TeilnehmerID = Forms!TeilnehmerAdressdatenF.ID
vProtokollTyp = Me.txtProtokollTyp
vSubject = Me.txtSubject
vBody = Me.txtBody
vTeilnehmerID = Me.TeilnehmerID
vDateTime = Now
rs.AddNew
rs!ProtokollTypID = vProtokollTyp
rs!Subject = vSubject
rs!Body = vBody
rs!TeilnehmerID = vTeilnehmerID
rs!DateTime = vDateTime
rs.Update
rs.Close
Me.txtSubject = ""
Me.txtBody = ""
Set rs = Nothing
Set db = Nothing
End Sub
Private Sub cmdDatensatzSpeichern_Click()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim vProtokollTyp As Integer
Dim vSubject As String
Dim vBody As String
Dim vTeilnehmerID As Integer
Dim vDateTime As Date
Set db = CurrentDb
Set rs = db.OpenRecordset("ProtokollT", dbOpenDynaset)
'If vProtokollTyp = 0 Or vSubject = "" Or vBody = "" Then
' MsgBox "Bitte Werte eintragen"
' Exit Sub
'End If
Me.TeilnehmerID = Forms!TeilnehmerAdressdatenF.ID
vProtokollTyp = Me.txtProtokollTyp
vSubject = Me.txtSubject
vBody = Me.txtBody
vTeilnehmerID = Me.TeilnehmerID
vDateTime = Now
rs.AddNew
rs!ProtokollTypID = vProtokollTyp
rs!Subject = vSubject
rs!Body = vBody
rs!TeilnehmerID = vTeilnehmerID
rs!DateTime = vDateTime
rs.Update
rs.Close
SendKeys "{ESC}" 'Ist nötig, damit der ERSTE Datensatz in der Tabelle "ProtokollT" gespeichert wird
DoEvents 'Ansonten erfolgt Abbuch des Code bei "Me.Requery"
'Weil der ERSTE Datensatz vor dem Requery nicht zur Verfügung steht
'Alle weiteren Datensätze nach dem ERSTEN wären unkritisch...
'warum????...egal
Me.Requery
Me.txtSubject = ""
Me.txtBody = ""
Set rs = Nothing
Set db = Nothing
End Sub
ZitatSendKeys "{ESC}" 'Ist nötig, damit der ERSTE Datensatz in der Tabelle "ProtokollT" gespeichert wird
Das ist im Normalfall Unsinn. Mit rs.Update ist der Datensatz in der Tabelle gespeichert, falls kein Fehler (Index-, Datentyp-, Gültigkeits-, fehlende Pflichtangabe, Verstoß gegen RI) auftritt.
Wenn die Speicherung des Datensatzes erfolgt ist, kann er per Requery auch ins Formular geholt werden (Datenherkunft überprüfen).
Deine Variablen sind überflüssig. Etwa:
Private Sub cmdDatensatzSpeichern_Click()
Dim db As DAO.Database
Dim rs As DAO.Recordset
' Die verwendeten Steuerelemente wären nach Bedarf auf Inhalt zu prüfen.
Set db = CurrentDb
Set rs = db.OpenRecordset("SELECT * FROM ProtokollT WHERE False", dbOpenDynaset)
' Für ein schlichtes Anfügen kann das Recordset leer geladen werden, geht schneller
With rs
.AddNew
!ProtokollTypID = Me.txtProtokollTyp
!Subject = Me.txtSubject
!Body = Me.txtBody
!TeilnehmerID = Me.Parent.TeilnehmerID
!DateTime = Now ' Feldname DateTime kann kritisch sein, weil reserviertes Wort
.Update
.Close
End With
Me.Requery
Me.txtSubject = ""
Me.txtBody = ""
Set rs = Nothing
Set db = Nothing
End SubFalls es interessiert: Statt des Recordset-AddNew könnte man auch eine Anfüge-Parameterabfrage verwenden, siehe Grundlagen - SQL ist leicht (16) - Abfragen mit Parametern (https://www.ms-office-forum.net/forum/showthread.php?p=2028899#post2028899), Abschnitt 6, ExecuteParamQuery
Vielen Dank für diese detaillierte und umfangreiche Antwort :)
Das hilft mir sehr in meiner Weiterentwicklung.
Ich werde jetzt alles gründlich prüfen und überdenken.
Zu dem[ESC]...
Das Problem habe ich in der Meldung vom Januar 20, 2022, 18:49:21 in diesem Thread beschrieben...
Der erste Datensatz wird nicht komplett in die Tabelle geschrieben. Das sieht man dann auch im Formular.
Bei dem Requery erfolgt dann der Ausstieg aus dem Code mit der beschriebenen Meldung.
Wenn ich danach mit der Tastatur und ESC aus dem unvollständigen Datensatz im Formular rausgehe, ist der Datensatz korrekt in die Tabelle geschrieben. Alle Informationen sind vorhanden. Und werden beim erneuten Aufrufen auch im Formular angezeigt...
Alle weiteren Datensätze machen dann keine Schwierigkeiten...Um dem Problem aus dem Weg zu gehen habe ich dann das [ESC] im Code gesetzt. Jetzt läuft alles einwandfrei...
Ich habe vorher 2 Tage im Web recherchiert. Dieses Problem wird oft beschrieben. Oft wird dann beschrieben dass der Focus auf ein Steuerelement gesetzt werden muss und wieder zurückgesetzt werden muss, um die Speicherung des Datensatzes anzustoßen...Das habe ich nicht hinbekommen...
Warum das so ist??? Das übersteigt bei weitem mein Urteilungsvermögen...
Den Rest schaue ich mir sehr gründlich an und werde im Bedarfsfall sehr gerne noch einmal nachfragen :)
Schöne Grüße aus Lüneburg
Ich habe den Code eingebaut...alles läuft top....
Und ist so viel einfacher aufgebaut :)
Ich habe durch diesen Code viel gelernt! Für die nächsten Projekte!
Schöne Grüße aus Lüneburg