Eine Kopie erstellen wenn die Datei gespeichert wird

Hallo zusammen,

ich habe folgendes Problem:

Eine Excel-Datei soll beim Speichern/Speichern
unter (also nur bei Veränderungen) automatisch
in einem Archivordner eine Kopie angelegen.

Original: C:\Excel\Dateiname.xlsm

Kopie: D:\Archiv\Dateiname_Datum_Zeit.xlsm

Die Kopien im Archivordner sollen
jedoch nicht überschrieben werden. Aus diesem Grund das Zeitformat im Namen
mit. Platz für viele Kopien ist genug.

Kann mir jemand bei der
Lösungsfindung helfen?

Vielen Dank.

Hallo.

Wahrscheinlich könnte man hier was mit Add-Ins basteln und wäre dann von der eigentlichen Datei unabhängig, aber wenn die Datei sowieso Makros enthält, geht auch sowas:

Dim fso As Object

Private Sub Workbook_AfterSave(ByVal Success As Boolean)
    Set fso = VBA.CreateObject("Scripting.FileSystemObject")
    datum = Date
    zeit = Time
    stunden = Left$(zeit, 2)
    minuten = Mid$(zeit, 4, 2)
    sekunden = Right$(zeit, 2)
    zt = stunden & minuten & sekunden
    file_name = ActiveWorkbook.FullName
    
    backup_file = "C:\temp\" & Date & "_" & stunden & minuten & sekunden & "_" & ActiveWorkbook.name
    Call fso.CopyFile(file_name, backup_file)
End Sub

Das Aufdröseln der Zeit ist notwendig, weil Dateinamen keine Doppelpunkte enthalten dürfen.
Beim Datum müsste man je nach Format evtl. auch sowas machen.

Gruß,

Kannitverstan

Wenn der Dateiname vorn stehen soll, geht es am einfachsten so:

base_name = fso.GetBaseName(ActiveWorkbook.name) ' diese zeile ist neu ggü. obigem Beispiel
backup_file = "C:\temp\" & base_name & "_" & Date & "_" & stunden & minuten & sekunden & ".xlsm" ' diese zeile ist entsprechend geändert

Die Erweiterung könnte man auch irgendwie auslesen und statt „.xlsm“ dynamisch machen, aber dazu bin ich jetzt zu faul :smile:

Gruß,

Kannitverstan

Hallo und DANKE,
dass sieht nun unwahrscheinlich Klasse für mich aus, da ich kein Vba kann. Aus diesem Grund hätte ich noch ein paar „blöde“ Fragen.
Wo muss nun der Speicherort eingetragen werden??? Ich denke mir im letzten Absatz. (Bite nicht lachen)

backup_file = "C:\temp" & Date & „" & stunden & minuten & sekunden & "“ & ActiveWorkbook.name
Call fso.CopyFile(file_name, backup_file)

Die Kopie sollte bei mir unter: N:\04 BSM_Admin\Kopien der BSM abgelegt werden.
Müste es dann so heißen:

backup_file = "C:\temp" & Date & „" & stunden & minuten & sekunden & "“ & ActiveWorkbook.name
Call fso.CopyFile(N:\04 BSM_Admin\Kopien der BSM)

Mit oder ohne Klammern? Oder wo anders?

Danke im Voraus für Zeit und Nerven

Hallo.

Sorry, hätte ich auch gleich dazu schreiben können:
Ersetze C:\temp\ einfach durch deinen Pfad (also „N:\04 BSM_Admin\Kopien der BSM“).
Der CopyFile-Aufruf bleibt gleich! Der verwendet ja nur die Variablen file_name (= Originalfile inkl. Pfad) und backup_file (= Sicherheitskopie)

Noch was: Das Makro muß im VBA-Editor unter „DieseArbeitsmappe“ stehen, also Doppelklick auf „DieseArbeitsmappe“ im Projektexplorer und den Code dann in dieses Fenster einfügen:

Gruß,

Kannitverstan

Nun habe ich es getan aber nichts passierte.
Ich habe unter „DieseArbeitsmappe“ die Zeile wie folgt ergänzt:

backup_file = „N:\04 BSM_Admin\Kopien der BSM“ & Date & „" & stunden & minuten & sekunden & "“ & ActiveWorkbook.Name

und den Rest mit der Zeitangabe gelassen.

Irgendwas habe ich falsch gemacht :weary:

Warum hast Du Dir „zt“ gebaut, und verlängerst dann den Namen mit stunden & minuten & sekunden ? :wink:

Gute Frage :wink:
zt hatte ich für Debugging-Zwecke gebaut, weil - was ich jetzt nicht mehr reproduzieren kann - falsche Werte rauskamen, als ich zeit mit stunden & minuten & sekunden überschrieben hatte.
Die Zeile braucht man entweder nicht, oder könnte sie gleich zum gewünschten String zusammenbauen und selbstverständlich in der Zuweisung backup_file = ... verwenden.

Gruß,

Kannitverstan

Hallo.

Hmmm… Excel zu alt? :wink: AfterSave wird offiziell erst seit Excel 2013 unterstützt. Plan B wäre folgender:

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
  Cancel = True
  Application.EnableEvents = False
  If SaveAsUI = True Then
    cFile = Application.GetSaveAsFilename(ActiveWorkbook.Name) & "xlsm" 
    If cFile <> False Then
       ActiveWorkbook.SaveAs Filename:=cFile
    End If
  Else
    ActiveWorkbook.Save
  End If

  ActiveWorkbook.Save
  Application.EnableEvents = True

  Set fso = VBA.CreateObject("Scripting.FileSystemObject")
  datum = Date
  zeit = Time
  stunden = Left$(zeit, 2)
  minuten = Mid$(zeit, 4, 2)
  sekunden = Right$(zeit, 2)
  zeit = stunden & minuten & sekunden
  file_name = ActiveWorkbook.FullName
  base_name = fso.GetBaseName(ActiveWorkbook.Name)
  backup_file = "C:\temp\" & base_name & "_" & Date & "_" & zeit & ".xlsm"
  Call fso.CopyFile(file_name, backup_file)
End Sub

Damit wird die Datei im Makro gespeichert und anschließend kopiert.
Das mit der Dateiendung beim Speichern ist etwas unsauber, funktioniert aber.
Application.EnableEvents = False vor dem Speichern ist wichtig, damit das Makro nicht endlos aufgerufen wird.
Application.EnableEvents = True nach dem Speichern ist genauso wichtig, damit das Makro auch mehrmals funktioniert.

Gruß,

Kannitverstan

1 Like

Gesagt - getan
Wieder ein Fehler

Hallo Kannitverstan,
ich habe es mit einer leeren Tabelle probiert und es klappt einwandfrei.

DANKE DIR.

Ich habe nun nachgelesen und herausbekommen warum der Fehler in meiner Datei kommt.

Ich habe den Begriff: beforesave
nun zweimal im Makro stehen.

Das andere Makro ist:

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Call prcStartTimer
End Sub

Kann man das auch anders schreiben wenn der Befehl nur einmal verwendet werden kann?
Ich weiß nicht mal was das Makro bewirkt? Oder kann ich den weglassen?

Danke noch einmal für weitere Hilfe.

Hallo.

Freut mich, dass es jetzt funktioniert :smile:
Zum anderen Makro:
Du kannst nicht zwei Makros gleichen Namens haben.
Aber du kannst den Aufruf von prcStartTimer (also die Zeile Call prcStartTimer) in das zweite Makro kopieren und das erste dann löschen.
Die Zeile ruft nur ein Unterprogramm (d.h. eine Sub namens prcStartTimer) auf, die anderswo definiert ist.
Du solltest den Aufruf an den Anfang des Makros kopieren. Falls - wovon ich mal ausgehe - diese Sub noch etwas an der Datei verändert, werden diese Änderungen mit abgespeichert und auch mit ins Backup übernommen.

Gruß

Kannitverstan

1 Like

PS: Bitte in Zukunft direkt die Kommentare bzw. Antworten kommentieren, auf die du dich beziehst (und nicht deine eigenen). Sonst ist es - wie hier - Glückssache, ob der/diejenige überhaupt mitbekommt, dass da noch was offen ist.
Aber bei der unübersichtlichen Gestaltung dieses Forums kann man schon mal durcheinanderkommen :wink:

1 Like

Danke für den Tipp und ein großes Dankeschön für die Unterstützung. Habe es hinbekommen.