Vba excel закрыть окно excel

I have used the following without success. The active workbook closes, indeed, but the excel window remains open.

Application.ActiveWindow.Close SaveChanges:=False
ActiveWorkbook.Close SaveChanges:=False

Which is the command that terminates the application?

EDIT

To say a little more: In the workbook Open event I run a macro. I want to terminate the application when that macro finishes. I also tried this without success.

Private Sub Workbook_Open()
   Macro_MyJob
   Application.Quit
End Sub

Where should I put this Application.Quit command?

asked Sep 2, 2010 at 14:45

Brani's user avatar

BraniBrani

6,57415 gold badges46 silver badges49 bronze badges

I think your problem is that it’s closing the document that calls the macro before sending the command to quit the application.

Your solution in that case is to not send a command to close the workbook. Instead, you could set the «Saved» state of the workbook to true, which would circumvent any messages about closing an unsaved book. Note: this does not save the workbook; it just makes it look like it’s saved.

ThisWorkbook.Saved = True

and then, right after

Application.Quit

answered Sep 2, 2010 at 16:00

variant's user avatar

variantvariant

1,3442 gold badges11 silver badges18 bronze badges

To avoid the Save prompt message, you have to insert those lines

Application.DisplayAlerts = False
ThisWorkbook.Save
Application.DisplayAlerts = True

After saving your work, you need to use this line to quit the Excel application

Application.Quit

Don’t just simply put those line in Private Sub Workbook_Open() unless you got do a correct condition checking, else you may spoil your excel file.

For safety purpose, please create a module to run it. The following are the codes that i put:

Sub testSave()
Application.DisplayAlerts = False
ThisWorkbook.Save
Application.DisplayAlerts = True
Application.Quit
End Sub

Hope it help you solve the problem.

answered Apr 29, 2013 at 8:14

Leng Keong's user avatar

Leng KeongLeng Keong

1431 silver badge3 bronze badges

1

Sub TestSave()
Application.Quit
ThisWorkBook.Close SaveChanges = False
End Sub

This seems to work for me, Even though looks like am quitting app before saving, but it saves…

answered Jan 6, 2015 at 8:33

kc kalama's user avatar

kc kalamakc kalama

711 silver badge1 bronze badge

2

Application.Quit 

Should do the trick.

answered Sep 2, 2010 at 14:47

Michael's user avatar

MichaelMichael

1,6362 gold badges16 silver badges21 bronze badges

0

I tried a certain sequence that seems to work as you can see below:

ThisWorkbook.Saved = True
Application.Quit
Application.ActiveWindow.Close SaveChanges:=False
ActiveWorkbook.Close SaveChanges:=False

ForceMagic's user avatar

ForceMagic

6,15212 gold badges68 silver badges88 bronze badges

answered Jul 17, 2013 at 19:55

Dan's user avatar

You can try out

ThisWorkbook.Save
ThisWorkbook.Saved = True
Application.Quit

answered Mar 27, 2019 at 5:19

K10's user avatar

In my case, I needed to close just one excel window and not the entire application, so, I needed to tell which exact window to close, without saving it.

The following lines work just fine:

Sub test_t()
  Windows("yourfilename.xlsx").Activate
  ActiveWorkbook.Close SaveChanges:=False
End Sub

answered Jun 7, 2018 at 13:55

Panagiotis Chatzikonstantis's user avatar

Sub button2_click()
'
' Button2_Click Macro
'
' Keyboard Shortcut: Ctrl+Shift+Q
'
    ActiveSheet.Shapes("Button 2").Select
    Selection.Characters.Text = "Logout"
    ActiveSheet.Shapes("Button 2").Select
    Selection.OnAction = "Button2_Click"
    ActiveWorkbook.Saved = True
    ActiveWorkbook.Save
    Application.Quit
End Sub

LuigiEdlCarno's user avatar

answered Jul 26, 2013 at 7:07

Menon's user avatar

закрытие екселя с сохранением и без предупреждения (Макросы/Sub)

​Смотрите также​​ клавиатуре)​ для нажатия кнопки:​ просто скрывает формулу​ перехватывать события на​ сценарии. Она такая.​ с Книги3 в​
​Mishel915​ одном Макросе1) книги.​ ‘и закрываю окно​
​: Кнопочка с решёткой,​
​ As Excel.Application) app.ActiveWorkbook.Close​
​ как. По-видимому, работающий​
​:​
​ другое сообщение, хотя​
​ файл Эксель, да​

​ True)​​85Muslim85​
​Не хочу размещать​
​Private Sub CommandButton1_Click()​
​ от пользователя​ уровне Application.​ В коллекции Workbooks​
​ Книгу1, потом перейти​
​:​Если команда о​ редактора VBA​
​ однако​
​ 0 app.Quit End​
​ макрос не дает​
​Mary_Rustle​ ничего принципиального я​ так чтобы и​Workbooks.Close True​: добрый день, скажите​
​ кнопки на форме​
​ Unload Me Set​метод Unload (имя​Mishel915​ фиксируется определённый порядок​ в Книгу2, потом​
​EducatedFool !​
​ закрытии книг поступает​Возможно и Вам​Glen​ SubА в самой​ выполнить команду Quit.​, а какой смысл​
​ не поменяла:​ в скрытых процессах​' закрыть без​ как закрыть ексель​
​ - так сделай​

​ UserForm1 = Nothing​​ формы) — выгружает​: Работает так :​ чередования открытых книг,​
​ перейти в Книгу1,​
​Спасибо за этюд.​
​ из Книги1, то​

excelworld.ru

VBA Access: как закрыть книгу Эксель без сохранения?

​ это поможет.​​: не получается код​
​ книге прописать​ Можно попробовать накидать​ открывать файл Excel​
​Помогите, пожалуйста, это​ его тоже не​ сохранения (без запроса​ (полностью выйти) с​ ее масенькой (все​ End Sub​ форму из памяти​Sub Макрос1() Dim​
​ который не меняется.​
​ после чего подать​Да, необходимо было​ закрывается только Книга1.​Glen​ прикрепить​Sub QE() Dim​ нажатий клавиш, типа​ и запускать макрос,​ очень большая проблема,​ было.​ подтверждения пользователя, даже​ сохранением под таким​ размеры и положение=1​flower2005​ и закрывает её​ wb As Workbook​ Код размещён в​ команду о закрытии​ подойти к ThisWorkbook​ Книга2 остаётся открытой.​:​Glen​ obj As Object​Код Sub closeE()​ если файл потом​ уже долго бьюсь​

​Я делаю следующее:​ если .DisplayAlerts =​ же названием и​ — прекрасно работает.Пусть​: А может быть,​CердЖиГ​

​ For Each wb​ Книге3, а запускается​ двух книг, то​ с другой стороны​Очевидно это происходит​

​ОлеггелО​​:​
​ Set obj =​ Set sh =​
​ закрывается без сохранения​ над ней, никаких​
​Private Sub Кнопка0_Click()​ True)​ без предупреждения​ в проекте существует​ стоит обработать событие​: Всем спасибо уже​ In Workbooks If​ с Книги1. Как​ закрывается только Книга1?​ !​ из-за того, что​,​Sub rr()​ CreateObject(‘Имя класса’) obj.ExcelQuit​ CreateObject(‘WScript.Shell’) sh.SendKeys (‘{F10}{Down​ (oBook.Close​ успехов!​ FullFilePath = «C:Папка7​Workbooks.Close False​скажите что в​

​ Userform1, тогда:​​ UserForm_KeyPress и,​​ сделал так :-)​​ wb.Name <> Application.ActiveWorkbook.Name​ только в коде​ Книга2 остётся не​Достаточно всего лиш​ управляющая книга (книга​спс.​​Set VBProj =​​ Application End SubЕсли​ 9}{Enter}{Right}{Enter}’) End Sub​False​Mary_Rustle​

​ свод реестров 2015_9.xlsm»​​’ закрыть Excel​​ этом коде не​​Private Sub UserForm_KeyPress(ByVal​если это клавиша​

CyberForum.ru

Надо закрыть через VBA Excel ,без сохранения и без выскакивания запросов на сохранеие

​Private Sub CommandButton1_Click()​​ And wb.Name <>​ подошла очередь закрыть​ закрытой?​Sub test() Dim​
​ с управляющим макросом)​Mishel915​

​ ActiveWorkbook.VBProject​​ установлен ODE, то​ Здесь надо подрегулировать​)? Этот макрос, что​: Ответ найден!​
​ Dim app As​ (закроется только если​ так((((​ KeyAscii As MSForms.ReturnInteger)​ ESC, выполнить закрытие​Unload userform1​ ThisWorkbook.Name Then wb.Close​ Книгу1, код её​4. Если перейти​ wb As Workbook​
​ закрывается первой, после​: Всем доброе время​Set VBComp =​ создание такой dll​ цифру в {Down​ ли, создает какой-то​Видимо плохо раньше​ Object Set app​ в этом же​200?’200px’:»+(this.scrollHeight+5)+’px’);»>Sub вава()​ If KeyAscii =​

​ формы, а на​​ActiveWorkbook.Save​ Next Application.ActiveWorkbook.Close End​ закрывает, после чего​ с Книги3 в​
​ For Each wb​ чего выполнение Макроса1​
​ суток !​ VBProj.VBComponents(«Лист3»)​ займет несколько минут​
​ 9}. Да и​ другой файл, который​ старалась​
​ = CreateObject(«Excel.Application») With​ Application больше нет​Range(«A1») = 1​ 27 Then MsgBox​ другие клавиши не​
​End Sub​ Sub​ выполнение кода прекращается​ Книгу1, потом перейти​ In Workbooks If​
​ прекращается.​Две книги Excel​Set CodeMod =​Glen​ работает это только​ потом используется?​Изменила код следующим​ app .Workbooks.Open FullFilePath​

CyberForum.ru

Закрыть окно редактора VBA макросом (Макросы/Sub)

​ открытых и не​​Workbooks.Application.DisplayAlerts = False​
​ ‘Была нажата ESC,​ реагировать.​Pavel55​СердЖиГ​
​ так как код​ в Книгу2, потом​ wb.Name <> ThisWorkbook.Name​Такой вопрос :​
​ (Книга1 и Книга2)​ VBComp.CodeModule​

​: Доброго дня.​​ с листа Excel,​
​Mary_Rustle​ образом:​
​ End With app.Run​

​ сохраненных книг,​​Excel.ActiveWorkbook.SaveAs («rl.xlsm»)​
​ прячем форму’ UserForm1.Hide​flower2005​: )) ну, всё​

​: Уважаемые форумчане!​​ запущен с Книги1.​ перейти в Книгу1,​%)

​ Then wb.Close Next​​ какой должен быть​ закрываются в одном​

​With CodeMod​​В работе макрос​​ а из среды​
​:​Private Sub Кнопка0_Click()​
​ "diap" app.Quit Set​' иначе будет​
​Workbooks.Close​ Else 'ничего не​
​: Кто тебя учил​
​ правильно) только вы​Напомните, плиззз, команды​
​ Все книги, которые​ потом перейти в​
​ End SubКнига3 должна​ код для закрытия​
​ макросе, например так​
​lLineNum = .CreateEventProc("Change",​
​ переносит модуль процедуры​

​ разработки не работает.​​Казанский​​ FullFilePath = «C:папка7​​ app = Nothing​ запрашивать подтверждения сохранения,​End Sub​ делаем End If​​ выгружать (unload) форму​ спрашивали о сохранении​ в VBA для​
​ стоят в очереди​ Книгу2, после чего​ оставаться для выбора​
​ всех книг, записанных​ :​

​ «Worksheet»)​​ события на новый​​oldpasp​​, спасибо) Действительно глупость.​
​ свод реестров 2015_9.xlsm»​

excelworld.ru

Как в одном макросе закрыть все книги Excel?

​ DoCmd.SetWarnings False DoCmd.RunSQL​​ при .DisplayAlerts =​KSV​
​ End SubКстати, а​ в кнопке? Не​ формы, а сами​ сохранения и закрытия​ на закрытие после​
​ подать команду о​
​ нового действия.​ в Макросе1, не​Код:​lLineNum = lLineNum​ лист.​: Так как макрос​ Исправила на (oBook.Save).​ Dim app As​ «DELETE Свод_реестров.* FROM​ True)​
​: все правильно​ какие элементы есть​ руби сук, на​ сохраняете активную книгу​
​ userform.​
​ Книги1, теперь не​ закрытии двух книг,​Не всё пока​
​ зависимо от порядка​Sub Макрос1() On​ + 1​При этом почему​ расположен в какой-либо​
​Штурмaн​ Object Dim oBook​ Свод_реестров» DoCmd.TransferSpreadsheet acImport,​Application.Quit​200?’200px’:»+(this.scrollHeight+5)+’px’);»>’ подавляет предупреждения Excel​ на форме?​ котором сидишь! Напиши​
​ ) или нам​Спасибо!​ закроются из-за того,​ то закрываются обе​ получается.​ расположения книг в​ Error Resume Next​.InsertLines lLineNum, «call​ то само открывается​ книге, то выполнив​: Помогите чайнику.Надо закрыть​ As Object Set​ , «Свод_реестров», FullFilePath,​85Muslim85​

​Workbooks.Application.DisplayAlerts = False​​Код может и​ в коде кнопки​ надо было догадаться​Pavel55​ что код уже​ книги!​1. Если перейти​

​ Макросе1. Очевидно в​​ Workbooks(«Книга1»).Close (SaveChanges) Workbooks(«Книга2»).Close​​ Izm(Target)»​​ окно редактора VBA.​
​ команду​ через VBA Excel​ app = CreateObject(«Excel.Application»)​ True, «Свод_реестров» CurrentDb.Execute​
​: все отлично)) спасибки…​
​’ сохраняет книгу​ не сработать, если,​ me.hide — это​ ?)​: А что значит​ не выполняется.​Таким образом в​ с Книги3 в​ Макросе1 необходимо определить​
​ (SaveChanges) On Error​End With​
​ По типу Alt+F11.​Application.Quit получаем запрос​ ,без сохранения и​ Set oBook =​ «DROP TABLE [Свод_реестров_ОшибкиИмпорта]»​ вот чего я​
​ в файл С​ например, фокус на​ переведет тебя в​СердЖиГ​ сохранить? У формы​Код будет срабатывать​ 3-ем сценарии код​ Книгу1, после чего​
​ управляющую книгу, т.​ GoTo 0 End​VBProj.VBE.MainWindow.Visible = False​Подскажите как кодом​ на сохранение​ без​ app.workbooks.Open(FullFilePath) app.Run «diap»​ DoCmd.SetWarnings True MsgBox​ хотел)​ ДРУГИМ именем​ TextBox(e).Только ListBox​
​ команду в вызывающей​: Павел, сорри, уже​ нет такой функции​ всегда, если его​ почемуто не видит​ подать команду о​ е. книгу с​ SubМакрос1 находится в​End Sub​ его закрыть.​А если предварительно​
​выскакивания запросов на​ oBook.Close False app.Quit​ «Импорт успешно завешен»​Workbooks.Application.DisplayAlerts = False​

​Excel.ActiveWorkbook.SaveAs («rl.xlsm»)​​К этой процедуре​ процедуре после show​
​ вечер был :-)​А закрыть можно​ запускать с книги​ Книги2.​ закрытии Книги1, то​ которой поступила команда,​ Книге3. Проэкт состоит​ОлеггелО​Glen​ закрыть книгу без​ сохранеие​ Set app =​ End SubРаньше все​Excel.ActiveWorkbook.Save​’ сохраняет книгу​ надо обратиться с​ — сделай там,​Димит​ так​ в которой он​Mishel915​ закрывается!​ и закрыть её​ из трёх книг​:​: Вроде так помогает​ сохранения​palva​ Nothing DoCmd.SetWarnings False​
​ работало хорошо за​Application.Quit​ в файл С​ фактическим параметром KeyAscii​ что требуется, а​
​: Не получается закрыть​Sub Макрос1()​ размещён.​: Установил причину не​2. Если перейти​ последней.​ — Книга1, Книга2,​Glen​Set VBProj =​Application.ActiveWorkbook.Close 0 то​

​: Закрыть одну из​​ DoCmd.RunSQL «DELETE Свод_реестров.*​
​ исключением следующего: когда​Mary_Rustle​ ТЕМ ЖЕ именем​ — как это​ затем выгружай форму!​ форму при нажатии​’или так​Если код запускать​ срабатывания кода​

CyberForum.ru

VBA сохранить&закрыть userform

​ с Книги3 в​​EducatedFool​

​ Книга3.​, здравствуйте. Я так​ ActiveWorkbook.VBProject​ работа макроса прекращается​

​ книг, если макрос​

​ FROM Свод_реестров» DoCmd.TransferSpreadsheet​​ уже после успешного​: Добрый день!​Excel.ActiveWorkbook.Save​

​ — ПРОШУ ПРОЩЕНИЯJohny​Димит​

​ ESC!!​
​Unload UserForm1 ‘закрыть​
​ с других книг,​Sub test() Dim​ Книгу1, потом перейти​
​: Sub test() Dim​
​Если команда о​
​ делал (топорно конечно),​

​VBProj.VBE.MainWindow.Visible = False​ (книга то закрывается)​ находится в другой,​
​ acImport, , «Свод_реестров»,​ выполнения модуля я​Мои попытки найти​’ закрывает книгу​

​ Walkerу​​: Не хочу размещать​Помогите!!​
​ и выгрузить из​
​ то на его​
​ wb As Workbook​
​ в Книгу2, после​

​ wb As Workbook​​ закрытии книг поступает​ добавьте перед «End​Glen​Значит надо объединить​ можно так:​ FullFilePath, True, «Свод_реестров»​ пыталась открыть файл​ нужное не увенчались​

​Workbooks.Close​​Почему нельзя Unload​ кнопки на форме​

planetaexcel.ru

VBA Excel закрытие формы на листе

​flower2005​​ памяти форму​ работу будет влиять​ For Each wb​
​ чего подать команду​

​ For Each wb​​ из Книги2, например​ sub»​: Код не покажу.​ эти команды: можно​Код Application.DisplayAlerts =​
​ CurrentDb.Execute «DROP TABLE​ эксель, мне выдавалось​ успехом, помогите пожалуйста!​’ закрыть с​

​ в кнопке?​​ — как и​: Разместите на форме​’или так​
​ порядок размещения открытых​ In Workbooks If​ о закрытии двух​ In Workbooks If​ так :​

​SendKeys «%{F11}», True ‘делаю​​Не знаю как​ сделать dll (AddIn),​ False Windows(‘Книга2’).Close Application.DisplayAlerts​ [Свод_реестров_ОшибкиИмпорта]» DoCmd.SetWarnings True​ следующее предупреждение:​Нужно после запуска​ сохранением (без запроса​А куда Я​ где завязать закрытие​ кнопку. Установите её​UserForm1.Hide ‘скрыть форму​ книг в коллекции​ wb.Name <> ThisWorkbook.Name​

​ книг, то закрываются​​ wb.Name <> ThisWorkbook.Name​Код:​ активным окно редактора​ его тут правильно​ где будут выполняться​ = True Закрыть​ MsgBox «Импорт успешно​

​Теперь не понятно​ модуля Эксель через​ подтверждения пользователя, даже​ выйду, если форма​ моей формы на​ свойство Сancel как​End Sub​ Workbooks! Очевидно на​
​ Then wb.Close Next​ обе книги!​ Then wb.Close Next​Application.Run «‘Книга3.xls’!Макрос1″,то закрываются​ VBA​ оформить.​ эти действия​ весь Excel из​ завешен» End Sub​ по какой причине,​ Аксесс полностью закрыть​
​ если .DisplayAlerts =​ vbModeless?​ нажатие Esc (на​ True. Напишите код​
​метод Hide -​ такой случай необходимо​ End Subв 3-ем​3. Если перейти​ ThisWorkbook.Close End Sub​ обе (все в​
​SendKeys «%{F4}», True​Udik​
​Public Sub ExcelQuit(app​ макроса не знаю​Казанский​

CyberForum.ru

​ он стал выдавать​

How to close an Excel workbook using VBA and macros, including how to save the file before you close it or discard any changes.

Sections:

Selecting Which Workbook to Close

Close Workbook While Saving Changes

Close Workbook Without Saving Changes

Let the User Decide to Save Changes or Not

Notes

Selecting Which Workbook to Close

First, we need to tell the macro to choose the current workbook to close or another workbook to close.

Current Workbook

We use this piece of code to close the current or currently active workbook and close that.

Other Workbook

We use this piece of code to close any specific open workbook.

Workbooks("test.xlsx").Close

Replace test.xlsx with the name of the file that you want to close.

Close Workbook While Saving Changes

To have Excel automatically save any changes for the workbook that you want to close, just put True behind the close workbook code from above like this:

ActiveWorkbook.Close True

or, to close a specific file like this:

Workbooks("test.xlsx").Close True

Close Workbook Without Saving Changes

To have an Excel window close WITHOUT saving any changes, just put False behind the close workbook code from above like this:

ActiveWorkbook.Close False

or, to close a specific file like this:

Workbooks("test.xlsx").Close False

Let the User Decide to Save Changes or Not

You use the basic code from the first section and don’t include a True or False after it and a dialog box will open asking if you want to save the file or not; it looks like this:

Close the currently active or visible workbook:

Close a specific workbook:

Workbooks("test.xlsx").Close

Notes

You may run into issues with messages popping up depending on your implementation of this code and your setup and it can help to turn off ScreenUpdating for Excel. Make sure to turn it back on when you are finished though.

If Application.DisplayAlerts is set to False before you close the workbook, you won’t see a popup asking if you want to save it or not before closing it. If this is the case, you may lose data if you wanted to save the file before closing it, so test your code on a sample workbook first.

Download the sample files for this tutorial to test everything out.

Similar Content on TeachExcel

Open Excel Workbook Using VBA Macros

Tutorial:
Simple way to open an Excel workbook using VBA and macros.

Syntax

Workbooks.Open («File…

Macro to get Data from Another Workbook in Excel

Tutorial:
Macro to get data from a workbook, closed or open, over a network or locally on your comp…

Get User Submitted Data from a Prompt in Excel using VBA Macros

Tutorial: How to prompt a user for their input in Excel.
There is a simple way to do this using VBA …

Interactive Clickable Buttons and Interface Without Using VBA/Macros in Excel

Tutorial:
How to make your Excel dashboards and worksheets more interactive and easier to view and …

Loop through a Range of Cells in Excel VBA/Macros

Tutorial: How to use VBA/Macros to iterate through each cell in a range, either a row, a column, or …

Kill Command in Excel (Delete Files Using VBA)

Tutorial:
How to safely remove, delete, kill any Excel file, or other file, using VBA Macros in Exc…

Subscribe for Weekly Tutorials

BONUS: subscribe now to download our Top Tutorials Ebook!

The need to close Excel after running a macro arises all the time especially in large-scale Excel reporting automations where you may be collating data from multiple Excel files.  To learn how to close Excel from within VBA then read on…

Excel has various options within VBA that can be used to close Excel down.  It is important to know exactly what you want to achieve as they all have slightly different results.

For example closing a workbook generally means that the workbook is closed but the Excel application remains open, closing Excel the application will close Excel down and by default that means the workbook will be closed with it.

Sometimes you may need to close down a certain workbook so again that is something to consider in your code.  For example maybe you have a data file that you copy data from and then you just want to close this down and leave the main report open.

Below are the most common scripts for achieving all of these options:

Close everything down, all workbooks and Excel

Application.Quit

This shuts the lot down, all open workbooks and all open Excel programs.   You will need to have saved any changes that you want before this code is completed, Excel will prompt you to save or not unless you have switched alerts off.

Close a certain workbook down

Workbooks(“Name of Workbook”).Close

This will close down a particular workbook.  You do not need to specify the file path as this will generate an error known as run-time error ‘9’, subscript out of range.  Excel will know which of the open workbooks you mean just by the workbook name.

If you have alerts turned off then Excel will just close the file without saving changes but if you want to be more professional with your VBA then add the save settings to the end of the code like so:

Workbooks(“Name of Workbook”).Close SaveChanges:=True

Or

Workbooks(“Name of Workbook”).Close SaveChanges:=False

Close all workbooks but leave Excel open

Workbooks.Close

This will close all the workbooks you have open.  As with the above you will be prompted to save changes, if any have occurred, unless you either have alerts switched off or you have previously saved the file.

Summary

To recap the first thing to do is decide on what you are trying to achieve with closing Excel, do you want everything closed down, just the workbook closed down or just a specific workbook closed down and Excel to remain open.

Always consider your saving options.

Sometimes you may not want to save so you can get around the Excel prompt message asking you to save the workbook by switching alerts off, a more professional approach will set the save criteria in the VBA script and this also helps prevent unwanted results that can occur when you do switch alerts off.

Keep Excelling,

The Headache

I’ve been experiencing issues with longstanding code that opens other Office applications (Excel, PowerPoint, Word) are not managing to close the applications even though the code used to work just fine. This is especially true of PowerPoint! So you end up with hidden processes running in the background and this can lock files and cause all sorts of headaches.

Now, I can’t say why this is now happening, when the .Quit command used to work beautifully, but I had to come up with a way to insure that I didn’t leave such processes, below is my solution.

The Solution

Elegant it is not, but so far the only solution has been to kill the process just as you would do by opening the task manager and killing it there.  The code I came up with to do this is:

Public Declare Function GetWindowThreadProcessId Lib "user32" _
                                                 (ByVal lHWnd As Long, _
                                                  ByRef lProcessId As Long) As Long

'---------------------------------------------------------------------------------------
' Procedure : KillHwndProcess
' Author    : Daniel Pineault, CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Terminate a process based on its Windows Handle (Hwnd)
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
'             (CC BY-SA 4.0) - https://creativecommons.org/licenses/by-sa/4.0/
' Req'd Refs: Uses Late Binding, so none required
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' lHWnd     : Windows Handle number (Hwnd)
'
' Usage:
' ~~~~~~
' Call KillHwndProcess(Application.hWnd)
'
' Revision History:
' Rev       Date(yyyy/mm/dd)        Description
' **************************************************************************************
' 1         2018-09-09              Initial Website Release
'---------------------------------------------------------------------------------------
Public Function KillHwndProcess(lHWnd As Long)
' https://docs.microsoft.com/en-us/windows/desktop/cimwin32prov/win32-process
    On Error GoTo Error_Handler
    Dim oWMI                  As Object
    Dim oProcesses            As Object
    Dim oProcess              As Object
    Dim lProcessId            As Long
    Dim sSQL                  As String
    Const sComputer = "."

    'Retrieve the ProcessId associated with the specified Hwnd
    Call GetWindowThreadProcessId(lHWnd, lProcessId)

    'Iterate through the matching ProcessId processes and terminate
    '   each one.
    Set oWMI = GetObject("winmgmts:\" & sComputer & "rootcimv2")
    sSQL = "SELECT * FROM Win32_Process WHERE ProcessId=" & lProcessId
    Set oProcesses = oWMI.ExecQuery(sSQL)
    For Each oProcess In oProcesses
        oProcess.Terminate
    Next

Error_Handler_Exit:
    On Error Resume Next
    If Not oProcess Is Nothing Then Set oProcess = Nothing
    If Not oProcesses Is Nothing Then Set oProcesses = Nothing
    If Not oWMI Is Nothing Then Set oWMI = Nothing
    Exit Function

Error_Handler:
    MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
           "Error Number: " & Err.Number & vbCrLf & _
           "Error Source: KillHwndProcess" & vbCrLf & _
           "Error Description: " & Err.Description & _
           Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _
           , vbOKOnly + vbCritical, "An Error has Occurred!"
    Resume Error_Handler_Exit
End Function

This code simply requires that you pass it the Handle of the application to forcibly close.

Some Examples

Below are a couple examples of how it can be implemented.

Excel

Public Sub RunXLS()
    Dim oExcel                As Object
    Dim oExcelWrkBk           As Object

    'Start Excel
    On Error Resume Next
    Set oExcel = GetObject(, "Excel.Application")    'Bind to existing instance of Excel
    If Err.Number <> 0 Then    'Could not get instance of Excel, so create a new one
        Err.Clear
        Set oExcel = CreateObject("Excel.Application")
    End If
    On Error GoTo Error_Handler
    oExcel.ScreenUpdating = True
    oExcel.Visible = True   'Keep Excel hidden until we are done with our manipulation
    Set oExcelWrkBk = oExcel.Workbooks.Add()    'Start a new workbook

    '    oExcel.Quit ' Normal, polite way to close Excel, commented out for demonstrative purposes only

    DoEvents
    'Maybe throw in a wait period to give the PC a chance to close the App before forcing it
    Call KillHwndProcess(oExcel.hWnd)

Error_Handler_Exit:
    On Error Resume Next
    oExcel.Visible = True   'Make excel visible to the user
    oExcel.ScreenUpdating = True
    Set oExcelWrkBk = Nothing
    Set oExcel = Nothing
    Exit Sub

Error_Handler:
    MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
           "Error Number: " & Err.Number & vbCrLf & _
           "Error Source: RunXLS" & vbCrLf & _
           "Error Description: " & Err.Description _
           , vbOKOnly + vbCritical, "An Error has Occurred!"
    Resume Error_Handler_Exit
End Sub

Word

Sub RunDoc()
    Dim oWord                 As Object
    Dim oWordDoc              As Object

    'Start Word
    On Error Resume Next
    Set oWord = GetObject("Word.Application")    'Bind to existing instance of Word
    If Err.Number <> 0 Then    'Could not get instance of Word, so create a new one
        Err.Clear
        Set oWord = CreateObject("Word.Application")
    End If
    On Error GoTo Error_Handler
    oWord.Visible = True   'Keep Word hidden until we are done with our manipulation
    Set oWordDoc = oWord.Documents.Add   'Start a new document

    '    oWord.Quit    ' Normal, polite way to close Word, commented out for demonstrative purposes only

    DoEvents
    'Maybe throw in a wait period to give the PC a chance to close the App before forcing it
    Call KillHwndProcess(oWord.ActiveWindow.hWnd)

Error_Handler_Exit:
    On Error Resume Next
    oWord.Visible = True   'Make Word visible to the user
    Set oWordDoc = Nothing
    Set oWord = Nothing
    Exit Sub

Error_Handler:
    MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
           "Error Number: " & Err.Number & vbCrLf & _
           "Error Source: RunDoc" & vbCrLf & _
           "Error Description: " & Err.Description _
           , vbOKOnly + vbCritical, "An Error has Occurred!"
    Resume Error_Handler_Exit
End Sub

Internet Explorer

Function RunIE()
    Dim oIE                   As Object     'SHDocVw.InternetExplorer

    On Error GoTo Error_Handler
    Set oIE = CreateObject("InternetExplorer.Application")

    With oIE
        .Navigate "https://google.com"
        .Visible = True    'True/False
        Do While .Busy Or .ReadyState <> 4: DoEvents: Loop
    End With

    '    oIE.Quit    ' Normal, polite way to close Internet Explorer, commented out for demonstrative purposes only

    DoEvents
    'Maybe throw in a wait period to give the PC a chance to close the App before forcing it
    Call KillHwndProcess(oIE.hWnd)

Error_Handler_Exit:
    On Error Resume Next
    Set oIE = Nothing
    Exit Function

Error_Handler:
    MsgBox "The following error has occurred." & vbCrLf & vbCrLf & _
           "Error Number: " & Err.Number & vbCrLf & _
           "Error Source: RunIE" & vbCrLf & _
           "Error Description: " & Err.Description, _
           vbCritical, "An Error has Occurred!"
    Resume Error_Handler_Exit
End Function

PowerPoint

PowerPoint is a very special case as there appears to be no way to natively get the Handle to use to close the application. So we have to use convoluted code and use the Presentation’s Caption to determine the Handle using APIs and then use it to close the instance.

To determine the Handle from the caption, there is simply no point in reinventing the wheel. Simply use Wayne Phillips’ code, see: https://www.everythingaccess.com/tutorials.asp?ID=Bring-an-external-application-window-to-the-foreground

' Module Name: ModFindWindowLike
' (c) 2005 Wayne Phillips (www.everythingaccess.com)
' https://www.everythingaccess.com/tutorials.asp?ID=Bring-an-external-application-window-to-the-foreground
' Written 02/06/2005
                    
Private Declare Function EnumWindows Lib "user32" _
   (ByVal lpEnumFunc As Long, _
    ByVal lParam As Long) As Long

Private Declare Function GetWindowText Lib "user32" _
    Alias "GetWindowTextA" _
   (ByVal hWnd As Long, _
    ByVal lpString As String, _
    ByVal cch As Long) As Long

'Custom structure for passing in the parameters in/out of the hook enumeration function
'Could use global variables instead, but this is nicer.
Private Type FindWindowParameters
    strTitle As String  'INPUT
    hWnd As Long        'OUTPUT
End Type

Public Function FnFindWindowLike(strWindowTitle As String) As Long
    'We'll pass a custom structure in as the parameter to store our result...
    Dim Parameters As FindWindowParameters
    Parameters.strTitle = strWindowTitle ' Input parameter

    Call EnumWindows(AddressOf EnumWindowProc, VarPtr(Parameters))
    
    FnFindWindowLike = Parameters.hWnd
End Function

Private Function EnumWindowProc(ByVal hWnd As Long, _
                               lParam As FindWindowParameters) As Long
   Dim strWindowTitle As String

   strWindowTitle = Space(260)
   Call GetWindowText(hWnd, strWindowTitle, 260)
   strWindowTitle = TrimNull(strWindowTitle) ' Remove extra null terminator
                                          
   If strWindowTitle Like lParam.strTitle Then
        lParam.hWnd = hWnd 'Store the result for later.
        EnumWindowProc = 0 'This will stop enumerating more windows
   Else
        EnumWindowProc = 1
   End If
End Function

Private Function TrimNull(strNullTerminatedString As String)
    Dim lngPos As Long

    'Remove unnecessary null terminator
    lngPos = InStr(strNullTerminatedString, Chr$(0))
   
    If lngPos Then
        TrimNull = Left$(strNullTerminatedString, lngPos - 1)
    Else
        TrimNull = strNullTerminatedString
    End If
End Function

Now that we have that, we can now continue with our example.

Sub RunPpt()
    Dim oPpt                  As Object
    Dim oPptPres              As Object
    Dim sPptCaption           As String

    'Start Word
    On Error Resume Next
    Set oPpt = GetObject("PowerPoint.Application")    'Bind to existing instance of PowerPoint
    If Err.Number <> 0 Then    'Could not get instance of PowerPoint, so create a new one
        Err.Clear
        Set oPpt = CreateObject("PowerPoint.Application")
    End If
    On Error GoTo Error_Handler
    oPpt.Visible = True   'Keep PowerPoint hidden until we are done with our manipulation
    Set oPptPres = oPpt.Presentations.Add   'Start a new presentation
    '    Set oPptSlide = oPpt.ActivePresentation.Slides.Add(1, 2) 'Add a new slide

    '    oPptPres.Close
    '    oPpt.Quit    ' Normal, polite way to close PowerPoint, commented out for demonstrative purposes only
    ' Does not work with PPT?!

    DoEvents
    'Maybe throw in a wait period to give the PC a chance to close the App before forcing it
    'No way to get the PPT Hwnd so we have to use an API, grrr....  
    '    Thank you Microsoft for standardizing your Office Properties!
    sPptCaption = oPpt.Caption & "*"
    Call KillHwndProcess(FnFindWindowLike(sPptCaption))

Error_Handler_Exit:
    On Error Resume Next
    oPpt.Visible = True   'Make Word visible to the user
    Set oPptPres = Nothing
    Set oPpt = Nothing
    Exit Sub

Error_Handler:
    MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
           "Error Number: " & Err.Number & vbCrLf & _
           "Error Source: RunPpt" & vbCrLf & _
           "Error Description: " & Err.Description _
           , vbOKOnly + vbCritical, "An Error has Occurred!"
    Resume Error_Handler_Exit
End Sub

Now this way of insuring an application is actually shutdown can be added after a standard .Quit call without issue since it will look for the Hwnd, so if it is already closed, it won’t find it, and so it won’t do anything. On the other hand, it the handle remains open, even after you asked it politely to close, then the will forcibly close it.

Warning

As always, we are messing around with computer processes and forcibly terminating them. Be forewarned that this can cause serious problems if not done properly, so be sure to test, test and test some more to insure everything is running smoothly before putting any code into production.

Hopefully, Microsoft will address the underlying issue with applications not closing when the Quit command is issued so that such a workaround isn’t necessary anymore, but until then ….

Понравилась статья? Поделить с друзьями:
  • Vba excel закрыть книгу с сохранением без подтверждения
  • Vba excel закрыть книгу с макросом
  • Vba excel закрыть книгу с именем
  • Vba excel закрыть все открытые книги
  • Vba excel закрыть все окна