Reputation: 9096
I have placed the following macro in my c:\program files (x86)\microsoft office\office11\xlstart\personal.xls
:
Option Explicit
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
' http://stackoverflow.com/questions/15267796/macro-to-make-a-backup-while-saving-a-file
' http://office.microsoft.com/en-us/excel-help/deploy-your-excel-macros-from-a-central-file-HA001087296.aspx
Dim BackupName As String
MsgBox "ActiveWorkbook.Name: " & ActiveWorkbook.Name 'For debugging
BackupName = ActiveWorkbook.Name
BackupName = Mid(BackupName, 1, InStrRev(BackupName, ".")) & "bak"
'For testing BackupName = "D:\temp\" & BackupName 'For testing
BackupName = ActiveWorkbook.Path & "\" & BackupName
ActiveWorkbook.SaveCopyAs BackupName
End Sub
From what I understand (e.g. second link mentioned above) this is supposed to run every time I save any worksheet, but this is not happening.
Only if I (edit and) save personal.xls do I see the MsgBox
and the personal.bak
file appearing.
What am I forgetting?
(Running W7 64-bits and Office 2003).
Upvotes: 0
Views: 2243
Reputation: 53623
I mentioned in the comments that what you have is a workbook-level event procedure. That is slightly different from a "macro" (your public macros would be available to any open workbook, but the worksheet or workbook-level events would not respond to other workbook events). What you need is to trap Application-level events.
I have not fully tested this but i did some simple test and it seems to work, (I am porting over some code that I use in PowerPoint to trap Application-level events). Give this a shot and let's see if it works for you.
First create an class object to handle the events.
In your Personal.XLS, add a Class module and name it cEventClass
(you can name it wahtever you want, but it will be easier to follow my example if you use the same naming conventions that I'm using).
In this class module, put the following code:
Option Explicit
Public WithEvents XLEvent As Application
Private Sub XLEvent_WorkbookBeforeSave(ByVal Wb As Workbook, ByVal SaveAsUI As Boolean, Cancel As Boolean)
'This is just my test, you can place your own code (modified as needed) here:
MsgBox "BeforeSave " & Wb.Name
End Sub
We've now established the means to trap Application-level events, and we can see these available options in the dropdowns in the VBE:
Next, instantiate an instance of this class.
Probably the best place to do this will be during the Personal.XLS Workbook_Open
procedure. You could put it in another sub and call it on-demand, etc., but if you put it in this event handler, I think it should work.
Add a normal code module (this can't go in an object or class module), do this:
Public cXLEvents As New cEventClass
Add some code to automatically instantiate the class
in the Workbook_Open procedure of your Personal.XLS, do this:
Option Explicit
Private Sub Workbook_Open()
'Add this line in addition to any other code you might already have in this procedure
Set cXLEvents.XLEvent = Application
End Sub
Now, sit back and let the handler do its job!
Now, when you go to save any workbook (not limited to the Personal.XLS) the Application event handler should pick it up, as verified with my example:
NOTE I think this will fail to work if you are debugging and "End" run-time; that will kill the cXLEvents
and so the event handler will essentially be turned "off", so you would need to re-instantiate it.
Upvotes: 1