VBA InputBox Prompts Twice - excel

I have a simple script to require a password before closing a workbook (to prevent accidental closing), but the InputBox re-opens if I enter the correct keyword. I have created multiple iterations of the below script, but I cannot resolve it.
Sub Workbook_BeforeClose(Cancel As Boolean)
If InputBox("Please enter the password to close the workbook.") <> "pa55word" Then
MsgBox ("Incorrect password. Please try again")
Cancel = True
Exit Sub
Else
GoTo GoToClose
End If
GoToClose:
ThisWorkbook.Close SaveChanges:=False
End Sub

If you code it like this:
the code simply proceeds to save the workbook if the password is correctly without a second close
The ThisWorkbook.Saved at front tells Excel the workbook is fully updated so there wont be a do you want to save message - ie it does the same task as the False part of ThisWorkbook.Close SaveChanges:=False and the existing Save event closes the workbook.
recut
Sub Workbook_BeforeClose(Cancel As Boolean)
ThisWorkbook.Saved = True
If InputBox("Please enter the password to close the workbook.") <> "pa55word" Then
MsgBox ("Incorrect password. Please try again")
Cancel = True
End If
End Sub

Disable Events before the Close.

Related

VBA to close any open excel file and excel application [duplicate]

I have following code under a button. When clicked it just closes the current Excel sheet but not the entire Excel application.
Application.DisplayAlerts = False
ThisWorkbook.Save
Application.DisplayAlerts = True
Application.Quit
Note: I don't have any other sheets open.
The following window still appears.
I had this issue and I resolved it by putting in the Workbook_BeforeClose():
ThisWorkbook.saved = true
I experienced the same issue and was able to resolve the issue with code that looks to see if multiple workbooks are open or not ...
Application.EnableEvents = False
Application.DisplayAlerts = False
If Application.Workbooks.Count = 1 Then 'Close Excel application
ThisWorkbook.Save
Application.Quit
Else 'Close the active workbook
With ActiveWorkbook
.Close Savechanges:=True
End With
End If
When Application.Quit is encountered in a subroutine,
it will only stay in memory and continue to run lines under it
and will actually quit until it encounters a "Exit Sub".
When the normal "End Sub" at the primary level is encountered,
it will then also close Excel. But say if the workbook is somehow
closed before reaching the "Exit Sub", "End" or "End Sub" line, then
Excel will not close.
Solution is to create a Public variable called ToQuitNow
with initial False value
and change it to True where you want Excel to quit.
and test right after to see if it is true, then return to previous Sub level
by "Exit Sub" or "End" to quit right away,
and do the same at every subrountine level where
it is expected to return from the deeper subroutine.
When it gets back to the primary level,
then a final "Exit Sub" will actually terminates Excel.
If you do not want Excel to ask for saving changes made,
add line "ThisWorkbook.Saved = True" right after Application.Quit,
or before the final "Exit Sub" at the Primary level
and Excel will quit without saving.
Try the following test below, just run "Test"
Public ToQuitNow As Boolean
Sub Test()
ToQuitNow = False ' initialize with False value
Call SecondSub
MsgBox ("Primary level here. Back from SecondSub")
If ToQuitNow = True Then
Exit Sub 'will actually quit Excel now if True
End If
MsgBox ("This line will not run if ToQuitNow is True")
End Sub
Sub SecondSub()
MsgBox ("SecondSub here")
Call ThirdSub
MsgBox ("SecondSub here. Back from ThirdSub")
If ToQuitNow = True Then
Exit Sub ' will return to Main level if True
End If
MsgBox ("This line from SecondSub will not run if ToQuitNow is True")
End Sub
Sub ThirdSub()
MsgBox ("ThirdSub here")
Call FourthSub
MsgBox ("ThirdSub here. Back from FourthSub")
If ToQuitNow = True Then
Exit Sub ' will return to SecondSub if True
End If
MsgBox ("This line from ThirdSub will not run if ToQuitNow is True")
End Sub
Sub FourthSub()
MsgBox ("FourthSub here")
Application.Quit
ThisWorkbook.Saved = True ' Excel will think changes already saved _
and will quit without saving
ToQuitNow = True ' activate Quit
If ToQuitNow = True Then
MsgBox ("Quit command executed in FourthSub")
Exit Sub ' will return to ThirdSub if True
'Can also put in End in above line to quit right away
End If
MsgBox ("This line from FourthSub will not run if ToQuitNow is True.")
End Sub
remove the Application.DisplayAlerts = True from the routine.
from the help for Application.Quit Method:
If unsaved workbooks are open when you use this method, Microsoft Excel displays a dialog box asking whether you want to save the changes. You can prevent this by saving all workbooks before using the Quit method or by setting the DisplayAlerts property to False. When this property is False, Microsoft Excel doesn’t display the dialog box when you quit with unsaved workbooks; it quits without saving them.
This will avoid any (possibly hidden) prompts from stopping excel from closing completely
I did not try it, but maybe this will help:
https://www.mrexcel.com/forum/excel-questions/606195-vba-application-quit-not-working-me-completly-why.html
According to Norie you might not have anymore workbooks open, therefore Application.Quit will never be executed.
AlphaFrog therefore suggests this:
Application.DisplayAlerts = False
If Application.Workbooks.Count = 1 Then
Application.Quit
Else
ActiveWorkbook.Close
End If
The window does not close because you are using personal.xlsb. Cut Personal.xlsb and paste in another location.
Instead of Personal.xlsb create and work on modules. It's a better option.
"ThisWorkbook.Saved = True" after "Application.Quit" works on Excel 2016
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Application.Quit
ThisWorkbook.Saved = True
End Sub
I had the same issue using the following code closed excel cleanly:
Application.DisplayAlerts = False
ThisWorkbook.Save
Application.Quit
This will allow excel to cleanly close without keeping a "ghost" window open.
This worked for me: (Office 365)
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Application.DisplayAlerts = False
Application.EnableEvents = False
ThisWorkbook.Save
Application.Quit
ThisWorkbook.Saved = True
End Sub
This is a strange one, hopefully someone will find this answer useful. I ran into something very similar using Excel 2010 (14.0). I stumbled to my answer through experimentation. This is bad answer for general purpose.
For whatever reason Application.Quit fails silently if the option AccessVBOM is not enabled. It is not enabled out of the box and can be set/unset by your network admin by windows policy.
You can find this option in the GUI by traversing "Excel Options" -> "Trust Center" -> "Trust Center Settings" -> "Macro Settings" -> "Trust access to the VBA project object model". Or programmatically.
.
Since we all love code, in this example we are running Excel from C# interop and calling the quit function.
using Excel = Microsoft.Office.Interop.Excel;
using Marshal = System.Runtime.InteropServices.Marshal;
Excel.Application app = new Excel.Application();
app.Visible = false;
app.DisplayAlerts = false;
// this will hang if AccessVBOM is not enabled
app.Quit();
Marshal.ReleaseComObject(app);
Have passed MacroName from bat file and tried the below code its working. But one thing I observed is if we are closing the workbook(ActiveWorkbook.Close) before Application.Quit then it is not working.
Private Sub Auto_Open()
Dim strMacroName As String
strMacroName =
VBA.CreateObject("WScript.Shell").Environment("process").Item("MacroName")
If strMacroName <> "" Then Run strMacroName
Application.DisplayAlerts = False
ThisWorkbook.Save
Application.DisplayAlerts = True
If strMacroName <> "" Then Application.Quit
End Sub
Sub Button1_Click()
MsgBox ("done")
End Sub
Make sure that your sheets do not have any external link references, especially broken links.
I struggled with this problem for more than a week, rewriting and commenting out lots of code to try to isolate the problem. I finally did a review of all table and external sheet references in my workbook this morning. I removed all unnecessary links and broken references and the workbook now closes without hanging in memory.

VBA Before close event

there is 2 events in my code i.e Before close,before save. in before save condition there are conditions to be filled before saving, else it wont allow to save. now while triggering before close, it will popup for save, dontsave, cancel message box. when selecting save, it will call before save function and it throws error message as like before save function. but after that file is closed.
Public Sub Workbook_BeforeClose(Cancel As Boolean)
Exit Sub
End Sub
I think i misunderstood what u tried to describe , but take a look if my code below can help you.
Public Sub Workbook_BeforeClose(Cancel As Boolean)
Select Case MsgBox("Select what do you want", vbYesNoCancel + vbExclamation, "Atention")
Case vbYes
Call Workbook_BeforeSave(True, False)
Case vbNo
Application.Quit
Case vbCancel
Cancel = True
End Select
Exit Sub

Closing application only thru VBA

I have this workbook and I want to make it look like a program.
I also want people using it to only be able to quit the application thru a specific command button.
Here is the code I have
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Application.OnKey "{ESC}"
Cancel = True
MsgBox "Please use the QUIT button to save and close the database."
End Sub
And for the quit button:
Sub SAVE_CLOSE
ActiveWorkbook.Save
If Workbooks.Count < 2 Then
Application.Quit
Else
ActiveWorkbook.Close
End If
End Sub
My problem is that when the user quit the application thru this button, it triggers the Private Sub Workbook_BeforeClose event and cancel the quitting process. How would you fix this?
Thanks!
Just set a flag in the button handler and test for it in the BeforeClose event:
In ThisWorkbook...
Public okToClose As Boolean '<--module level.
Private Sub Workbook_BeforeClose(Cancel As Boolean)
If Not okToClose Then
Application.OnKey "{ESC}"
Cancel = True
MsgBox "Please use the QUIT button to save and close the database."
End If
End Sub
...and in the handler...
Sub SAVE_CLOSE()
ActiveWorkbook.Save
ThisWorkbook.okToClose = True
If Workbooks.Count < 2 Then
Application.Quit
Else
ActiveWorkbook.Close
End If
End Sub
Note that you should avoid calling ActiveWorkbook.Close - use a hard reference instead. That's a really good way to destroy somebody's day's worth of work...
Since Workbook_BeforeClose() is called whenever the workbook is about to close (whether it's your method or not) you'll need some way within that method to know that it was your button that called it. Perhaps a global variable, or a value in a given cell on a hidden sheet?

Application.Quit command not closing the entire Excel Application

I have following code under a button. When clicked it just closes the current Excel sheet but not the entire Excel application.
Application.DisplayAlerts = False
ThisWorkbook.Save
Application.DisplayAlerts = True
Application.Quit
Note: I don't have any other sheets open.
The following window still appears.
I had this issue and I resolved it by putting in the Workbook_BeforeClose():
ThisWorkbook.saved = true
I experienced the same issue and was able to resolve the issue with code that looks to see if multiple workbooks are open or not ...
Application.EnableEvents = False
Application.DisplayAlerts = False
If Application.Workbooks.Count = 1 Then 'Close Excel application
ThisWorkbook.Save
Application.Quit
Else 'Close the active workbook
With ActiveWorkbook
.Close Savechanges:=True
End With
End If
When Application.Quit is encountered in a subroutine,
it will only stay in memory and continue to run lines under it
and will actually quit until it encounters a "Exit Sub".
When the normal "End Sub" at the primary level is encountered,
it will then also close Excel. But say if the workbook is somehow
closed before reaching the "Exit Sub", "End" or "End Sub" line, then
Excel will not close.
Solution is to create a Public variable called ToQuitNow
with initial False value
and change it to True where you want Excel to quit.
and test right after to see if it is true, then return to previous Sub level
by "Exit Sub" or "End" to quit right away,
and do the same at every subrountine level where
it is expected to return from the deeper subroutine.
When it gets back to the primary level,
then a final "Exit Sub" will actually terminates Excel.
If you do not want Excel to ask for saving changes made,
add line "ThisWorkbook.Saved = True" right after Application.Quit,
or before the final "Exit Sub" at the Primary level
and Excel will quit without saving.
Try the following test below, just run "Test"
Public ToQuitNow As Boolean
Sub Test()
ToQuitNow = False ' initialize with False value
Call SecondSub
MsgBox ("Primary level here. Back from SecondSub")
If ToQuitNow = True Then
Exit Sub 'will actually quit Excel now if True
End If
MsgBox ("This line will not run if ToQuitNow is True")
End Sub
Sub SecondSub()
MsgBox ("SecondSub here")
Call ThirdSub
MsgBox ("SecondSub here. Back from ThirdSub")
If ToQuitNow = True Then
Exit Sub ' will return to Main level if True
End If
MsgBox ("This line from SecondSub will not run if ToQuitNow is True")
End Sub
Sub ThirdSub()
MsgBox ("ThirdSub here")
Call FourthSub
MsgBox ("ThirdSub here. Back from FourthSub")
If ToQuitNow = True Then
Exit Sub ' will return to SecondSub if True
End If
MsgBox ("This line from ThirdSub will not run if ToQuitNow is True")
End Sub
Sub FourthSub()
MsgBox ("FourthSub here")
Application.Quit
ThisWorkbook.Saved = True ' Excel will think changes already saved _
and will quit without saving
ToQuitNow = True ' activate Quit
If ToQuitNow = True Then
MsgBox ("Quit command executed in FourthSub")
Exit Sub ' will return to ThirdSub if True
'Can also put in End in above line to quit right away
End If
MsgBox ("This line from FourthSub will not run if ToQuitNow is True.")
End Sub
remove the Application.DisplayAlerts = True from the routine.
from the help for Application.Quit Method:
If unsaved workbooks are open when you use this method, Microsoft Excel displays a dialog box asking whether you want to save the changes. You can prevent this by saving all workbooks before using the Quit method or by setting the DisplayAlerts property to False. When this property is False, Microsoft Excel doesn’t display the dialog box when you quit with unsaved workbooks; it quits without saving them.
This will avoid any (possibly hidden) prompts from stopping excel from closing completely
I did not try it, but maybe this will help:
https://www.mrexcel.com/forum/excel-questions/606195-vba-application-quit-not-working-me-completly-why.html
According to Norie you might not have anymore workbooks open, therefore Application.Quit will never be executed.
AlphaFrog therefore suggests this:
Application.DisplayAlerts = False
If Application.Workbooks.Count = 1 Then
Application.Quit
Else
ActiveWorkbook.Close
End If
The window does not close because you are using personal.xlsb. Cut Personal.xlsb and paste in another location.
Instead of Personal.xlsb create and work on modules. It's a better option.
"ThisWorkbook.Saved = True" after "Application.Quit" works on Excel 2016
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Application.Quit
ThisWorkbook.Saved = True
End Sub
I had the same issue using the following code closed excel cleanly:
Application.DisplayAlerts = False
ThisWorkbook.Save
Application.Quit
This will allow excel to cleanly close without keeping a "ghost" window open.
This worked for me: (Office 365)
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Application.DisplayAlerts = False
Application.EnableEvents = False
ThisWorkbook.Save
Application.Quit
ThisWorkbook.Saved = True
End Sub
This is a strange one, hopefully someone will find this answer useful. I ran into something very similar using Excel 2010 (14.0). I stumbled to my answer through experimentation. This is bad answer for general purpose.
For whatever reason Application.Quit fails silently if the option AccessVBOM is not enabled. It is not enabled out of the box and can be set/unset by your network admin by windows policy.
You can find this option in the GUI by traversing "Excel Options" -> "Trust Center" -> "Trust Center Settings" -> "Macro Settings" -> "Trust access to the VBA project object model". Or programmatically.
.
Since we all love code, in this example we are running Excel from C# interop and calling the quit function.
using Excel = Microsoft.Office.Interop.Excel;
using Marshal = System.Runtime.InteropServices.Marshal;
Excel.Application app = new Excel.Application();
app.Visible = false;
app.DisplayAlerts = false;
// this will hang if AccessVBOM is not enabled
app.Quit();
Marshal.ReleaseComObject(app);
Have passed MacroName from bat file and tried the below code its working. But one thing I observed is if we are closing the workbook(ActiveWorkbook.Close) before Application.Quit then it is not working.
Private Sub Auto_Open()
Dim strMacroName As String
strMacroName =
VBA.CreateObject("WScript.Shell").Environment("process").Item("MacroName")
If strMacroName <> "" Then Run strMacroName
Application.DisplayAlerts = False
ThisWorkbook.Save
Application.DisplayAlerts = True
If strMacroName <> "" Then Application.Quit
End Sub
Sub Button1_Click()
MsgBox ("done")
End Sub
Make sure that your sheets do not have any external link references, especially broken links.
I struggled with this problem for more than a week, rewriting and commenting out lots of code to try to isolate the problem. I finally did a review of all table and external sheet references in my workbook this morning. I removed all unnecessary links and broken references and the workbook now closes without hanging in memory.

How to disable the save as prompt?

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

Resources