Neuigkeiten:

Wenn ihr euch für eine gute Antwort bedanken möchtet, im entsprechenden Posting einfach den Knopf "sag Danke" drücken!

Mobiles Hauptmenü

Formular legt Datensatz doppelt an

Begonnen von Roadrunner, Januar 11, 2012, 13:02:46

⏪ vorheriges - nächstes ⏩

Roadrunner

Mahlzeit,
ich habe eine recht große Datenbank angelegt, die bis auf eine Kleinigkeit super funktioniert.

Es geht um eine Antrags-Verwaltungsdatenbank für meine Fakultät an der Uni.
Ein oder mehrere Lehrstühle können zusammen einen Antrag stellen, weshalb ich eine Relation angelegt habe, die diese beiden Tabellen referenziert.

Nun zu meinem Problem:
Es gibt ein Formular "Neuer Antrag", in das sämtliche Antragsdaten eingetragen werden. Teilweise geschieht das durch Dialoge, in denen man Checkboxes anhaken oder Datensätze suchen und auswählen kann. Bei schließen dieser Dialoge werden die gewählten Daten an Listen oder Texteingabefelder des Antragsformulars übergeben.

Mir ist dann aufgefallen, dass beim Speichern des Antragsformulars doppelte Einträge erstellt werden. Bei weiterer Untersuchung der Sache bemerkte ich, dass zunächste ein Teil-Datensatz nach Rückgabe des einen Dialogs angelegt wird und beim Klicken auf den Speichern-Button am Ende dann der gesamte Datensatz nochmal gesondert gespeichert wird. Zunächst vermutete ich, es läge daran, dass dies der einzige Dialog war, den ich via Button-Klick öffnete (Restliche öffnen durch OnKlick-Action in Textfeld). Ich legte also ein OnKlick für meine Liste an, in die die Ausgewählten Lehrstühle gespeichert werden sollen. Dies brachte keine Änderung.

Google lieferte mir den Vorschlag, das Formular ungebunden zu betreiben, darufhin stand im ersten Textfeld "#Name?" und es lässt sich nichts eingeben.

Ist dieses Problem bekannt?

Leider wusste ich nicht nach welchen Schlagworten ich genau suchen sollte, weshalb alle Versuche über die Suchfunktion und Google eine Lösung zu finden im Sande verliefen.

Das Formular "Neuer Antrag" öffne ich über folgenden Code

Private Sub neuer_Antrag_Click()
          DoCmd.OpenForm "FormNeuerAntrag", acNormal, , "", , ac´Normal
End Sub


Die "LehrstuhlWahl" öffne ich über
Private Sub ListeLehrstuehle_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
    DoCmd.OpenForm "FormLehrstuhlWahl", acNormal, , "", , acDialog
End Sub


Habe ich da über die Parameter etwas falsch gemacht?

In der "LehrstuhlWahl" befindet sich eine Liste, in der man eine Mehrfachauswahl treffen soll. Diese Auswahl soll im Antragsformular in eine nicht sichtbare Liste für die ID's und eine Sichtbare Liste für den Nutzer gespeichert werden. Das läuft über folgenden Code

    Dim I As Variant
    Dim ListeLehrstID As String
    Dim ListeLehrstuehle As String

    ListeLehrstuehle = ""
    ListeLehrstID = ""
   
    For Each I In Me!Liste.ItemsSelected
        ListeLehrstID = ListeLehrstID & "'" & Me!Liste.Column(0, I) & "';"
        ListeLehrstuehle = ListeLehrstuehle & "'" & Me!Liste.Column(1, I) & "';'" & Me!Liste.Column(2, I) & "';"
    Next I
   
    If IstGeladen("FormNeuerAntrag") Then
        Forms!FormNeuerAntrag.ListeLehrstID.RowSourceType = "Value List"
        Forms!FormNeuerAntrag.ListeLehrstID.RowSource = ListeLehrstID
   
        Forms!FormNeuerAntrag.ListeLehrstuehle.RowSourceType = "Value List"
        Forms!FormNeuerAntrag.ListeLehrstuehle.RowSource = ListeLehrstuehle
    End If
    If IstGeladen("FormAntragÄndern") Then
        Forms!FormAntragÄndern.ListeLehrstID.RowSourceType = "Value List"
        Forms!FormAntragÄndern.ListeLehrstID.RowSource = ListeLehrstID
   
        Forms!FormAntragÄndern.ListeLehrstuehle.RowSourceType = "Value List"
        Forms!FormAntragÄndern.ListeLehrstuehle.RowSource = ListeLehrstuehle
    End If
     
    DoCmd.Close

Die Methode "IstGeladen" war notwendig, da ich den Dialog auch von dem Formular für Änderungen an dem Antrag verwende. Das Formular für Änderungen ist leider noch nicht Fertig um meinen Problemfall dort zu testet. Die Methode sieht so aus
Function IstGeladen(MeinFormularname As String)
   
    Dim I

    IstGeladen = False

    For I = 0 To Forms.Count - 1
        If Forms(I).FormName = MeinFormularname Then
            IstGeladen = True
            Exit Function
        End If
    Next
End Function


Die Befehle zum Speichern sind sehr unübersichtlich, trotzdem Poste ich den mal im Ganzen. Soweit ich das sehe, wird der "Nonsense-Eintrag" ohnehin vor dem Klick auf "Speichern" angelegt.

Private Sub Speichern_Click()
If ValidUser() Then
    Dim vollstaendig As Boolean
    vollstaendig = True
   
    Dim heute As String
    Dim Datum As Date
    heute = Date
    Datum = Format(CDate(Me!TextAntragsDatum), "dd.mm.yyyy")
   
       
    If Datum = heute Then
        MsgBox ("Das eingegebene Datum ist das Heutige! Bitte Datum im Datensatz ändern, falls der Antrag nicht heute gestellt wurde!")
    End If
               
    If Trim(Nz(Me!TextAntragsteller, "")) = "" Then
        MsgBox ("Das Feld für den Antragsteller darf nicht leer sein!")
        vollstaendig = False
    End If
    If Me!ListeLehrstID.ListCount = 0 Then
        MsgBox ("Das Feld für die Lehrstühle/Institute darf nicht leer sein!")
        vollstaendig = False
    End If
    If Trim(Nz(Me!TextBetreff, "")) = "" Then
        MsgBox ("Das Feld für den Betreff darf nicht leer sein!")
        vollstaendig = False
    End If
   
    If Trim(Nz(Me!TextModulID, "")) = "" Then
        MsgBox ("Das Feld für den Modultitel darf nicht leer sein!")
        vollstaendig = False
    End If
    If Trim(Nz(Me!TextErlaeuterung, "")) = "" Then
        MsgBox ("Das Feld für die Erläuterung darf nicht leer sein!")
        vollstaendig = False
    End If
    If vollstaendig = True Then
   
    On Error GoTo Err_Speichern
    Dim oRst As DAO.Recordset
    Dim csql As String

    'Neuer Antrag
    csql = "select * from Antrag"
    Set oRst = CurrentDb.OpenRecordset(csql)
    With oRst
    .AddNew
    .Fields("Betreff").Value = Me.TextBetreff
    .Fields("Erlaeuterung").Value = Me.TextErlaeuterung
    .Fields("Zeitpunkt").Value = Me.TextAntragsDatum
    .Fields("Veranstaltungstyp").Value = Me.TextArt
    .Fields("ModulbeschreibungVorhanden").Value = Me.Check2
    .Fields("BefuerwortungVorhanden").Value = Me.Check3
    .Fields("FormularVollstaendig").Value = Me.Check1
    .Fields("Bemerkungen").Value = Me.TextBemerkungen
    .Fields("CreditPoints").Value = Me.TextCP
    .Fields("SemesterWochenStunden").Value = Me.TextSWS
    .Fields("Benotung").Value = Me.TextBenotung
    .Fields("Pruefungsart").Value = Me.TextPruefungsart
    .Fields("Pruefungsform").Value = Me.TextPruefungsform
    .Fields("Lehrform").Value = Me.TextLehrform
    .Fields("Dauer").Value = Me.TextDauer
    .Fields("TurnusStart").Value = Me.TextTurnus
    .Fields("Fachsemester").Value = Me.TextFachsemster
    .Fields("Lehrende").Value = Me.TextLehrende
    .Fields("ModulID").Value = Me.TextModulID
    .Fields("Veranstaltungen").Value = Me.TextVeranst
    .Fields("Antragsteller").Value = Me.TextAntragsteller
    .Fields("Gueltigkeitsdatum").Value = Me.TextGueltigkeit
    .Fields("Studiengang").Value = Studiengaenge()
    .Update
    .Close
    End With
    Set oRst = Nothing
   
    'Antrag ID
    Dim neueID As Integer
    csql = "select ID from Antrag order by ID"
    Set oRst = CurrentDb.OpenRecordset(csql)
    oRst.MoveLast
    neueID = oRst!ID
    Set oRst = Nothing
   
    'Lehrstühle speichern
    For I = 0 To Me!ListeLehrstID.ListCount - 1
   
      csql = "select * from vonLehrstuhl"
      Set oRst = CurrentDb.OpenRecordset(csql)
      With oRst
      .AddNew
      .Fields("Lehrstuhl").Value = Me!ListeLehrstID.Column(0, I)
      .Fields("Antrag").Value = neueID
      .Update
      .Close
      End With
    Set oRst = Nothing
   
    Next I

   

    csql = "select * from Veranstaltungen"
    Set oRst = CurrentDb.OpenRecordset(csql)
    With oRst
    .AddNew
    .Fields("V1").Value = Me!V1
    .Fields("V2").Value = Me!V2
    .Fields("V3").Value = Me!V3
    .Fields("V4").Value = Me!V4
    .Fields("V5").Value = Me!V5
    .Fields("V6").Value = Me!V6
    .Fields("V7").Value = Me!V7
    .Fields("V8").Value = Me!V8
    .Fields("V9").Value = Me!V9
    .Fields("V10").Value = Me!V10
    .Fields("V11").Value = Me!V11
    .Fields("V12").Value = Me!V12
   
    .Fields("S1").Value = Me!S1
    .Fields("S2").Value = Me!S2
    .Fields("S3").Value = Me!S3
    .Fields("S4").Value = Me!S4
    .Fields("S5").Value = Me!S5
    .Fields("S6").Value = Me!S6
    .Fields("S7").Value = Me!S7
    .Fields("S8").Value = Me!S8
    .Fields("S9").Value = Me!S9
    .Fields("S10").Value = Me!S10
    .Fields("S11").Value = Me!S11
    .Fields("S12").Value = Me!S12
   
    .Fields("C1").Value = Me!C1
    .Fields("C2").Value = Me!C2
    .Fields("C3").Value = Me!C3
    .Fields("C4").Value = Me!C4
    .Fields("C5").Value = Me!C5
    .Fields("C6").Value = Me!C6
    .Fields("C7").Value = Me!C7
    .Fields("C8").Value = Me!C8
    .Fields("C9").Value = Me!C9
    .Fields("C10").Value = Me!C10
    .Fields("C11").Value = Me!C11
    .Fields("C12").Value = Me!C12
   
    .Fields("P1").Value = Me!P1
    .Fields("P2").Value = Me!P2
    .Fields("P3").Value = Me!P3
    .Fields("P4").Value = Me!P4
    .Fields("P5").Value = Me!P5
    .Fields("P6").Value = Me!P6
    .Fields("P7").Value = Me!P7
    .Fields("P8").Value = Me!P8
    .Fields("P9").Value = Me!P9
    .Fields("P10").Value = Me!P10
    .Fields("P11").Value = Me!P11
    .Fields("P12").Value = Me!P12
   
    .Fields("AntragID").Value = neueID
    .Update
    .Close
    End With
    Set oRst = Nothing
   

    csql = "select * from Changelog"
    Set oRst = CurrentDb.OpenRecordset(csql)
    With oRst
    .AddNew
    .Fields("MitarbeiterID").Value = getUserID()
    .Fields("Datenbank").Value = "Antrag"
    .Fields("Formular").Value = "FormNeuerAntrag"
    .Fields("Beschreibung").Value = "neuer Eintrag"
    .Fields("Kommentar").Value = "ID: " & neueID & "; Betrifft Modul: " & Me!TextModulTitel
    .Update
    .Close
    End With
    Set oRst = Nothing
   

    csql = "select * from Bearbeitung"
    Set oRst = CurrentDb.OpenRecordset(csql)
    With oRst
    .AddNew
    .Fields("MitarbeiterID").Value = getUserID()
    .Fields("AntragID").Value = neueID
    .Fields("Aenderungen").Value = "neuer Eintrag"
    .Update
    .Close
    End With
    Set oRst = Nothing
     
    DoCmd.Close acForm, "FormNeuerAntrag"

Exit_Speichern_Click:
    Exit Sub
Err_Speichern:
    MsgBox Err.Description
    Resume Exit_Speichern_Click
           
    End If
End If
End Sub


So das sollte es sein ... oder fehlen noch Informationen?

Hat jemand eine Idee für die Lösung zu meinem Problem?

Viele Grüße und vielen Dank schonmal,
Roadrunner116

MzKlMu

#1
Hallo,
mit Grossposting machst Du Dir keine Freunde. Meistens gibt es dann gar keine Antwort.

http://www.office-loesung.de/ftopic502599_0_0_asc.php

Mir scheint hier eher ein problematisches Datenmodell vorzuliegen.
Und Formulare per Recordset zu füllen ist im Regelfall bei Access nicht notwendig. Einfache gebundene Formulare erfüllen da viel besser ihren Zweck.
Und wenn Du eine Mischung hast von gebunden und Recordset hast Du 2 datensätze.
Bei einem korrekten Datenmodell ist es nicht notwendig sich den Krampf mit Recordsets und ungebunden Formularen anzutun.
Gruß Klaus

Klingon 33

Prinzipel ist das oben gesagte richtig.
aber:
wenn du vor dem Speichern in dem Recordset nachschaust, ob bereits ein Eintrag existiert kannst du mit einem einfachen If auswählen, ob du anfügen oder Editieren willst.
also:

oRST.FindFirst("Betreff = '" & me!TextBetreff & "'")  'Betreff mus eindeutig sein oder ein anders Feld verwenden
if oRST.noMatch then
oRST.addnew
...
else
oRST.Edit
...
end if
Wer Fehler findet, dar diese behalten.