Message box with if condition - excel

I want to save as an excel file as .csv from Sheet2 (Sheet name changes) so I want excel to pop up a message if I try to save as the file from Sheet1. I've a code to pop up the message but I'm not sure how to apply if condition for this scenario. Thank you for your help!!
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean)
If SaveAsUI Then
MsgBox "Make sure you are on correct sheet"
End If
End Sub

This Should Work for you:
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
If SaveAsUI Then
If ActiveSheet.Name = "Sheet1" Then
MsgBox "Make sure you are on correct sheet"
SaveAsUI = False
End If
End If
End Sub
If you are on Sheet1, the Msgbox will pop and sheet won't be saved.

Related

Protect VBA Excel from saving by others

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

VBA - Event inside event (BeforeClose -> BeforeSave) not working

I've hijacked saving in an excel file for the purposes of preventing unintended overwrites of a file in an odd environment.
The Workbook_BeforeSave and the Workbook_BeforeClose events work perfectly on their own. Unfortunately, the way the code is currently structured, I would need to call the BeforeSave event from within the BeforeClose event.
In the most basic form, the following code will not do as I'd like. In the following example, wksHiddenWorksheet.Visible = True will not make wksHiddenWorksheet visible if the save is called from within the BeforeClose event.
Option Explicit
Private Sub Workbook_BeforeClose(Cancel As Boolean)
ThisWorkbook.Save
End Sub
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
wksHiddenWorksheet.Visible = True
End Sub
Is there any way around this? Is it poor practise (or even fundamentally incorrect) to call an event from inside another event in the way that I'm attempting?
Update:
I have played around with Application.EnableEvents in the workbook, but I've made sure it always reverts back to True in error handling.
I've opened a brand new workbook and entered the following code
Option Explicit
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Debug.Print Application.EnableEvents 'Prints TRUE
ThisWorkbook.Save
End Sub
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
'The workbook consists of two sheets. Sheet1 and Sheet2
Sheet1.Visible = xlSheetHidden
Debug.Print Sheet1.Visible 'Prints -1 (xlSheetVisible)
End Sub
The Visible sheet does not become hidden, though the line is triggered if I go line by line through the code. If I enter code such as a MsgBox in the same space, the MsgBox will open as normal.
Update 2:
To answer everyone's questions and display exactly what happens, please see the below code:
Option Explicit
Private Sub Workbook_BeforeClose(Cancel As Boolean)
'The workbook consists of two sheets. Sheet1 and Sheet2
Debug.Print Application.EnableEvents 'Prints TRUE
Debug.Print Sheet1.Visible 'Prints -1 (xlSheetVisible)
Sheet1.Visible = xlSheetHidden
Sheet1.Visible = False 'Same thing
Debug.Print Sheet1.Visible 'Prints 0 (xlSheetHidden)
Sheet1.Visible = xlSheetVisible
Sheet1.Visible = True 'Same thing
Debug.Print Sheet1.Visible 'Prints -1 (xlSheetVisible)
ThisWorkbook.Save
End Sub
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Debug.Print Sheet1.Visible 'Prints -1 (xlSheetVisible)
Sheet1.Visible = xlSheetHidden
Sheet1.Visible = False 'Same thing
'Sheet1 should now be hidden, but it's not
Debug.Print Sheet1.Visible 'Prints -1 (xlSheetVisible)
End Sub
Hiding and unhiding sheets works perfectly in the first event, but as soon as the second event is triggered, the sheet visibility does not change.
Update 3:
Another point. If I enter the Workbook_BeforeSave() event directly (by saving), rather than entering it from the Workbook_BeforeClose() event, then everything works as expected.
MUCH LATER UPDATE:
Although I marked this question as solved a while ago, I've come across an article that helps to explain the behaviour. An explanation can be found at:
http://www.cpearson.com/excel/events.aspx
edited after all clarifications
the following code worked for me
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Workbook_BeforeSave False, True
ThisWorkbook.Save
End Sub
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
If Cancel Then Sheet1.Visible = xlSheetHidden
End Sub
hard to tell why though...
In this example procedure HideSheet is called from BeforeSave and from BeforeClose event handler. So both handlers hide the sheet. HTH
Private Sub Workbook_BeforeClose(Cancel As Boolean)
HideSheet Sheet1
ThisWorkbook.Save
End Sub
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
HideSheet Sheet1
End Sub
Private Sub HideSheet(wks As Worksheet)
wks.Visible = xlSheetHidden
End Sub

Refuse save if cell contains text

I have this code, that refuses and cancels to save a workbook if a cell contains a specific text. the code is working fine, but if i want it to refuse saving if some cells in a range contains specific text then it is not working. my code below that is working:
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
If Sheets("Sheet1").Range("A1").Value = "Fill in a comment" Then
Cancel = True
Response = MsgBox("Fill in a comment", vbCritical, "Error!")
End If
End Sub
the code that i tried to make it work but its not
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean
For Each c In Sheet1.Range("A1:A5000")
If c.Value = "Fill in a comment" Then
Cancel = True
Response = MsgBox("Fill in a comment", vbCritical, "Error!")
End If
Next
End Sub
do you guys have any ideas?
Try this instead rather than looping:
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Cancel = Not Sheet1.Range("A1:A5000").Find("Fill in a comment") Is Nothing
If Cancel Then MsgBox "Fill in a comment", vbCritical, "Error!"
End Sub
It uses the .Find() method to look for "Fill in a comment" and if it isn't Nothing then Cancel is set to True
Then, we test the value of Cancel to see if we need to display the message box.
Doing it this way also makes sure that you don't get 500 message boxes if you have "Fill in a comment" written in 500 different cells in that range...

Call a sub in Workbook_BeforeSave event [duplicate]

This question already has answers here:
Making fields mandatory of a specific sheet on workbook save
(3 answers)
Closed 8 years ago.
I want to call this Sub in the Workbook_BeforeSave event:
Sub test()
If ActiveSheet.Range("A4") = "" Then
MsgBox ("Please fill in cell A4!")
Exit Sub
Else
End If
End Sub
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
test
End Sub
When I click save the file is saved even if the cell A4 is blank.
You should set Cancel as the proper way to terminate the save event.
It would be better to have test as a function, so you can check the return value, and set cancel appropriately.
Function test() as Boolean
If ActiveSheet.Range("A4") = "" Then
Test = False
Else
Test = True
End If
End Sub
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
If test = False then Cancel=True
End Sub
Also, ActiveSheet is not appropriate, unless you have only one worksheet, and you have protected the workbook from having extra sheets added.
My suggested solution would be to check Sheets("MySheet").Range("A4").
Of course, the laziest way to do the test would be:
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
cancel = (ActiveSheet.Range("A4") = "")
End Sub
where the test is done within the save procedure, and no sub tests are required.
Try:
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Call test
End Sub
Sub test()
If ActiveSheet.Range("A4") = "" Then
MsgBox ("Please fill in cell A4!")
End
End If
End Sub
Exit Sub merely terminates sub test(), while End completely stops code execution, thus preventing Workbook_BeforeSave() from running further.
if cancel is true, the saving will be blocked :
Sub Test(byref cancel as boolean)
If ActiveSheet.Range("A4") = "" Then
MsgBox ("Please fill in cell A4!")
cancel = true
Exit Sub
'Else
End If
End Sub
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Test Cancel
End Sub

Can't unprotect an excel worksheet in Workbook_BeforeSave

I am using Workbook_BeforeSave to update some cells on a locked sheet in excel 2010. The subroutine works as desired when using ctrl-s to save, but will not unlock the sheet when using .Save in vba.
ThisWorkbook(code)
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Dim MyPassword As String
MyPassword = "password"
ActiveWorkbook.Worksheets("Sheet1").Unprotect (MyPassword)
ActiveWorkbook.Worksheets("Sheet1").Range("A1").Value = Now
ActiveWorkbook.Worksheets("Sheet1").Range("A2").Value = ThisWorkbook.BuiltinDocumentProperties("Author")
ActiveWorkbook.Worksheets("Sheet1").Protect (MyPassword)
End Sub
Module1(Code)
Sub SaveMe()
ActiveWorkbook.Save
End Sub
I have a button that calls SaveMe(). SaveMe() saves the document, activating Workbook_BeforeSave. The Worsheet fails to unprotect, causing an error when writing to A1.
The error states:
Run-time error '1004':
Application-defined or object-defined error
This worked for me, but it is not very elegant. I did not find a separate module for both unprotecting and writing worked.
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
UnlockWorksheets
With ThisWorkbook.Worksheets("Sheet1")
.Range("A1").Value = Now
.Range("A2").Value = ThisWorkbook.BuiltinDocumentProperties("Author")
End With
LockWorksheets
End Sub
Sub SaveMe()
UnlockWorksheets
ThisWorkbook.Save
LockWorksheets
End Sub
Sub UnlockWorksheets()
ThisWorkbook.Worksheets("Sheet1").Unprotect Password:="password"
End Sub
Sub LockWorksheets()
ThisWorkbook.Worksheets("Sheet1").Protect Password:="password"
End Sub
why not put the 'before save' module into a new sub routine and have the before close call that
EG.
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Call SomeSub
End Sub
sub someSub()
'Code here
end sub
sub Button()
call SomeCub
activeworkbook.save
end sub

Resources