Dokumentänderungen auf versteckter Seite....

Informationen und Beispiele zu den hier genannten Dialog-Elementen:
MsgBox
Bild

Betrifft: Dokumentänderungen auf versteckter Seite....
von: Malte Ludwig
Geschrieben am: 22.06.2015 14:06:22

....speichern
Hallo ihr Lieben,
angehängt habe ich eine Beispielmappe.
https://www.herber.de/bbs/user/98372.xlsx
Unter den Spalten "ModulX" seht ihr jeweils 2 einer Person N zugeordnete Zellen. Eine Änderung in der oberen der beiden Zellen führt dazu, dass in der Zelle darunter das Änderungsdatum eingetragen wird.
(Wert dieser Zellen ist auf 0-2 begrenzt)
Ich hätte gerne, dass es ein nicht sichtbares Dokument gibt, auf dem alle diese Änderungen nachvollzogen werden können.
Wenn also Person 1 bei Modul 1 etwas am 21.02.2014 eingetragen bekommen hat, und ich jetzt etwas anderes am 22.06.2015 eintrage, dann sollte auf der nicht sichtbaren Tabelle der Wert der Zelle und das dazugehörige Datum vor Änderung abgespeichert werden.
Wenn eine weitere Änderung erfolgt, sollte diese daneben abgespeichert werden, sodass man auf der nicht sichtbaren Tabelle eine (der Person zugeordnete) Liste bekommt auf der alle Änderungen sichtbar sind.
Ich hoffe das ist so verständlich, wenn nicht, korrigiere ich gerne.
lg
Malte

Bild

Betrifft: AW: Dokumentänderungen auf versteckter Seite....
von: Michael
Geschrieben am: 22.06.2015 17:17:18
Hi Malte,
in Deiner Datei gibt es keine Spalte "ModulX".
Ich würde vorschlagen, Du lädst eine Datei mit aussagefähigeren Werten hoch, und zwar zwei mit *beiden* Blättern, das für die Benutzereingabe und das für das Logbuch.
Letzteres würde ich fast zeilenweise untereinanderschreiben: Person(Name) hat am (Datum) Zelle(Spalte+Zeile) von(alter Wert) nach (neuer Wert) geändert, alle diese Angaben in je einer Spalte, dann kann man das sortieren, wie man's gerade braucht.
Soll sich die Tabelle die Namen aus dem Environment holen?
Schöne Grüße,
Michael

Bild

Betrifft: AW: Dokumentänderungen auf versteckter Seite....
von: Malte Ludwig
Geschrieben am: 22.06.2015 17:17:34
Habe inzwischen diesen Code gefunden:


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 Tabelle 'wksDoku' eintragen
'Ausnahme: Zelländerung in wksDoku
If Sh.CodeName <> "wksDoku" Then
  'damit DIESE Prozedur durch Eingaben in wksDoku
  'NICHT gestartet wird
  Application.EnableEvents = False
  With wksDoku
    'erste freie Zeile in wksDoku ermitteln
    lngLZ = .Cells(1, 1).End(xlDown).Row + 1
    'wenn wksDoku voll dann alte Inhalte löschen
    If lngLZ > Rows.Count Then
      Call NeuesProtokoll
      'erste freie Zeile in wksDoku ermitteln
      lngLZ = .Cells(Rows.Count, 1).End(xlUp).Row + 1
    End If
    .Cells(lngLZ, 2) = ActiveSheet.Name
    .Cells(lngLZ, 3) = ActiveSheet.CodeName
    .Cells(lngLZ, 6) = Environ("Username")
    .Cells(lngLZ, 7) = Environ("Computername")
    .Cells(lngLZ, 8) = 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) = "< Inhalt entfernt >"
      Else
        .Cells(lngLZ, 5) = rngZelle.Value
      End If
      lngLZ = lngLZ + 1
      If lngLZ > Rows.Count Then
        Call NeuesProtokoll
        'erste freie Zeile in wksDoku 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 von wksDoku eintragen und weitermachen
  'erste freie Zeile in wksDoku ermitteln
  lngLZ = wksDoku.Cells(1, 1).End(xlDown).Row + 1
  'VOR dem schreiben prüfen
  'ob wksDoku voll dann alte Inhalte löschen
  If lngLZ > Rows.Count Then
    Call NeuesProtokoll
    'erste freie Zeile in wksDoku ermitteln
    lngLZ = wksDoku.Cells(Rows.Count, 1).End(xlUp).Row + 1
  End If
  With wksDoku
    .Cells(lngLZ, 1) = Now
    .Cells(lngLZ, 2) = "Err.Number: " & Err.Number
    .Cells(lngLZ, 3) = "Err.Description: " & Err.Description
  End With
  lngLZ = wksDoku.Cells(1, 1).End(xlDown).Row + 1
  'NACH dem schreiben prüfen
  'ob wksDoku voll dann alte Inhalte löschen
  If lngLZ > Rows.Count Then
    Call NeuesProtokoll
    'erste freie Zeile in wksDoku ermitteln
    lngLZ = wksDoku.Cells(Rows.Count, 1).End(xlUp).Row + 1
  End If
  Resume Next
End Sub
Private Sub NeuesProtokoll()
'entfernt alle Protololleinträge in wksDoku
'und schafft damit Platz für neue
With wksDoku
  .Range(.Cells(3, 1), .Cells(Rows.Count, Columns.Count)).Clear
  .Cells(3, 1) = Now
  .Cells(3, 2) = "ALTES PROTOKOLL GELÖSCHT!!!"
  'erste freie Zeile in wksDoku ermitteln
  'lngLZ = .Cells(Rows.Count, 1).End(xlUp).Row + 1
End With
'MsgBox "neues Protokoll"
End Sub
Und auch angewandt.
Das einzige was jetzt noch fehlt ist, dass mir zu den geänderten Zellen die dazugehörige Person in den gleichen Zeilen ausgespuckt wird.
Könnte zum Beispiel statt des Feldes "ändernder Benutzer" eingefügt werden, allerdings weiß ich nicht wie ich das anpacken soll.
Vielen Dank im Voraus!
Malte

Bild

Betrifft: AW: Dokumentänderungen auf versteckter Seite....
von: Michael
Geschrieben am: 22.06.2015 17:50:44
Hi Malte,
wenn das denn funzt... (bei mir zickt's irgendwie)
Die Zeile, in der der Name steht ist (ohne den Fall mehrfach markierter/geänderter Zellen zu berücksichtigen) in der gleichen Zeile wie die geänderte Zelle, nämlich die Target.Row
Hole Dir zunächst den Namen:

Private Sub Workbook_SheetChange(ByVal Sh As Object, _
                                 ByVal Target As Range)
Dim lngLZ As Long
Dim rngZelle As Range
Dim B_Name as String
B_Name = Range("B" & Target.Row).value
On Error GoTo Fehler
'Zellwertänderungen aller Tabellen in Tabelle 'wksDoku' eintragen
'Ausnahme: Zelländerung in wksDoku
Nach .Cells(lngLZ, 8) = ThisWorkbook.FullName könntest Du also einfügen:
.Cells(lngLZ, 9).value = B_Name
Dann sollte es passen.
Dann würde es zumindest passen, wenn Du keine verbundenen Zellen für die Namen verwenden würdest.
Hier gibt die Beispieldatei nicht genug Infos her: was ist, wenn außerhalb der Zeilen mit den Namen was geändert wird? Wenn "überall" Namen stehen, kannst Du Dir mit einer Modula2-Berechnung helfen, auf deutsch: wenn target.row ungerade, dann nimm target.row-1.
Schöne Grüße,
Michael

Bild

Betrifft: AW: Dokumentänderungen auf versteckter Seite....
von: Malte Ludwig
Geschrieben am: 22.06.2015 19:18:31
Hi Michael,
mir ist an den Code folgendes "Problem" aufgefallen:
Ich habe ein paar Tabellen, die nicht mit in die Doku aufgenommen werden sollen,
leider sind diese Tabellen variabel und werden mittels VBA erstellt.
Ich habe versucht bei folgender Zeile einfach die erste Tabelle einzufügen und dann True und False zu Switchen, aber so einfach scheint das dann doch nicht zu sein...
If Sh.CodeName <> "wksDoku" Then
Wie bekomme ich es hin, statt nur "wksDoku" auszuschließen nur (von mir im Code deklarierte) Tabellen einzuschließen?
Danke im Voraus,
lg
Malte

Bild

Betrifft: Blacklist oder whitelist
von: Michael
Geschrieben am: 22.06.2015 21:39:43
Hi Malte,
ist anhand des Namens ersichtlich, wie sie heißen ("NichtBerücksichtigen_1, 2 usw.) oder sind die Namen völlig unterschiedlich?
Hast Du dann irgendwo eine Tabelle (einen Bereich), in der die entsprechenden Namen stehen, und wenn ja, wo?
Auf alle Fälle brauchst Du entweder eine Liste von Tabellen, die zu berücksichtigen sind (whitelist) oder eine von denen, die *nicht* zu berücksichtigen sind (blacklist). Die kann auf einem Tabellenblatt stehen, das man zum Vergleich heranziehen kann, die kann auch in globalen Variablen (evtl. einem Array) gespeichert sein.
So oder so DIMst Du erst mal ne Variable protokoll und machst dann ne Schleife über die Blattnamen.
Das als ausführbarer Code zum Testen in einer "leeren" Datei (mit Blattnamen in A1 bis A5):

Sub protoTesten()
Dim protokoll As Boolean
Dim p&
Dim sh As Worksheet ' hast Du schon
Set sh = ActiveSheet ' brauchst Du nicht
'whitelist
protokoll = False
For p = 1 To 5
  If sh.CodeName = Range("A" & p).Value Then
    protokoll = True
    Exit For
  End If
Next
'und dann statt if sh.codename then... nur:
If protokoll Then
MsgBox "Protokoll wird erstellt"
End If
'oder blacklist:
protokoll = True
For p = 1 To 5
  If sh.CodeName = Range("A" & p).Value Then
    protokoll = False
    Exit For
  End If
Next
If protokoll Then
MsgBox "Protokoll wird erstellt"
End If
End Sub
Die Else zu den IFs kannste ja noch einfügen, dann siehst Du mehr.
Schöne Grüße,
Michael

Bild

Betrifft: AW: Blacklist oder whitelist
von: Malte Ludwig
Geschrieben am: 23.06.2015 08:00:15
Die Listennamen die nicht berücksichtigt werden sollen werden mit einer Combobox aus der Tabelle1 ausgelesen und dann erstellt wenn man copy triggert.
Das einfachste wäre also tatsächlich nur Tabelle1 als whitelist einzutragen und alle anderen Tabellen blacklisted zu lassen, sollte eine zweite Tabelle zum auslesen hinzukommen, kann man die ja einfach bei whitelist anfügen. Ich werde mal ein bisschen mit dem Code rumspielen und melde mich bei Fragen wieder!
Vielen herzlichen Dank für deine großartige Hilfe!
Malte

Bild

Betrifft: AW: Blacklist oder whitelist
von: Malte Ludwig
Geschrieben am: 23.06.2015 08:45:49
Ich werde dir mal meine Beispielmappe anhängen, die ist von der Programmierung genau so wie das tatsächliche Arbeitsdokument.
In der Beispielmappe werden aus Tabelle1 die Namen (PersonN) ausgelesen, und in eine versteckte Tabelle2 kopiert, die dann ihrerseits Kopiert wird (vielen Dank an dieser Stelle nochmal an fcs für die Combobox und den Code)
Im Prinzip ist also die einzige Tabelle, die im Moment berücksichtigt werden soll Tabelle1.
Hier die Beispielmappe
https://www.herber.de/bbs/user/98399.xlsm
Vielen Dank im Voraus!
Malte

Bild

Betrifft: AW: Blacklist oder whitelist
von: Michael
Geschrieben am: 23.06.2015 15:22:07
Hi Malte,
ich habe grad keine Zeit, mir die Tabelle näher anzusehen, und es sollte auch gar nicht nötig sein.
Der Knackpunkt ist doch die Codezeile (siehe Dein Code ganz oben):

If Sh.CodeName <> "wksDoku" Then

Das entspricht im Prinzip einer blacklist: [alle außer "wksDoku"].
Zwischenzeitlich möchtest Du [keinen außer "Tabelle1"].
Dann schreibst Du einfach:
If Sh.CodeName = "Tabelle1" Then

Solange es sich nur um wenige Blätter handelt, kannst Du Dir die ganzen Listen schenken und mit UND oder ODER arbeiten, z.B.:
If Sh.CodeName = "Tabelle1" Or Sh.CodeName = "Tabelle27" Then
dabei werden nur die Blätter Tabelle1 und Tabelle27 berücksichtigt.
Ich mag mich nicht weiter drum kümmern, derweil Du zwischenzeitlich zwei neue Fragen zum gleichen Themenkomplex aufgemacht hast.
Schöne Grüße,
Michael

Bild

Betrifft: AW: Blacklist oder whitelist
von: Malte Ludwig
Geschrieben am: 23.06.2015 15:45:11
Danke vielmals für die Hilfe Michael!
Habs angewandt und es funktioniert super.
Die beiden neuen Themen habe ich aufgemacht, weil im den Anweisungen stand, das zu komplexe Themen die Suche nach Lösungen im Archiv behindern.
Habe jetzt die verschiedenen Steps gesplittet.
Wenn das falsch war, dann entschuldige ich mich.
LG
Malte

Bild

Betrifft: erledigt
von: Michael
Geschrieben am: 23.06.2015 18:48:27
Hi Malte,
nicht nötig, weil, naja, ob's "falsch" war, weiß ich nicht, es hat mich halt verwirrt.
Aber wenn es tut, ist ja alles gut.
Danke für die Rückmeldung und schöne Grüße,
Michael

 Bild

Beiträge aus den Excel-Beispielen zum Thema "SAP Anmeldung via VBA nicht mehr möglich"