I have an add-in with an application object. The object is declared WithEvents. This enables me to flush some data points to a central database every time the user saves the file. This works most of the time. However, there is one user who quits the Excel application, which calls up the Save dialog box. It appears that quitting Excel with an unsaved file means that the WorkbookBeforeSave event does not fire.
Just to emphasize, I have confirmed that the event does fire when the user hits CTRL-S, or presses the save button. I have also confirmed that the event does NOT fire if I quit the application.
I can think of a few workarounds (automatically save every 10 seconds, for example), but I'm not crazy about that. Can anyone confirm this behavior and/or does anyone have a remedy?
Option Explicit
Private WithEvents mapp As Excel.Application
Private Sub mapp_WorkbookBeforeSave(ByVal Wb As Workbook, ByVal SaveAsUI As Boolean, Cancel As Boolean)
' Sanity preservation device
Msgbox "WorkbookBeforeSave event fired."
SaveSomeData Wb
End Sub
You could use the Workbook_BeforeClose routine and the Workbook Object's Saved property.
Private Sub Workbook_BeforeClose(Cancel As Boolean)
If ThisWorkbook.Saved = False Then
'Call save function
End If
End Sub
Have you considered using before BeforeClose? This might be a better alternative.
Related
As I very often have to problem, that the tick vanishes in the settings: Calculate before save. (I don't know the exact term as my office version is in German).
That's why I tried to use VBA to solve the problem. I used the following code in my Excel file:
Option Explicit
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, _
Cancel As Boolean)
If Application.CalculateBeforeSave = False Then
If MsgBox("Caution! Should >calculatebeforesave< be activated?", vbYesNo) = vbYes Then
Application.CalculateBeforeSave = True
Else
End If
Else
End If
End Sub
I put this into "Thisworkbook". But I would like this code to be ran in every workbook I work with (at least all these which allow for macros).
My suggestion was to write ActiveWorkbook_BeforeSave... instead of Workbook_BeforeSave and then put the code in a module in the PERSONAL Macro file. But this doesn't work.
I think you need to use the Excel Applications events rather than workbook events to achieve this, such as in this example
In your PERSONAL workbook right click and insert a a Class Module (Class 1)
Add something similar to below to Class 1:
Public WithEvents appevent As Application
Private Sub appevent_WorkbookBeforeClose(ByVal Wb As Workbook, Cancel As Boolean)
'Add what you would like to happen before a workbook closes
End Sub
Next open ThisWorksheet and add code along these lines (I think the PERSONAL workbook opens automatically when Excel starts):
Dim myobject As New Class1
Private Sub Workbook_Open()
Set myobject = Application
End Sub
I have a BeforeClose event in a workbook, however if the user closes the workbook when it is not the active workbook, e.g. from the taskbar, the script executes on the wrong workbook.
Is there a way to tell which workbook triggered the event and reference that workbook rather than ActiveWorkbook?
Private Sub Workbook_BeforeClose(Cancel As Boolean)
' Replaces default Save message box with custom one
' that includes request stats, warnings, and errors.
If Not ActiveWorkbook.Saved Then
UF_Stats.Show
If Not GlobalVariables.bAllowClose Then Cancel = True
End If
End Sub
Use ThisWorkbook instead of ActiveWorkbook – Vincent G
Q: What is recommended way of notifing user about loss of functionality unless User change macro security settings?
What I do now:
I display warning on the first sheet user see after opening Workbook, with explanation why things WONT work unless proper settings are set.
And I hide it on start up. (Which wont happen unless settings are OK)
But its not perfect solution:
That message is just one time. (While user could send that sheet to somebody else with different settings...)
Hiding and showing those few rows is treaded by Excel as changing document. (So just opening and closing excel will generate Save changed warning!)
Ok, here is best answer I could think off
(And big thx to #brettdj for suggestion!)
Sub HideMacroSecWarning()
Status = ThisWorkbook.Saved
Help.Range("Warning").rows.hidden = True
ThisWorkbook.Saved = Status
End Sub
Sub ShowMacroSecWarning()
Status = ThisWorkbook.Saved
Help.Range("Warning").rows.hidden = False
ThisWorkbook.Saved = Status
End Sub
Those are for showing and hiding macros. Saved state is preserved so only user actions can trigger "unsaved changes" dialogbox.
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Call ShowMacroSecWarning
End Sub
Private Sub Workbook_Open()
Call HideMacroSecWarning
End Sub
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Call ShowMacroSecWarning
End Sub
Private Sub Workbook_AfterSave(ByVal Success As Boolean)
Call HideMacroSecWarning
End Sub
Those assure that no matter the state of user settings warning will ALWAYS be displayed in SAVED FILE. (So even if for user Exel do not display that warning, somebody else who will open it on different machine will see that warning.)
I have an excel sheet which is protected, since the sheet is protected I don't want the user to save it, and I don't want the save the sheet prompt to appear when someone closes the workbook. Till now I have been using this:
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Cancel = True
Application.DisplayAlerts = False
End Sub
Using this code, save feature is disabled but the prompt is still appearing
Similar problem: Since the workbook is protected whenever someone tries to change the cell content it displays an alert, I want to disable that prompt message as well.
Can someone help me to fix this
L42 has already answered part of your question.
I want to disable that prompt message as well.
Do this. While protecting the sheet, unckeck the option Select Locked Cells. Now that will take care of the keyboard input while the sheet is locked and protected.
As for mouse inputs i.e the prompt showing up when you double click on the cell, use this :)
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Cancel = True
End Sub
Using VBA in Excel 2003, I'm trying to cancel an Application.OnTime event using the following code:
Application.OnTime EarliestTime:=varNextRunTime, Procedure:="SomeMethod", Schedule:=False
where varNextRunTime is a global variable containing the next time it is due to run. This code runs in the Workbook_BeforeClose event handler so is always run when the workbook is closed, which is my intention.
However, if the user tries to close the workbook, but changes their mind and hits the cancel button when prompted to Save (Yes, No, Cancel), the Application.OnTime event is still cancelled. BeforeClose is always run before they decide to hit cancel, so has anyone got any ideas how I can only cancel the Application.OnTime event when the workbook is closed?
Here's some ideas
http://www.dailydoseofexcel.com/archives/2004/06/16/beforeclose-vs-beforereallyclose/
Check the Saved property of the Workbook in your event handler. If the workbook is unsaved then display your own dialog to find out if the users wants to save changes, not save changes or cancel.
Here's some rough code. Obviously uncomment the line which deals with the Application.OnTime part and change the MsgBox title to something suitable
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Dim response As Integer
If Not (Me.Saved) Then
response = MsgBox("Do you want to save changes to '" & Me.Name & "'?", vbYesNoCancel, "put title here")
If (response = vbCancel) Then
Cancel = True
ElseIf (response = vbYes) Then
Me.Save
End If
End If
If Not (Cancel) Then
' Application.OnTime EarliestTime:=varNextRunTime, Procedure:="SomeMethod", Schedule:=False
End If
End Sub
Investigate using:
Application.Quit
If you find this command results in the Excel program remaining open although the document has closed, you may want to follow with
ActiveWorkbook.Close False
I'm not in position to test this or give more insights, unfortunately.
A bit late to the show but here is a simple solution that I've come across (and tested):
If a user deactivates the workbook by closing it, the workbook will still remain the ActiveWorkbook when the Workbook_WindowDeactivate event fires. If the user deactivates the workbook by switching to another workbook, then the new workbook will become the ActiveWorkbook by the time Workbook_WindowDeactivate fires. You can use this behavior to determine the action that caused the event to fire:
Private Sub Workbook_WindowDeactivate(ByVal Wn As Window)
If Application.ActiveWorkbook.Name = Me.Name Then
'Your code here
End If
End Sub