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
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.
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