This may sound silly but I'm trying to prevent saving in Excel Workbook by using the code below in ThisWorkbook:
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Cancel = True
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Application.ThisWorkbook.Saved = True
End Sub
However, after pressing Ctrl + s, and close the workbook, when reopening it, the code wasn't saved.
Any idea why this happen ?
This is a good thing - it means your code is working right. Your code prevented you from saving the workbook yourself. I have this in a couple applications I have made, the way around it is to make a sub as follows:
sub saveTheWB()
Application.EnableEvents = False
ThisWorkbook.Save
Application.EnableEvents = True
end sub
You have to run this sub every time you want to save.
That's right because the Workbook_BeforeSave event handler is firing and cancelling the save operation.
In the Immediate window of The IDE, run Application.EnableEvents = False before saving your workbook and it will save with the code.
Don't forget to run Application.EnableEvents = True after!
Related
I have an excel Workbook that uses Power Query to populate a table. The query pulls information from multiple external Workbooks as well as a table in a Worksheet within the same Workbook.
The Worksheet in the same Workbook also stores changes to columns that are meant to be manipulated. The Worksheet in the same Workbook is part of a loop. It stores information that is pulled into the main table but also stores the changes made.
To make this work correctly, the Workbook needs to be Saved before the storage query runs. If a Save does not occur before running the query, the query will not contain the changes.
This is accomplished easily when clicking the save button. The following code works well:
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Application.EnableEvents = False
ThisWorkbook.Save
ThisWorkbook.Connections("Query - Stored").Refresh
Application.EnableEvents = True
End Sub
This does not work when the workbook is closed and save is clicked after clicking the document close.
The BeforeSave event does not fire because it does not get a chance to. The document closes and when it is reopened it shows it as a crashed file and is listed in the recovery list.
Can anyone help me understand why and how to overcome it.
Since this is caused by an Excel crash while closing, it's possible that the Refresh gets messed up when Close is underway.
You could try executing the Refresh before Closing, like this
Private Closing As Boolean
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Closing = True
Application.EnableEvents = False
ThisWorkbook.Save
ThisWorkbook.Connections("Query - Stored").Refresh
Application.EnableEvents = True
End Sub
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
If Closing Then Exit Sub
Application.EnableEvents = False
ThisWorkbook.Save
ThisWorkbook.Connections("Query - Stored").Refresh
Application.EnableEvents = True
End Sub
I am trying to protect my Excel VBA from saving by others who are also using my macro. I tried using the below code but it is not working. I want to prevent others from saving the VBA Excel before closing as well as while using Ctrl+S for saving.
Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
If Not SaveAsUI Then
Cancel = True
MsgBox "You cannot save this workbook"
End If
End Sub
I'm using Excel 2019 and I cannot reproduce your issue. The code works as expected. If I press Save I get the message box and it does not save. If I close the workbook, it asks me if I want to save, if I press Save I again get the message box and it does not save.
But you can try to add a Workbook_BeforeClose event with a ThisWorkbook.Saved = True to make VBA believe the workbook was already saved. This prevents the message box when closing the workbook, that asks if you want to save or not.
Option Explicit
Private Sub Workbook_BeforeClose(Cancel As Boolean)
ThisWorkbook.Saved = True
End Sub
Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
If Not SaveAsUI Then
Cancel = True
MsgBox "You cannot save this workbook"
End If
End Sub
So this is strange to me, but I have a macro-enabled excel 2016 file. The only macro in the file is a BeforeSave event, which is stored in ThisWorkbook. After using the blank file once or twice, it gets to the point where opening the file and doing anything at all, like clicking File or Developer or entering data, causes excel to "Stop Working" and close.
Below is the BeforeSave event which is the only macro in this file (there are no modules or userforms, nothing else in ThisWorkbook).
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Application.EnableEvents = False
Cancel = True
ThisWorkbook.Sheets("Pending").Columns(9).NumberFormat = "#"
ActiveWorkbook.Save
Application.EnableEvents = True
End Sub
This basic macro event will work perfectly for a few times. Then after some data is in the file, the next time it is opened the issue will occur. This is the only excel file that experiences this crash, I can still open the original backup file with this macro that does not have data in it yet, and it will be okay.
I have tried opening the file in Safe Mode, and I have installed all the latest Microsoft Office updates.
Has anyone else experienced an issue like this? Does it have something to do with the BeforeSave event macro?
UPDATE:
I changed the ActiveWorkbook to ThisWorkbook. Also, I have changed from editing the entire column to now finding the last used row and formatting that range excluding the header row.
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Application.EnableEvents = False
Cancel = True
Dim Lastrow As Integer
Lastrow = ThisWorkbook.Sheets("Pending").Cells(Rows.Count, 9).End(xlUp).Row
ThisWorkbook.Sheets("Pending").Range("I2:I" & Lastrow).NumberFormat = "#"
ThisWorkbook.Save
Application.EnableEvents = True
End Sub
Thank you.
As Zack & GWD advised in the comments, I updated the VBA to factor in the header row and set all references to ThisWorkbook instead of including ActiveWorkbook. So far the error has not occurred again. If it does happen in the future, I will post a new question if I cannot solve the issue.
Here is the updated code for reference:
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Application.EnableEvents = False
Cancel = True
Dim Lastrow As Integer
Lastrow = ThisWorkbook.Sheets("Pending").Cells(Rows.Count, 9).End(xlUp).Row
ThisWorkbook.Sheets("Pending").Range("I2:I" & Lastrow).NumberFormat = "#"
ThisWorkbook.Save
Application.EnableEvents = True
End Sub
My Workbook_BeforeSave event is not called before saving
This is my code:
Option Explicit
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
a = MsgBox("Do you really want to save the workbook?", vbYesNo)
If a = vbNo Then Cancel = True
End Sub
This is probably normal, because events are probably not enabled.
Now I tried to put Application.Events = True like this:
Option Explicit
Application.Events = True
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
a = MsgBox("Do you really want to save the workbook?", vbYesNo)
If a = vbNo Then Cancel = True
End Sub
This doesn't change anything, Workbook_BeforeSave is still not called up on saving. But when I close the excel file, following error message is displayed :
The english translation is "Compilation error: Incorrect instruction outside of a procedure."
Apparently the Application.Events = True is not at the right place, but where should I put it ?
Hope these will help:
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean) must be inside ThisWorkbook in a VBA project.
Application.EnableEvents = True can not be inserted outside procedure or function.
Events are enabled by default. So, there must be somewhere inside vba project Events are getting disabled. This can be searched by :
Once you are inside VBA project, Press Ctrl+F to open the Find dialog box. Then search for application.enableevents in the current project. Press Find Next. See the image below.
You can use a little sub to change and view the Application.EnableEvents status (ON/OFF). Place the sub under any standard module. See the image below.
If IsWorkbookOpen("CONTRACT\CONTRACTLIST_Cement.xlsx") Then
x = 0
Else
Application.DisplayAlerts = False
ActiveWorkbook.Close savechanges:=True
Application.DisplayAlerts = True
End If
Hi, despite using the above code, the save as prompt still occasionally appears and affect the program. Does anyone know how to stop it completely? The problem is that after I click save as, it will alert me that it was still open.
Try below code
Its always good to explcilty refer the workbook rather than ActiveWorkbook
Sub test()
If IsWorkbookOpen("CONTRACT\CONTRACTLIST_Cement.xlsx") Then
x = 0
Else
Application.DisplayAlerts = False
ThisWorkbook.Save
ThisWorkbook.Close False
Application.DisplayAlerts = True
End If
End Sub
You can use Workbook_BeforeSave Event in the ThisWorkbook object to capture the user selecting SaveAs (or using the keyboard shortcut), which would result in the Save As prompt being displayed and the SaveAsUI being set to true. If SaveAsUI is true, this means the user is trying to save the file as something else, so you can then cancel the save As operation.
Open up the Visual Basic Window (Alt + F11) and put the following code in ThisWorkbook.
Disable Save As
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
If (SaveAsUI = True) Then
MsgBox "Sorry. I can't have you saving this file as something else."
Cancel = True
End If
End Sub
You can delete the MsgBox line if you want; i put it there as an example if you wanted to notify the user that the function was disabled
To disable both the Save and Save As functionalities, you would remove the if statement and cancel the Save operation, regardless of if the Save as prompt is displayed.
Disable Save and Save As
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
MsgBox "Sorry. I can't have you saving this file at all."
Cancel = True
End Sub
If you just want to disable the Save operation, you would only need to look for the occurrence where the user is saving, but the SaveAsUI is not being displayed (i.e. user is simply saving the file).
Disable Save
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
If (SaveAsUI = False) Then
MsgBox "Sorry. I can't have you saving any updates to this file."
Cancel = True
End If
End Sub
Finally, note that the user will still get a prompt to save if the user simply closes the file. The user won't be able to save and the file will close, but if you want the experience to be a bit cleaner, you'll need to make an additional change. When a user closes a file, Excel checks the ThisWorkbook.Saved variable to see if the file has been saved. If it is false, it will prompt the user to Save the file. To prevent this as well, we can set this boolean to true without saving, thus "tricking" Excel into thinking the file has been saved
Disable Save and Save As, including after User attempts to close file
Add the following code after your Workbook_BeforeSave code.
Private Sub Workbook_BeforeClose(Cancel As Boolean)
ActiveWorkbook.Saved = True
MsgBox "Click OK to continue closing this file. Changes will not be saved."
End Sub