Juni 15, 2021, 21:55:52

Neuigkeiten:

Wenn ihr euch für eine gute Antwort bedanken möchtet, im entsprechenden Posting einfach den Knopf "sag Danke" 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 ⏩

Nic-O

Sind sie auch. Aber ich kann den Wert nicht nachträglich auf Autowert ändern.

Soll ich nun folgendes machen?

KundenID: Autowert (Primärschlüssel)
KundenName: Text (nicht mehr als Primärschlüssel)




Nic-O

Mai 07, 2015, 14:56:33 #32 Letzte Bearbeitung: Mai 07, 2015, 15:19:39 von Nic-O
EDIT: Jetzt geht gar nichts mehr... Datenstätze sind komplett verschwunden und es werden falsche Datensatzeinträge übergeben. Oder gar keine...
Zum Glück gibts ein Backup.



ok :D

ich kann mir richtig vorstellen, wie verzweifelt ihr vor euren Monitoren sitz und denkt: ohh mein gott... haha

Hondo

Hallo,
ja logisch, in den Verbundenen Tabellen stehen ja keine ID-Werte sondern immer noch die Namen, wie soll das gehen?
Du hättest  in den Master-Tabellen das Feld nicht umbenennen sollen sondern ein neues hinzufügen, das hab ich doch mehrfach geschrieben in diesem Thread.

Dann hätte man mit Aktionsabfragen die FremdSchlüssel setzen können.
Wieviele Datensätze hast du denn in den Verbundenen Tabellen so ca.?

Andreas

Nic-O

Hi Andreas,

ich habe ja in den beiden Mastertabellen ein neues Feld mit z.B. KundenID + Autowert erstellt und diesem den Primärschlüssel zugewiesen.

ca 60 - 80 Datensätze

Was Access angeht, bin ich wirklich ein Anfänger

gruß Nico

Hondo

Wenn die Daten keiner Geheimhaltung unterliegen oder keine personenbezogene Daten sind, kannst du mir die Datenbank ja mal schicken, gezippt an "av punkt offenburg ät gmx.de". Ich sieh es mir gerne an und korrigiere es.

Andreas

MaggieMay

@Hondo:
Es ist so wie ich es die ganze Zeit schon gesagt habe, das Protokollieren des gelöschten Datensatzes im AfterDelConfirm-Ereignis funktioniert nicht, weil der DS da schon weg ist. Daran ändert auch deine schöne neue Klasse nichts. ;-)
Freundliche Grüße
MaggieMay

Hondo

Also bei mir funktionierts??
hast du die Option eigentlich eingeschaltet dass DS Änderungen bestätigt werden müssen? Weil ohne das gehts nunmal nicht.
Ah vergaß, in den Formularen sind keine Felder für die CustomerID und EmployeeID, die müsste man als Textfelder in die beiden Forms einfügen, z.B. als unsichtbare felder.

Andreas

MaggieMay

Mai 07, 2015, 16:29:43 #38 Letzte Bearbeitung: Mai 07, 2015, 16:35:36 von MaggieMay
In dem Moment wo die Lösch-Nachfrage gestellt wird, ist der aktuelle Datensatz bereits aus dem Formular verschwunden. Was also soll da noch protokolliert werden können? Gehe ich auf Nein, ist der vorherige DS wie von Zauberhand wieder da. Aber wenn ich die Löschung bestätige, wird die falsche, also die nachfolgende DS-ID protokolliert.

Wieso merkt das denn eigentlich keiner?!  ???

PS:
Wenn bei der Löschung eh nur die DS-ID protokolliert wird, so könnte man sich die ja im BeforeDelConfirm-Ereignis merken und im AfterDelConfirm irgendwie an das AuditTrail weiterreichen...
So ähnlich hatte ich das ja bereits schonmal vorgeschlagen. :-)
Freundliche Grüße
MaggieMay

Hondo

Hallo,
anbei eine Demonstration. In beiden Formularen habe ich kein IDFeld, es wird auf das RecordSource-Feld gezeigt.
http://www.accessblog.de/AuditTrail1.mp4

Andreas

Hondo

Oh je. Da Graut mir was.
Das Formular KundenprofilBearbeiten_F z.B., da ist ist das Kombinationsfeld Kombinationsfeld113 (was für ein besch... Name. Verwende doch eine durchgängige Benamsung wie z.B. comKunden oder cbKunden etc.)
Dieses Combo ist nicht gebunden obwohl beim Speichern das Feld benötigt wird. Gespeichert wird per Makro, ebenfalls ziemlich besch... .

Um deine Datenbank mit den dutzenden von Berichten, Abfragen, Formulare, Makros etc.  zu Überarbeiten würde man sicherlich mehrere Arbeitstage benötigen. Frag doch mal den Franz ob er dafür Zeit und Nerven hat, kostenlos wird es aber nicht sein, aber auch nicht umsonst.

Gruß Andreas

Hondo

Hier noch die Änderungsabfrage um den Fremdschlüssel zu befüllen:
UPDATE [Tabellennamen] AS L INNER JOIN [Profiltabelle] AS P ON P.Kunden_Name = L.Kunden_Name SET L.KUNDENID = P.KUNDENID;

für jede Tabelle musst du Tabellennamen und Profiltabelle einsetzen, und Kunden_Name und KUNDENID bei den Lieferanten anpassen.

Andreas

MaggieMay

Hi,
Zitat von: Hondo am Mai 07, 2015, 18:08:19In beiden Formularen habe ich kein IDFeld, es wird auf das RecordSource-Feld gezeigt.
ich verstehe nicht ganz, was willst du damit sagen?

Das Video beweist, dass die falsche ID gespeichert wird (wenn man zusätzlich in die tblEmployees schaut).
Freundliche Grüße
MaggieMay

Hondo

Mai 07, 2015, 22:28:29 #43 Letzte Bearbeitung: Mai 07, 2015, 23:05:45 von Hondo
Vergiss den Satz.
In der Tat wird der falsche DS geloggt, ist mir gar nicht aufgefallen.

Aber jetzt sehe ich die Intension warum der Entwickler dieses Event genommen hat. Schreibe ich das AuditTrail beim Ereignis "beim löschen", dann ist das AuditTrail bereits gelaufen wenn die Speicher-MSGBox kommt.
Was fehlt ist eine Methode AuditRedoChanges(), die falls man das Löschen abgebrochen hat den falschen Eintrag in der Log entfernt.

So, hier mal die aktuelle Klasse die auch beim Löschen den richtigen ID Loggt, bzw. bei Abbruch den Log entfernt:
Option Explicit

Private WithEvents m_frm As Form
Private WithEvents m_CMDquit As CommandButton
Private m_Identifier As Long

Private Property Get lastIdentifier() As Long
    lastIdentifier = m_Identifier
End Property

Private Property Let lastIdentifier(ByVal lastident As Long)
    m_Identifier = lastident
End Property

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.OnDelete = "[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_Delete(Cancel As Integer)
    Call AuditChanges("DELETE")
End Sub

Private Sub m_frm_AfterDelConfirm(Status As Integer)
    If Status <> acDeleteOK Then Call AuditRedoDelete
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 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
            If UserAction = "DELETE" Then lastIdentifier = ![AuditTrailID]
        End With
    End Select
    rst.Close
    cnn.Close
    Set rst = Nothing
    Set cnn = Nothing
End Sub

Private Sub AuditRedoDelete()
    Dim cnn As ADODB.Connection
    Dim rst As ADODB.Recordset
   
    Set cnn = CurrentProject.Connection
    Set rst = New ADODB.Recordset
    rst.Open "SELECT * FROM tblAuditTrail", cnn, adOpenDynamic, adLockOptimistic
    rst.Find "AuditTrailID = " & lastIdentifier
    If Not rst.EOF Then
        rst.Delete
    End If

    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


Der Code in frmHome (unverändert)
Option Explicit

' ================================================
' Code by Martin Green Email: martin@fontstuff.com
' Visit my Office Tips website @ www.fontstuff.com
' YouTube tutorials www.youtube.com/martingreenvba
' ================================================

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
    m_WrapColl.Add myAudit
End Sub

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

Private Sub cmdQuit_Click()
    DoCmd.Quit
End Sub


Andreas

MaggieMay

ZitatWas fehlt ist eine Methode AuditRedoChanges(), die falls man das Löschen abgebrochen hat den falschen Eintrag in der Log entfernt.

Genau das ist die Lösung, anders geht's nicht. Aber wie ist das denn in an anderer Stelle gelöst, ich meine dort wo die ursprüngliche Vorlage her kommt - wurde die Quelle hier eigentlich schon erwähnt?
Freundliche Grüße
MaggieMay