Probleme beim Löschen von Datensätzen über Visual Basic

  • VB6

Es gibt 5 Antworten in diesem Thema. Der letzte Beitrag () ist von raist10.

    Probleme beim Löschen von Datensätzen über Visual Basic

    Hallo, ich habe folgendes Problem ich habe 2 Buttons der eine löscht auf dem Form_frm_Teilnehmerdaten eine Zuordnung und der andere löscht auf dem Form_frm_Sozialarbeiter einen Datensatz. Alleine funktionieren beide wunderbar nur wenn ich erst die Zuordnung lösche und dann den Account löscht er mir mit dem 2ten Button ein völlig falschen Datensatz in der Tabelle Teilnehmerdaten. Die Buttons stehen beide auf Form_frm_Sozialarbeiter.
    Hier mal der Quellcode von den Buttons:

    Visual Basic-Quellcode

    1. Private Sub Befehl9_Click()
    2. On Error GoTo Err_Befehl9_Click
    3. 'Zuordnung prüfen und gegebenfalls Datenfeld Teilnehmerdaten Zuordnung zum Sozialarbeiter löschen
    4. Form_frm_Teilnehmerdaten.Recordset.FindFirst "[ID-SA] = '" & Me![Liste6] & "'"
    5. If Form_frm_Teilnehmerdaten.Recordset.NoMatch = False Then
    6. Form_frm_Teilnehmerdaten.Recordset.Edit
    7. Form_frm_Teilnehmerdaten.Recordset![ID-SA].Value = Null
    8. Form_frm_Teilnehmerdaten.Recordset.Update
    9. Form_frm_Teilnehmerdaten.Recordset.FindNext "[ID-SA] = '" & Me![Liste6] & "'"
    10. If Form_frm_Teilnehmerdaten.Recordset.NoMatch = False Then
    11. Form_frm_Teilnehmerdaten.Recordset.Edit
    12. Form_frm_Teilnehmerdaten.Recordset![ID-SA].Value = Null
    13. Form_frm_Teilnehmerdaten.Recordset.Update
    14. End If
    15. End If
    16. 'Aktuallisieren
    17. DoCmd.DoMenuItem acFormBar, acRecordsMenu, 5, , acMenuVer70
    18. End Sub
    19. 'Das hier ist dann der 2te Button zum löschen
    20. Private Sub Befehl14_Click()
    21. On Error GoTo Err_Befehl14_Click
    22. 'Sozialarbeiter löschen
    23. Dim zuordnung As String
    24. Form_frm_Teilnehmerdaten.Recordset.FindFirst "[ID-SA] = '" & Me![Liste6] & "'"
    25. If Form_frm_Teilnehmerdaten.Recordset.NoMatch = False Then
    26. zuordnung = MsgBox("Bitte löschen Sie erst die Zuordnung/en!", vbCritical, "Zuordnungen vorhanden") = vbOK
    27. Else
    28. Form_frm_Sozialarbeiter.Recordset.FindFirst "[ID-SA] = '" & Me![Liste6] & "'"
    29. If Form_frm_Sozialarbeiter.Recordset.NoMatch = False Then
    30. DoCmd.DoMenuItem acFormBar, acEditMenu, 8, , acMenuVer70
    31. DoCmd.DoMenuItem acFormBar, acEditMenu, 6, , acMenuVer70
    32. End If
    33. End If
    34. 'Aktuallisieren
    35. DoCmd.DoMenuItem acFormBar, acRecordsMenu, 5, , acMenuVer70
    36. End Sub



    Hoffe mir kann jemand weiterhelfen!

    Mit freundlichen Grüßen
    Julian

    Edit by Manschula: Für Codeabschnitte bitte den entsprechenden Tag verwenden --> VB-Tag eingefügt

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Manschula“ ()

    Helfen kann Dir vieles ... vorallem den Umgang mit VBA (und nicht VB ;) ) und vorallem die speziellen Access-Objektmodelle lernen. ^^

    Mit welcher Access Version arbeitest Du eigentlich ... uralt? Weil wenn nicht gehörst Du für die DoCmd.MenuItem-Anweisung gehauen. ;)

    Guck Dir mal die Befehlsmöglichkeiten von DoCmd.RunCommand an. Da wird Dir besser geholfen.


    Alleine funktionieren beide wunderbar nur wenn ich erst die Zuordnung lösche und dann den Account löscht er mir mit dem 2ten Button ein völlig falschen Datensatz in der Tabelle Teilnehmerdaten.


    Natürlich tut der Code das, so hast Du ihn auf jeden Fall programmiert.

    Wenn er was anderes tun soll, dann musst Du ihn auch anders programmieren.

    Das ist kein Code-Fehler sondern ein Logik-Fehler Deinerseits. Gehe mal jeden Schritt Deines Codes durch und überlege was dort passiert und Du wirst sehen wo Dein Logik-Fehler ist.

    Oder andersrum gefragt: Wie willst Du einen Datensatz an Hand des Inhaltes von Feld [ID-SA] identifizieren und löschen, wenn Du zuvor den User zwingst den Inhalt des Feldes [ID-SA] zu löschen, bzw. auf Null zu setzen? Tja, wenn Du dann den Datensatz nicht findest/indentifizieren kannst dann macht der Code was Du ihm sagst ... Datensatz auswählen und Datensatz löschen. Da er keinen gefunden hat, wählt er halt den aktuellen aus (aktuell = der auf dem der Bookmark aktuell steht) und das ist ja ganz offensichtlich der Falsche. ;)

    Und vor allem wofür das Ganze? Wenn Du einen Datensatz löscht dann wird auch automatisch der Inhalt von Feld [ID-SA] für diesen Datensatz mit gelöscht. Wieso den Inhalt des Feldes [ID-SA] also zuvor separat löschen? Macht eigentlich überhaupt keinen Sinn.

    Gruß

    Rainer
    Entschuldige hätte ich vielleicht besser beschreiben sollen.

    Das Problem ist das es sich um 2 Forms handelt und auch 2x [ID-SA]. Einmal in der Tabelle "Sozialarbeiter" und in der Tabelle "Teilnehmerdaten". Da beide [ID-SA] miteinander in Beziehung stehen kann ich den Datensatz nicht einfach so löschen. Darum greift er erst auf [ID-SA] in der Tabelle Teilnehmerdaten bzw auf dem Form Teilnehmerdaten zu und setzt dort [ID-SA] auf Null damit der 2te Button dann den Datensatz löschen kann. Nur statt den Datensatz aus der Tabelle Sozialarbeiter löscht er mir dann immer einen aus der Tabelle Teilnehmerdaten aber auch nur wenn ich zuvor Button1 geklickt habe sonst funktionierts.

    Würde halt gerne wissen wieso er auf Teilnehmerdaten zugreift wenn ich doch auf dem Sozialarbeiter Form bin. Oder ob man sonst irgendwas dazwischen schalten kann um das zu verhindern.

    Manche Befehle hab ich aus dem Internet oder über die Hilfe :thumbsup: .
    Aber größtenteils verstehe ich was gemacht wird :whistling: .

    Das Problem ist das es sich um 2 Forms handelt und auch 2x [ID-SA]. Einmal in der Tabelle "Sozialarbeiter" und in der Tabelle "Teilnehmerdaten". Da beide [ID-SA] miteinander in Beziehung stehen kann ich den Datensatz nicht einfach so löschen.


    Uff ... also gut:

    Ich verstehe das richtig, dass der "Arbeiter" in der Tabelle Sozialarbeiter geführt wird und wenn er an irgendwas teilnimmt wird er mit dem entsprechenden Event über die Tabelle Teilnehmerdaten in Beziehung gesetzt. Das erfolgt darüber das der Primary Key des Tables Sozialarbeiter dann als Foreign Key im Table Teilnehmerdaten eingetragen wird?

    Und wieso sollte dann das direkt Löschen nicht funzen? Es ist eine Sache der Beziehungsdeklaration ob bei Delete des Hauptdatensatzes im Table Sozialarbeiter auch der Eintrag im Table Teilnehmerdaten gleichzeitig mit gelösht wird. Stichwort ON DELETE UPDATE für das Table Teilnehmerdaten.

    Solltest Du übrigens in allen Beziehungen zur Tabelle Sozialarbeiter einbauen, da es u.U. mühselig wird alle Beziehungen händisch zu löschen bevor man einen DS löscht. Datenbanken verwalten referentielle Integritäten und beherrschen sowas daher automatisch ... wenn man das dann auch richtig anweist. ;)

    Grundsätzlich stellt sich aber die Frage: Was zum Henker soll der Mist das man Mitarbeiter löschen kann!? :huh:

    Das geht ja mal gar nicht. Die Standardvorgehensweise in solchen Fällen ist, dass man ein Flag von aktiv auf inaktiv einbaut.

    Der Grund ist schlicht und ergreifend das eine Datenbank auch Informationen über historische Zustände problemlos vorhalten kann und auch SOLL.


    Nur statt den Datensatz aus der Tabelle Sozialarbeiter löscht er mir dann immer einen aus der Tabelle Teilnehmerdaten aber auch nur wenn ich zuvor Button1 geklickt habe sonst funktionierts.


    Du solltest Dich ganz schnell mit der Funktionsweise vertraut machen. ;)

    Docmd hat eine unangenehme Eigenschaft: Vieles was damit machbar ist bezieht sich immer auf die aktive Form. Und nicht auf die Form oder das Modul in dem der Befehl steht. Dadurch kann es zu so unschönen Effekten kommen wie eben das nicht da wo soll gelöscht wird. Vorallem bei Verwendung der MenuItems ist das zu 100% der Fall.

    Du kannst das vermeiden in dem Du vor Ausführung der Befehle dafür sorgst das die Form aus der gelöscht werden soll auch wirklich die aktive Form ist (Stichwort SetFocus).

    Ich würde ja eher empfehlen den kompletten Code in die Tonne zu treten und es richtig zu machen, aber gut Deine Entscheidung. ;)

    Gruß

    Rainer
    Die Sozialarbeiter werden Teilnehmern zugeordnet und wenn ein Sozialarbeiter nicht mehr beschäftigt wird muss er gelöscht werden und kann sich nicht mehr um Teilnehmer kümmern. Würde man ihn nicht löschen würde man irgendwann die Übersicht auf den Forms verlieren.

    Könntest du mir die on delete update funktion nochmal näher erläutern? Es darf halt nicht der gesamte Datensatz in der Tabelle Teilnehmer gelöscht werden sondern nur das Sozialarbeiter Feld auf Null gesetzt werden. Lediglich in der Tabelle Sozialarbeiter soll dann der ganze Datensatz gelöscht werden.

    Ich weiß das der Programm Code nicht gut ist aber ich muss auch nur noch dieses Problem irgendwie lösen dann hab ich das erstmal hinter mir ;).

    raist10 schrieb:

    Zitat:
    Du kannst das vermeiden in dem Du vor Ausführung der Befehle dafür sorgst das die Form aus der gelöscht werden soll auch wirklich die aktive Form ist (Stichwort SetFocus).
    Mit setfocus hab ichs schon versucht hat nichts gebracht.

    Könnte mir vielleicht jemand ein Beispiel schreiben zum lösen des Problems?

    Werde mich erst nächste Woche wieder an die Datenbank setzen und mir dann hier alles nochmal durchlesen.

    Vielen Dank aber schonmal für die Hilfe :thumbup:

    EdvTeilnehmerliste schrieb:

    Die Sozialarbeiter werden Teilnehmern zugeordnet und wenn ein Sozialarbeiter nicht mehr beschäftigt wird muss er gelöscht werden und kann sich nicht mehr um Teilnehmer kümmern. Würde man ihn nicht löschen würde man irgendwann die Übersicht auf den Forms verlieren.


    NEIN ... ein Sozialarbeiter wird NIE UND NIMMER gelöscht! Sondern nur auf inaktiv gesetzt. Und bei diesem Vorgang wird durch eine Datenbankabfrage festgestellt zu welchen atuellen (also noch vorhandenen) Teilnehmern er als Betreuer zugeordnet ist und dann wird entsprechend verfahren. Oder andersrum man lässt sich alle Teilnehmer anzeigen denen ein Sozialarbeiter zugeordnet ist der INAKTIV ist und das Programm zwingt einen AKTIVEN Sozialarbeiter als Betreuer einzugeben.

    Zum wirklich sinnvollen Handling ist es dann natürlich nötig das die Beziehung zwischen Teilnehmer und Sozialarbeiter eine M:N Beziehung ist und deswegen über ein Zwischentable abgehandelt wird. Dieses beinhaltet zu den beiden Foreign Keys auch noch die Information von Wann bis Wann (also 2 Datumsfelder) für den Betreuungszeitraum.

    So und nicht anders wird das in einer Datenbank gehandelt. Alles andere ist völliger Unsinn.

    Stell Dir mal vor Du müsstest die Frage "Welcher Betreuer war vor 2 Jahren für den Teilnehmer XYZ verantwortlich?" beantworten. Wenn sowas simples abzubilden eine Datenbank nicht beherrschen braucht dann hör auf da noch eine Minute Arbeit reinzustecken. Jede Excel-Tabelle kann das was ihr dann haben wollt mit weniger Aufwand abbilden.


    Könntest du mir die on delete update funktion nochmal näher erläutern? Es darf halt nicht der gesamte Datensatz in der Tabelle Teilnehmer gelöscht werden sondern nur das Sozialarbeiter Feld auf Null gesetzt werden. Lediglich in der Tabelle Sozialarbeiter soll dann der ganze Datensatz gelöscht werden.


    Sorry ... es heisst natürlich korrekt ON DELETE CASCADE. Und es ist keine Funktion sondern eine Einstellung die in der Beziehung vorgenommen wird. Eben das der Inhalt des Foreign Key Feldes (und auch nur DAS) im Table Teilnehmer automatisch gelöscht wird wenn der korrespondierende Datensatz in dem Table Sozialarbeiter gelöscht wird.

    Aber ehrlich ... das ist einfachstes und simplestes Wissen das jeder der mit eine DB umgehen will beherrschen sollte. Ansonsten ist das was raus kommt eh völlig untauglich und nur für die Tonne geeignet.

    Sorry, dass ich da vllt "hart" klinge ... aber mit einer Datenbank rumfuhrwerken und nicht mal die simpelsten Basis-Kenntnisse haben geht einfach nicht. Es kommt dabei so oder so nur Müll raus.


    Ich weiß das der Programm Code nicht gut ist aber ich muss auch nur noch dieses Problem irgendwie lösen dann hab ich das erstmal hinter mir


    Genau ... und das Problem ist nicht das Dir ein Stück Code fehlt, sondern das Problem ist das Programm selber inklusive des Datenmodelles (dort werden ja solche kleinen aber wichtigen Details wie ON DELETE CASCADE festgelegt).



    Könnte mir vielleicht jemand ein Beispiel schreiben zum lösen des Problems?


    Ich zumindest nicht. :)

    Und der Grund ist einfach ich werde keinen Code schreiben um ein Problem zu lösen das bei ordentlichem Vorgehen gar nicht vorhanden wäre. Code ist wie Geld ... man schmeisst schlechten Code nicht auch noch guten Code hinterher.


    Vielen Dank aber schonmal für die Hilfe :thumbup:


    Gerne und ich helfe Dir auch gerne Dich besser in die Thematik einzuarbeiten, aber nur nicht dabei schlechten Code so hinzubiegen das er arbeitet. Wenn Du mal länger mit DB's und Programmierung zu tun hast, dann wirst Du verstehen wieso ... denn das ist ein Faß ohne Boden und wenn der Teil läuft, kommt sofort im Anschluß der nächste Teil der wieder hingebogen werden muss etc., etc., etc. ... es hört nie auf, dass ist das einzige was bei untauglichem Code absolut garantiert ist.

    Gruß

    Rainer