Reputation: 8366
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.
Upvotes: 10
Views: 64395
Reputation: 41
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
Upvotes: 4
Reputation: 1
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
Upvotes: 0
Reputation: 41
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
Upvotes: 4
Reputation: 115
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.
Upvotes: 0
Reputation: 930
I did not try it, but maybe this will help:
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
Upvotes: 1
Reputation: 1
"ThisWorkbook.Saved = True" after "Application.Quit" works on Excel 2016
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Application.Quit
ThisWorkbook.Saved = True
End Sub
Upvotes: 0
Reputation: 9
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.
Upvotes: 0
Reputation: 1
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.
Upvotes: -1
Reputation: 1
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
Upvotes: -1
Reputation: 152
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);
Upvotes: -1
Reputation: 155
I had this issue and I resolved it by putting in the Workbook_BeforeClose()
:
ThisWorkbook.saved = true
Upvotes: 10
Reputation: 15923
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
Upvotes: 2