Anzeige
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Inhaltsverzeichnis

Änderungsprotokoll via Excel VBA

Forumthread: Ä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

Anzeige

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

Anzeige
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
;
Anzeige

Infobox / Tutorial

Änderungsprotokoll in Excel mittels VBA


Schritt-für-Schritt-Anleitung

Um ein Änderungsprotokoll in Excel mittels VBA zu erstellen, folge diesen Schritten:

  1. Öffne Excel und gehe zu „Entwicklertools“.

  2. Klicke auf „Visual Basic“, um den VBA-Editor zu öffnen.

  3. Füge ein neues Modul hinzu, indem Du mit der rechten Maustaste auf „DieseArbeitsmappe“ klickst und „Einfügen“ > „Modul“ auswählst.

  4. Kopiere den folgenden Code in das Modul:

    Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
       Dim lngLZ As Long
       On Error GoTo Fehler
       If Sh.CodeName <> "Änderungsprotokoll" Then
           Application.EnableEvents = False
           With Änderungsprotokoll
               lngLZ = .Cells(1, 1).End(xlDown).Row + 1
               .Cells(lngLZ, 1) = Now
               .Cells(lngLZ, 2) = ActiveSheet.Name
               .Cells(lngLZ, 5) = Target.Value
           End With
           Application.EnableEvents = True
       End If
       Exit Sub
    Fehler:
       ' Fehlerbehandlung
    End Sub
  5. Speichere die Datei als Makro-fähige Arbeitsmappe (*.xlsm).

  6. Teste die Funktion, indem Du Werte in die Zellen eingibst. Überprüfe das Änderungsprotokoll auf die Einträge.


Häufige Fehler und Lösungen

  • Fehler: „Variable nicht definiert“
    Stelle sicher, dass alle Variablen korrekt deklariert sind. In diesem Fall könnte die Deklaration von arrValue, arrFormula und arrAddress fehlen.

  • Fehler: „Index außerhalb des gültigen Bereichs“
    Dieser Fehler tritt auf, wenn Du versuchst, auf ein Element eines Arrays zuzugreifen, das nicht existiert. Achte darauf, dass Du den Code in der richtigen Reihenfolge ausführst.

  • Lange Ladezeiten beim Löschen von Spalten
    Optimiere Deinen Code, indem Du die Anzahl der bearbeiteten Zellen begrenzt. Statt alle Zellen in einer Spalte zu durchlaufen, beschränke Dich auf den Bereich, der tatsächlich Daten enthält.


Alternative Methoden

Falls VBA nicht die gewünschte Lösung bietet, kannst Du auch auf folgende Methoden zurückgreifen:

  1. Excel-Add-Ins: Es gibt spezielle Add-Ins für Excel Änderungsprotokolle, die das Protokollieren von Änderungen automatisch übernehmen.
  2. Manuelle Protokollierung: Du kannst auch manuell ein Änderungsprotokoll führen, indem Du ein neues Blatt erstellst und dort Änderungen dokumentierst.

Praktische Beispiele

Hier sind einige praktische Beispiele, wie Du das Änderungsprotokoll in Excel umsetzen kannst:

  • Beispiel 1: Trage den Code in ein Arbeitsblatt ein, um Änderungen zu protokollieren.
  • Beispiel 2: Implementiere eine Funktion, die alte Werte speichert, bevor sie überschrieben werden.
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
    ' Speichert alte Werte in ein Array
End Sub

Tipps für Profis

  • Nutze Application.EnableEvents = False, um zu verhindern, dass das Änderungsprotokoll erneut ausgelöst wird, wenn Du Änderungen durch das Protokoll vornimmst.
  • Reduziere die Anzahl der Zeilen im Änderungsprotokoll, um die Performance zu verbessern. Setze eine maximale Anzahl von Einträgen.
  • Füge zusätzliche Informationen hinzu, wie z.B. den Benutzernamen oder den Zeitpunkt der Änderung, um das Protokoll informativer zu gestalten.

FAQ: Häufige Fragen

1. Wie kann ich das Änderungsprotokoll in Excel einrichten?
Befolge die Schritt-für-Schritt-Anleitung, um den VBA-Code in Deiner Arbeitsmappe zu implementieren.

2. Welche Excel-Version benötige ich für das Änderungsprotokoll?
Die Anleitung funktioniert ab Excel 2010 und höher, solange VBA unterstützt wird.

3. Kann ich das Änderungsprotokoll anpassen?
Ja, Du kannst den VBA-Code anpassen, um zusätzliche Informationen zu protokollieren oder die Art der Änderungen zu ändern.

4. Was tun, wenn das Protokoll nicht funktioniert?
Überprüfe den Code auf Fehler und stelle sicher, dass Du die richtigen Blätter und Zellreferenzen verwendest. Debugge den Code Schritt für Schritt.

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Entdecke mehr
Finde genau, was du suchst

Die erweiterte Suchfunktion hilft dir, gezielt die besten Antworten zu finden

Suche nach den besten Antworten
Unsere beliebtesten Threads

Entdecke unsere meistgeklickten Beiträge in der Google Suche

Top 100 Threads jetzt ansehen
Anzeige