Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
1348to1352
Aktuelles Verzeichnis
Verzeichnis Index
Übersicht Verzeichnisse
Vorheriger Thread
Rückwärts Blättern
Nächster Thread
Vorwärts blättern
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Inhaltsverzeichnis

Änderungsprotokoll via Excel VBA

Änderungsprotokoll via Excel VBA
25.02.2014 10:09:44
Daniel
Hallo zusammen,
ich bitte um Eure Hilfe bei folgender Problematik. Ich habe mir den u.a. Code aus dem Internet zusammenkopiert. Dieser klappt super bei der Aufzeichnung der neuen Werte/Formeln. Seht Ihr eine Möglichkeit hier auch die alten Werte/Formeln zu protokollieren?
Beste Dank vorab!!!
'Änderungsprotokoll erstellen:
Private Sub Workbook_SheetChange(ByVal Sh As Object, _
ByVal Target As Range)
Dim lngLZ As Long
Dim rngZelle As Range
On Error GoTo Fehler
'Zellwertänderungen aller Tabellen in der Tabelle Änderungsprotokoll eintragen
'Ausnahme: Zelländerung im Änderungsprotokoll
If Sh.CodeName  "Änderungsprotokoll" Then
'damit DIESE Prozedur durch Eingaben im Änderungsprotokoll
'NICHT gestartet wird
Application.EnableEvents = False
With Änderungsprotokoll
'erste freie Zeile im Änderungsprotokoll ermitteln
lngLZ = .Cells(1, 1).End(xlDown).Row + 1
'wenn Änderungsprotokoll voll dann alte Inhalte löschen
If lngLZ > Rows.Count Then
Call NeuesProtokoll
'erste freie Zeile im Änderungsprotokoll ermitteln
lngLZ = .Cells(Rows.Count, 1).End(xlUp).Row + 1
End If
.Cells(lngLZ, 2) = ActiveSheet.Name
.Cells(lngLZ, 3) = ActiveSheet.CodeName
.Cells(lngLZ, 7) = Environ("Username")
.Cells(lngLZ, 8) = Environ("Computername")
.Cells(lngLZ, 9) = ThisWorkbook.FullName
'falls gleichzeitige Eingabe in mehreren Zellen
For Each rngZelle In Target
.Cells(lngLZ, 1) = Now
.Cells(lngLZ, 4) = rngZelle.Address(False, False)
If rngZelle.Value = "" Then
.Cells(lngLZ, 5) = ""
Else
.Cells(lngLZ, 5) = rngZelle.Value
End If
If rngZelle.Value = "" Then
.Cells(lngLZ, 6) = ""
Else
.Cells(lngLZ, 6) = rngZelle.Formula
End If
lngLZ = lngLZ + 1
If lngLZ > Rows.Count Then
Call NeuesProtokoll
'erste freie Zeile im Änderungsprotokoll ermitteln
lngLZ = .Cells(Rows.Count, 1).End(xlUp).Row + 1
End If
Next
End With
Application.EnableEvents = True
End If
Exit Sub
Fehler:
'im Fehlerfall FehlerNr. und Fehlerbeschreibung
'in nächste Zeile vom Änderungsprotokoll eintragen und weitermachen
'erste freie Zeile im Änderungsprotokoll ermitteln
lngLZ = Änderungsprotokoll.Cells(1, 1).End(xlDown).Row + 1
'VOR dem schreiben prüfen
'ob Änderungsprotokoll voll dann alte Inhalte löschen
If lngLZ > Rows.Count Then
Call NeuesProtokoll
'erste freie Zeile im Änderungsprotokoll ermitteln
lngLZ = Änderungsprotokoll.Cells(Rows.Count, 1).End(xlUp).Row + 1
End If
With Änderungsprotokoll
.Cells(lngLZ, 1) = Now
.Cells(lngLZ, 2) = "Err.Number: " & Err.Number
.Cells(lngLZ, 3) = "Err.Description: " & Err.Description
End With
lngLZ = Änderungsprotokoll.Cells(1, 1).End(xlDown).Row + 1
'NACH dem schreiben prüfen
'ob Änderungsprotokoll voll dann alte Inhalte löschen
If lngLZ > Rows.Count Then
Call NeuesProtokoll
'erste freie Zeile im Änderungsprotokoll ermitteln
lngLZ = Änderungsprotokoll.Cells(Rows.Count, 1).End(xlUp).Row + 1
End If
Resume Next
End Sub

Private Sub NeuesProtokoll()
'entfernt alle Protololleinträge im Änderungsprotokoll
'und schafft damit Platz für neue
With Änderungsprotokoll
.Range(.Cells(3, 1), .Cells(Rows.Count, Columns.Count)).Clear
.Cells(3, 1) = Now
.Cells(3, 2) = "ALTES PROTOKOLL GELÖSCHT!!!"
'erste freie Zeile im Änderungsprotokoll ermitteln
'lngLZ = .Cells(Rows.Count, 1).End(xlUp).Row + 1
End With
'MsgBox "neues Protokoll"
End Sub

6
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Änderungsprotokoll via Excel VBA
25.02.2014 13:17:01
fcs
Hallo Daniel,
das ist jetzt etwas komplizierter. Die alten Werte mussen nach Selektion der Zelle(n) in einem Datenarray zwischengespeichert werden.
Deswegen funktioniert die Erfassung der alten Werte auch nicht wenn per Ziehen mit der Maus oder per Drag and Drop Werte in Zellen eingetragen werden.
Außerdem musste ich noch rumtricksen, damit beim Löschen/Einfügen einer kompletten Zeile nicht ca. 16000 Zeilen im Änderungsprotokoll eingetragen werden.
Gruß
Franz
'Code unter DieseArbeitsmappe
Option Explicit
Private arrValue() As Variant, arrFormula() As String, arrAddress() As String
Private Sub Workbook_SheetChange(ByVal Sh As Object, _
ByVal Target As Range)
Dim lngLZ As Long, lngSpalteMax As Long
Dim rngZelle As Range
Dim lngC As Long
On Error GoTo Fehler
'Zellwertänderungen aller Tabellen in der Tabelle Änderungsprotokoll eintragen
'Ausnahme: Zelländerung im Änderungsprotokoll
If Sh.CodeName  "Änderungsprotokoll" Then
'damit DIESE Prozedur durch Eingaben im Änderungsprotokoll
'NICHT gestartet wird
Application.ScreenUpdating = False
Application.EnableEvents = False
With Änderungsprotokoll
'erste freie Zeile im Änderungsprotokoll ermitteln
lngLZ = .Cells(1, 1).End(xlDown).Row + 1
'wenn Änderungsprotokoll voll dann alte Inhalte löschen
If lngLZ > Rows.Count Then
Call NeuesProtokoll
'erste freie Zeile im Änderungsprotokoll ermitteln
lngLZ = .Cells(Rows.Count, 1).End(xlUp).Row + 1
End If
.Cells(lngLZ, 2) = ActiveSheet.Name
.Cells(lngLZ, 3) = ActiveSheet.CodeName
.Cells(lngLZ, 7) = Environ("Username")
.Cells(lngLZ, 8) = Environ("Computername")
.Cells(lngLZ, 9) = ThisWorkbook.FullName
'letzte verwendete Spalte im Blatt
lngSpalteMax = Sh.UsedRange.Column + Sh.UsedRange.Columns.Count - 1
'falls gleichzeitige Eingabe in mehreren Zellen
For Each rngZelle In Target
If Target.Columns.Count = Sh.Columns.Count Then 'ganze Zeile ist geändert/eingefügt  _
worden worden.
If rngZelle.Column > lngSpalteMax Then GoTo nextZelle
End If
.Cells(lngLZ, 1) = Now
.Cells(lngLZ, 4) = rngZelle.Address(False, False)
If rngZelle.Value = "" Then
.Cells(lngLZ, 5) = ""
Else
.Cells(lngLZ, 5) = rngZelle.Value
End If
If rngZelle.Value = "" Then
.Cells(lngLZ, 6) = ""
Else
.Cells(lngLZ, 6) = "'" & rngZelle.FormulaLocal
End If
'gemerkte alte Werte eintragen
For lngC = 1 To UBound(arrValue)
If arrAddress(lngC) = rngZelle.Address(False, False) Then
.Cells(lngLZ, 10) = arrValue(lngC)
.Cells(lngLZ, 11) = arrFormula(lngC)
Exit For
End If
Next
lngLZ = lngLZ + 1
If lngLZ > Rows.Count Then
Call NeuesProtokoll
'erste freie Zeile im Änderungsprotokoll ermitteln
lngLZ = .Cells(Rows.Count, 1).End(xlUp).Row + 1
End If
nextZelle:
Next
End With
Application.EnableEvents = True
Application.ScreenUpdating = True
Erase arrValue, arrFormula, arrAddress
End If
Exit Sub
Fehler:
'im Fehlerfall FehlerNr. und Fehlerbeschreibung
'in nächste Zeile vom Änderungsprotokoll eintragen und weitermachen
'erste freie Zeile im Änderungsprotokoll ermitteln
lngLZ = Änderungsprotokoll.Cells(1, 1).End(xlDown).Row + 1
'VOR dem schreiben prüfen
'ob Änderungsprotokoll voll dann alte Inhalte löschen
If lngLZ > Rows.Count Then
Call NeuesProtokoll
'erste freie Zeile im Änderungsprotokoll ermitteln
lngLZ = Änderungsprotokoll.Cells(Rows.Count, 1).End(xlUp).Row + 1
End If
With Änderungsprotokoll
.Cells(lngLZ, 1) = Now
.Cells(lngLZ, 2) = "Err.Number: " & Err.Number
.Cells(lngLZ, 3) = "Err.Description: " & Err.Description
End With
lngLZ = Änderungsprotokoll.Cells(1, 1).End(xlDown).Row + 1
'NACH dem schreiben prüfen
'ob Änderungsprotokoll voll dann alte Inhalte löschen
If lngLZ > Rows.Count Then
Call NeuesProtokoll
'erste freie Zeile im Änderungsprotokoll ermitteln
lngLZ = Änderungsprotokoll.Cells(Rows.Count, 1).End(xlUp).Row + 1
End If
Resume Next
End Sub
Private Sub NeuesProtokoll()
'entfernt alle Protololleinträge im Änderungsprotokoll
'und schafft damit Platz für neue
With Änderungsprotokoll
.Range(.Cells(3, 1), .Cells(Rows.Count, Columns.Count)).Clear
.Cells(3, 1) = Now
.Cells(3, 2) = "ALTES PROTOKOLL GELÖSCHT!!!"
'erste freie Zeile im Änderungsprotokoll ermitteln
'lngLZ = .Cells(Rows.Count, 1).End(xlUp).Row + 1
End With
'MsgBox "neues Protokoll"
End Sub
Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)
If Sh.CodeName  "Änderungsprotokoll" Then
'damit DIESE Prozedur durch Eingaben im Änderungsprotokoll
'NICHT gestartet wird
On Error GoTo Fehler
Dim lngC As Long, rngZelle As Range, lngSpalteMax As Long
Erase arrValue, arrFormula, arrAddress
'letzte verwendete Spalte im Blatt
lngSpalteMax = Sh.UsedRange.Column + Sh.UsedRange.Columns.Count - 1
lngC = 0
'Inhalte in den selektierten Zellen merken
For Each rngZelle In Target
If rngZelle.Column > lngSpalteMax Then GoTo nextZelle
lngC = lngC + 1
ReDim Preserve arrValue(1 To lngC), arrFormula(1 To lngC), arrAddress(1 To lngC)
With rngZelle
If IsEmpty(rngZelle) Then
arrValue(lngC) = ""
arrFormula(lngC) = ""
Else
arrValue(lngC) = rngZelle.Value
arrFormula(lngC) = "'" & rngZelle.FormulaLocal
End If
arrAddress(lngC) = .Address(False, False)
End With
nextZelle:
Next
End If
Fehler:
With Err
Select Case .Number
Case 0
Case Else
MsgBox "Fehler-Nr.: " & .Number
End Select
End With
End Sub

Anzeige
AW: Änderungsprotokoll via Excel VBA
26.02.2014 13:22:38
Daniel
Hallo Franz,
erstmal besten Dank vorab, dass Du Dich mit meiner Problematik auseinandersetzt.
Wenn ich Deinen Code übernehme, bekomme ich allerdings einen Fehler beim Komplimieren (Variable nicht definiert - markiert wird arrValue).
Die Thematik mit der Aufzeichnung bei löschen von Zeilen und Spalten ist tatsächlich extrem nervig. :)
Wenn eine Spalte gelöscht wird, dann "rödelt" der Rechner ne ganze Weile.
Besten Dank vorab für weitere Unterstützung.
Gruß
Daniel

AW: Änderungsprotokoll via Excel VBA
26.02.2014 16:53:33
fcs
Hallo Daniel,
hast du evtl. die Deklaration der Variablen nicht mit nach "DieseArbeitsmappe" kopiert?
'Code unter DieseArbeitsmappe
Option Explicit
Private arrValue() As Variant, arrFormula() As String, arrAddress() As String

Diese Zeilen müssen als erstes vor allen Prozeduren im Modul stehen.
Die Thematik mit der Aufzeichnung bei löschen von Zeilen und Spalten ist tatsächlich extrem nervig. :)
Wenn eine Spalte gelöscht wird, dann "rödelt" der Rechner ne ganze Weile.

Dieses problem sollte mit meinem Code behoben sein. Es werden nur soviele Zeilen im Änderungsprotokoll eingetragen, wie die Tablle ausgefüllte Spalten hat.
Gruß
Franz

Anzeige
AW: Änderungsprotokoll via Excel VBA
27.02.2014 09:56:56
Daniel
Hallo Franz,
mein Fehler...Sorry! :)...klappt!
Rückfragen habe ich trotzdem noch. Der protokolliert mir bei jedem ersten Eintrag auf einem neuen Tabellenblatt in Spalte 2 im Änderungsprotokoll "Err.Number9" und in Spalte 3 "Err.Description: Index außerhalb des gültigen Bereichs". Ist ein Schönheitsfehler, mit dem ich durchaus leben kann aber vielleicht weißt Du ja aus dem ff wie man das verhindert.
Die Zeilen kann ich Problemlos löschen, wenn ich allerdings eine Spalte löschen will, dann fängt Excel an zu "rödeln" und hört so schnell nicht auf.
Ist hierfür eine Lösung zu finden?
Besten Dank vorab!
Daniel

Anzeige
AW: Änderungsprotokoll via Excel VBA
27.02.2014 10:07:22
Daniel
Hallo nochmal,
der protokolliert den Fehler doch nicht lediglich bei jedem Eintrag auf einem neuen Tabellenblatt sondern leider sehr oft. Ich kann leider nicht sagen, wodurch dieser Fehler ausgelöst wird.
Gruß
Daniel

AW: Änderungsprotokoll via Excel VBA
28.02.2014 00:58:02
fcs
Hallo Daniel,
ich hab die Makros nochmals gründlich überarbeitet.
Das Fehlerproblem schein gelöst. Es passierte wenn der Wert von Zellen mehrfach geändert würde ohne zwischendurch eine andere Zelle zu selektieren.
Das "Rödeln" beim Bearbeiten ganzer Spalten konnte ich abstellen. Statt die über 1 Mio Zellen in einer Spalte abzuarbeiten wird die Zahl der Zellen jetzt begrenzt auf den Bereich der Tabelle der tatsächlich Daten enthält.
Die max. Anzahl Zeilen im Protokoll hab ich jetzt mal auf 20000 begrenzt. So benötigt das Protokoll ca. 1MB Speicher in der Datei. Den Wert kannst du im Code auch anders setzen.
Gruß
Franz
Textdatei mit Code
https://www.herber.de/bbs/user/89469.txt
Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige