April 18, 2021, 01:56:00

Neuigkeiten:

Ist euer Problem gelöst, dann bitte den Knopf "Thema gelöst" drücken!


Datensatz löschen - Verhindern, dass nächste DS angezeigt wird

Begonnen von Nic-O, Mai 04, 2015, 11:36:44

⏪ vorheriges - nächstes ⏩

MaggieMay

Hi,
Zitatdas Ereignis ist das richtige.

ein Test hat ergeben, dass auf den Datensatz im Ereignis AfterDelConfirm nicht mehr zugegriffen werden kann, weil er bereits weg ist.

Wenn man das Delete-Ereignis nimmt und die Löschbestätigung anfordert, diese aber verweigert wird, so wird ein Löschvorgang protokolliert der keiner ist.

Man muss also vor dem Löschen das Protokoll schreiben und nach dem Löschen bestätigen, andernfalls wieder entfernen?
Ohne Löschbestätigung kann das also nicht gehen, oder?
Freundliche Grüße
MaggieMay

Nic-O

ich habe jetzt folgendes ausprobiert:

'Private Sub Form_AfterDelConfirm(Status As Integer)
If Status = acDeleteOK Then Call AuditChanges("Kunden_Name", "DELETE")
    End Sub

Private Sub Form_BeforeUpdate(Cancel As Integer)
If Me.NewRecord Then
'Daten mit Kennung "Neuer DS" wegschreiben
Else
'Daten "normal" wegschreiben
End If
End Sub


hat leider nicht funktioniert.

Ich hab aber mal den DS in einem anderen Formular offen gelassen. Dorst steht dann schön sauber in jedem Feld #gelöscht.
Schade, dass das nicht in dem Formular steht, in dem gelöscht wird...


Hondo

Mai 06, 2015, 16:32:08 #17 Letzte Bearbeitung: Mai 06, 2015, 16:38:02 von Hondo
Hallo,
ja stimmt, bei AfterDeleteConfirm ist der DS physisch bereits gelöscht.
Aber das Form hat sich noch nicht aktualisiert, sonst könnte in:
Screen.ActiveForm.Controls(m_IDField).Value nicht der korrekte (gelöschte) ID stehen.

Aber zu deinem Formular, da dürfte nicht #gelöscht stehen, das ist das Problem. Ist die Datenbank aufgeteilt, benutzt du ein Serverbackend?

Ich zitiere dazu mal Josef P.:
Zitat#Gelöscht wird normalerweise angezeigt, wenn ein Feld als Primärschlüssel verwendet wird, bei dem Access keine eindeutige Zuordnungen zu den Datensätzen machen kann.
Das könnten einerseits doppelte Werte im Primärschlüssel sein - es kann aber auch Probleme mit den Datentypen geben.
Oder es wurde kein Pirmärschlüssel in der verknüpften Tabelle eingestellt und die Datensatzzuordnung über alle Felder versagt, weil z. B. Float oder andere Zahlentypen nicht gut genug konvertiert werden konnten.


Falls du einen SQL Server als Backend hast, dann in jede Tabelle  Current_Timestamp einfügen.

Andreas

MaggieMay

Hi,

"hat nicht funktioniert" heißt was genau? Bezieht sich die Äußerung auf das Lösch-Protokoll oder auf die Update-Prozedur?
ZitatSchade...
Wieso, was hättest du davon?

Zitatsonst könnte in:
Screen.ActiveForm.Controls(m_IDField).Value nicht der korrekte (gelöschte) ID stehen.
Tut's ja auch gar nicht - zumindest nicht bei meinem Test.
Freundliche Grüße
MaggieMay

Hondo

also ich habe getestet mit Win7 Access 2010 2007er-DBFormat kein Backend, und da funktioniert es. Ich poste mal meine Klasse clsAuditTrail:
Option Explicit

Private WithEvents m_frm As Form
Private WithEvents m_CMDquit As CommandButton

Friend Sub Init(FRM As Form)
    Set m_frm = FRM
    Set m_CMDquit = m_frm.cmdQuit
    m_frm.AfterDelConfirm = "[Event Procedure]"
    m_frm.BeforeUpdate = "[Event Procedure]"
    m_frm.OnClose = "[Event Procedure]"
    m_CMDquit.OnClick = "[Event Procedure]"
    m_frm.Visible = True
End Sub

Private Sub m_frm_Close()
    Set m_CMDquit = Nothing
    Set m_frm = Nothing
End Sub

Private Sub m_CMDquit_Click()
    DoCmd.Quit
End Sub

Private Sub m_frm_AfterDelConfirm(Status As Integer)
    If Status = acDeleteOK Then Call AuditChanges("DELETE")
End Sub

Private Sub m_frm_BeforeUpdate(Cancel As Integer)
    If m_frm.NewRecord Then
        Call AuditChanges("NEW")
    Else
        Call AuditChanges("EDIT")
    End If
End Sub

Private Sub m_frmUfo_AfterDelConfirm(Status As Integer)
    If Status = acDeleteOK Then Call AuditChanges("DELETE")
End Sub

Private Sub m_frmUfo_BeforeUpdate(Cancel As Integer)
    If m_frm.NewRecord Then
        Call AuditChanges("NEW")
    Else
        Call AuditChanges("EDIT")
    End If
End Sub

Private Sub AuditChanges(UserAction As String)
    Dim cnn As ADODB.Connection
    Dim rst As ADODB.Recordset
    Dim CTL As Control
    Dim datTimeCheck As Date
    Dim strUserID As String
   
    Set cnn = CurrentProject.Connection
    Set rst = New ADODB.Recordset
    rst.Open "SELECT * FROM tblAuditTrail", cnn, adOpenDynamic, adLockOptimistic
    datTimeCheck = Now()
    strUserID = Environ("USERNAME")
    Select Case UserAction
        Case "EDIT"
            For Each CTL In Screen.ActiveForm.Controls
                If CTL.Tag = "Audit" Then
                    If Nz(CTL.Value) <> Nz(CTL.OldValue) Then
                        With rst
                            .AddNew
                            ![DateTime] = datTimeCheck
                            ![UserName] = strUserID
                            ![FormName] = Screen.ActiveForm.Name
                            ![action] = UserAction
                            ![RecordID] = Screen.ActiveForm.Controls(getIDField).Value
                            ![FieldName] = CTL.ControlSource
                            ![OldValue] = CTL.OldValue
                            ![NewValue] = CTL.Value
                            .Update
                        End With
                    End If
                End If
            Next CTL
        Case Else
            With rst
                .AddNew
                ![DateTime] = datTimeCheck
                ![UserName] = strUserID
                ![FormName] = Screen.ActiveForm.Name
                ![action] = UserAction
                ![RecordID] = Screen.ActiveForm.Controls(getIDField).Value
                .Update
            End With
    End Select
    rst.Close
    cnn.Close
    Set rst = Nothing
    Set cnn = Nothing
End Sub

Private Function getIDField() As String
    Dim i As Long
    With Screen.ActiveForm.Recordset
        For i = 0 To .Fields.Count - 1
            If .Fields(i).Type = 4 Then
                getIDField = .Fields(i).Name
                Exit For
            End If
        Next i
    End With
End Function


Im Startformular (im Beispiel frmHome) folgender Code:
Option Compare Database
Option Explicit

Private myAudit As clsAuditTrail
Private m_WrapColl As New Collection

Private Sub Form_Load()
    Set myAudit = New clsAuditTrail
End Sub

Private Sub cmdAuditTrail_Click()
    DoCmd.OpenTable "tblAuditTrail"
End Sub

Private Sub cmdCustomers_Click()
    myAudit.Init Form_frmCustomers, "CustomerID"
    m_WrapColl.Add myAudit
End Sub

Private Sub cmdEmployees_Click()
    myAudit.Init Form_frmEmployees, "EmployeeID"
    m_WrapColl.Add myAudit
End Sub

Private Sub cmdQuit_Click()
    DoCmd.Quit
End Sub


Die Formulare frmCustomers und frmEmployees sind Codefrei, die Eigenschaft "Enthält Modul" muss aber auf ja stehen.

Gruß Andreas

Nic-O

Zitat von: Hondo am Mai 06, 2015, 16:32:08
Ist die Datenbank aufgeteilt, benutzt du ein Serverbackend?


Nein. Ich werde ledeglich die Tage die DB in 2 Teile splitten. Tabellen = Backend und der Rest alles ins Frontend. Einen Server wird es jedoch nicht geben.

Ich werde dein Codebeispiel erst morgen ausprobieren können. Vielen Dank schon mal dafür!

Hondo

Hast du das Zitat oben gelesen? hast du die einzelne Punkte geprüft?

Andreas

Nic-O

Mai 07, 2015, 08:33:09 #22 Letzte Bearbeitung: Mai 07, 2015, 09:18:44 von Nic-O
Guten Morgen Zusammen,

Kann es daran liegen, dass Lieferantenprofil und Kundenprofil als Primärschlüssel aus Buchstaben besteht und alle anderen nummerisch sind?

hier mal ein Foto meiner Beziehungen.



Zitat"hat nicht funktioniert" heißt was genau? Bezieht sich die Äußerung auf das Lösch-Protokoll oder auf die Update-Prozedur?


Beides hat keine Veränderungen gebracht. Ich hatte den selben Fehler wie zuvor auch.

Zitat
sonst könnte in:
Screen.ActiveForm.Controls(m_IDField).Value nicht der korrekte (gelöschte) ID stehen.


wo finde ich das?


Ich hatte im 1. Semester mal ganz oberflächlich mit Access zu tun. Deshalb würde ich mich immer noch als absoluten Anfänger bezeichnen :D

MaggieMay

Hi,

myAudit.Init Form_frmCustomers, "CustomerID"

was hast du mit dem zweiten Parameter vor? Die Init-Prozedur erwartet nur das Formular.
Freundliche Grüße
MaggieMay

Hondo

Die Tabellen Lieferantenprofil und Kundenprofil benötigen einen Identifier.
Was machst du wenn es 2 Firmen Maier gibt? Also, füge in beide Tabellen ein Autowert-Feld ein.
In den verknüpften Tabellen benennst du das Feld Lieferantenname in LieferantenID um, und verwendest als Datentyp LongInteger.

Ich denke mal dass due die Profile z.B. per Kombifeld auswählst, trage einfach sorge dass statt des Namens der ID-Wert in den Verbundenen Tabellen steht.
Dann wird sich das Problem erledigt haben.

Gruß Andreas

Hondo

@MaggieMay:
in der Orginalen Version ist das richtig, ich habe das bei meiner Klasse anderst gelöst weil ich es unsinnig fand.

Andreas

MaggieMay

@Hondo:
Dann passen also die von dir in Antwort #19 gezeigten Codes gar nicht zusammen?
Ich wollte das gern mal ausprobieren, was muss ich tun, damit es klappt?
Freundliche Grüße
MaggieMay

Nic-O

Zitat von: Hondo am Mai 07, 2015, 12:40:16
Die Tabellen Lieferantenprofil und Kundenprofil benötigen einen Identifier.
Was machst du wenn es 2 Firmen Maier gibt? Also, füge in beide Tabellen ein Autowert-Feld ein.
In den verknüpften Tabellen benennst du das Feld Lieferantenname in LieferantenID um, und verwendest als Datentyp LongInteger.


Irgendwie stehe ich gerade auf dem Schlauch...

Also ich weiße den 2 Mastertabellen einen Autowert zu. Soll dieser auch zum Primärschlüssel werden?
Bsp.: LieferantenID
Oder kann das Feld XY genannt werden, hauptsache ein Autowert ist vorhanden?

Warum muss in den verknüpften Tabellen der Lieferantenname zu LieferantenID umbenannt werden? Den Wert LongInteger kann ich als Autowert und als Zahl zuweißen. Was soll ich nehmen?

Hondo

Wiso Autowert? du hast doch gesagt die Primärschlüssel sind vom Datentyp Text??
Das ist der Fehler den du korrigieren musst.

Andreas

Hondo

@MaggieMay: Hier ist das von mir überarbeitete Audittrail.

Gruß Andreas