Why does Macro Enabled Excel Workbook kill UserForm in another Macro Enabled Excel Workbook when closed? - vba

Scenario:
User is running a macro-enabled Excel Workbook. User clicks a link on a UserForm that launches another macro-enabled Excel Workbook that also has user forms. The second Workbook is then closed using the following code:
Private Sub btnExit_Click()
'Check if other Excel files are open before quitting the application
If Workbooks.Count = 1 Then
Application.Quit
Else
ThisWorkbook.Close
End If
End Sub
and...
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Dim intResponse As Integer
If MsgBox("Are you sure you would like to exit the calculator?", vbYesNo + vbQuestion) = vbNo Then
Cancel = True
End If
ThisWorkbook.Saved = True
End Sub
Upon closing of the second Workbook (ThisWorkbook.Close), the original Workbook remains open, however, the vbModeless UserForm that was previously visible has been killed. It might also be pertinent to mention that the second Workbook's forms are Modal.
If the second Workbook is closed using the Excel exit button in the upper right corner, this problem does not occur.
Does anyone know why this is happening? Is it because code execution for Excel.Application is ceased when the Workbook is closed programmatically? Could it be due to the difference in form modes? Is there a work-around other than putting a button on the original Workbook in a Sheet to re-launch the UserForm?
Many thanks for any assistance with this issue!!
CiViCChiC79

This is what is happening:
Assuming that both workbooks are in the same Excel Application, Application.Quit would close them both.
ThisWorkbook.Close will close the workbook, in which the code is present.
Thus, concerning your question - you are not closing the second workbook with ThisWorkbook.Close, but you are closing the workbook, which has the btnExit button, on which you have clicked. I guess that both the workbooks are quite similar and you are mistaken which one you are closing?

Changing the second Workbook's form containing the Exit button to vbModeless fixed the problem!!!! Yay!!!!!

Related

Closing Workbook after opening it through VBA - Excel

I have the code below. I've called the excel document from a VBA code. However, after pressing the closing button on the workbook, it doesn't close until I stop the macro. I want to be able to close the document without stopping the macro. i.e. the main userform is still running behind. I can close the excel workbook from the close button top right of the workbook itself.
Anyone happen to know how to solve this?
Private Sub CommandButton7_Click()
Workbooks("master system.xlsm").Activate
Workbooks.Open ActiveWorkbook.Path & "\Toolbox\Define\PPST.xlsx"
End Sub
Try Workbooks("PPST.xlsx").Close SaveChanges:=True
This is from the documentation enter link description here
Try scattering DoEvents throughout your code after opening the workbook.
Just be aware that if you depend on the ActiveWorkbook or Selection objects in your code, they could change after DoEvents.
DoEvents essentially tells your code to pause, and let Excel do other, waiting tasks -- such as allowing the user to select cells, and probably closing a workbook -- before continuing.

How to make vba code to run auto-close only on active workbook?

Here's the scenario. I have multiple excel workbooks that copy and paste data among each other. So the macro works to open.copy.close from one workbook then open.paste.close to another. I am working on creating a function to auto run macro when file is closed.
Here's the issue, when I click macro button in workbook 1, it is supposed to open.copy.close from workbook 2. However, because of the auto run when file is closed function in workbook 2, an error will occur (2 macros cannot run at the same time)Any solution for this? I am looking for a solution to only auto run macro when file is closed IF IT IS AN ACTIVE WORKBOOK. Here is what I have now:
Workbook 1
Sub workbook_beforeclose(cancel As Boolean)
Application.Run "Sheet1.UpdateYellowTabs_Click"
End Sub
Workbook 2
Sub Workbook_BeforeClose(Cancel As Boolean)
Workbook.BeforeClose
Application.Run "Sheet12.UpdateGreen_Click"
End Sub
How do I code it in the workbook code to only make this run only when it's active/closed by a human user and not when open/close by macro?
Thanks!
Well I am not sure to understand your final goal from this, but I can answer the "technical" question. Technically, if you want to check if a given workbook is active: If Application.ActiveWorkbook Is Me,
Private Sub Workbook_BeforeClose(Cancel As Boolean)
If Not Application.ActiveWorkbook Is Me Then Exit Sub ' <-- add this test
''''''''''''''''''''''''''
' Whatever code goes here
''''''''''''''''''''''''''
End Sub
EDIT
But problem is that invoking wb2.close will make the workbook wb2 the "active" one during the execution of the macro. So this method won't work. Another method is to disable events before closing the workbook; so that the event Workbook_BeforeClose will not fire. After that, you can enable events back if needed. The code looks like this:
' ... open wb2 and do the work with it
Application.EnableEvents = False
wb2.Close False
Application.EnableEvents = True
notice, if you had already disabled events at the beginning of the current macro, which is usually recommended, then this additional code wouldn't be needed.

Cannot close workbook after running sub with userform

I have a macro that opens a userform to capture a start and end date. After clicking OK on the userform, a file dialog box opens to select an Excel Workbook to open.
Immediately after I run the below sub, I can't close the workbook that is opened by using the 'X' in the top-right corner. I also can't save the workbook by clicking the save icon.
However, if I click on another workbook or switch to a different sheet in the workbook that was opened, and then click back to the one opened by the sub everything works as it's supposed to.
Also, I replace the userform with two input boxes, to capture each of the two dates, I am able to close the workbook that is opened with no issue.
Maybe there's something funny with the userform code?
This is all that is in the userform.
Private Sub Ok_button_Click()
call module1.forecast
unload userform1
end Sub
And this is the main sub.
Sub forecast()
dim start_SFY as long
dim end_SFY as long
dim filesToOpen as object
dim wb as workbook
Application.ScreenUpdating= False
start_SFY = userform1.textbox1.value
end_SFY = userform1.textbox2.value
set filesToOpen = application.fileDialog(msoFileDialogOpen)
filesToOpen.show
set wb = application.workbooks.open(filesToOpen.selecteditems(1),false)
Application.ScreenUpdating= True
End Sub
Here's the sub showing userform1
Sub run_userform()
userform1.show
End Sub
Also, here is the Excel version:
Excel 2013 64-bit (15.04753.1003) Part of Microsoft Office 365 ProPlus
Can someone maybe try to replicate the issue that I'm having? I'm wondering if this is an issue related to my employer's version of Excel or something?
This sort of thing has never happened to me before.
Also, I can close the program with VBA. It's just when trying to click the 'X' that it won't close.
Update:
I was able to get the code, with no changes, to work fine at home on Excel 2016. I'm going to get a coworker to test on their system today.
When I was home, I didn't put a button to call the sub on a worksheet. I called it from the VBA editor. After some testing this morning, it seems that the button is the issue. If I call the sub from the VBA editor, I can close the opened workbook. However, if I use a command button (form control, not ActiveX as I get an error saying, "Cannot draw object" whenever I try to add any kind of ActiveX object to a worksheet) the opened workbook will not close.
I think I have found the problem
This issue seems to be with the 'form control command button'. ActiveX was disabled in the Trust Center. When I enabled it and created a command button, I was able to close the opened workbook. I then tried the command form button again, and could not close the opened workbook. I was also successfully able to close the opened workbook when I ran the sub from the sub listbox in the developer tab, and when I place the sub in the Excel Ribbon and ran it from there.
Any idea as to why the control form command button would cause this issue?
The root of the problem is the change to using multiple excel interfaces in 2013. Microsoft addresses the issue in the Solutions for SDI Issues section of this page.
A workbook cannot be closed by clicking the red "X" Close button when
that workbook is programmatically opened via a modal user form. To
work around this issue, it is suggested that you add the following
code to the user form Layout event procedure and then open the user
form as modeless
Private Sub UserForm_Layout()
Static fSetModal As Boolean
If fSetModal = False Then
fSetModal = True
Me.Hide
Me.Show 1
End If
End Sub
Another option is to open the workbook window, activate any other
window, and then reactivate the workbook window. You should now be
able to close the workbook using the Close button.
So these are the two options they present and one I came up with.
Option 1) You can switch your dialog to modeless using their code, or by setting the ShowModel property to false in your userform.
Option 2) As you discovered, manually switching between workbooks after opening via modal userform resyncs everything. Not a good solution for the users of my code, and I don't recommend relying on it.
Option 3) It's worth mentioning, if you don't open the file via the userform then there's no issue. So if last thing the userform needs to do is open the file, you can easily save the file path in a string, unload the troublesome userform and move the workbooks.open call after closing. Here's an example of what I mean
Public EDIT_FILE_DIRECTORY As String
Public Sub Main()
fileOpenerForm.Show
If EDIT_FILE_DIRECTORY <> "" Then
Call Workbooks.Open(EDIT_FILE_DIRECTORY)
End If
End Sub
And in the userform something along these lines, where the filename is created based on userform parameters and a listbox selection:
Private Sub OpenSelectedWorkbooks_Button_Click()
Dim workbookName As String
workbookName = selectionList.Item(Me.FileSelection_ListBox.ListIndex + 1)
EDIT_FILE_DIRECTORY = ROOT_DIR & GetSelectedSubfolder & "\" & workbookName
Unload Me
End Sub
Try fileOpenerForm Show 0 to open open it with Modal = False (Makes the macro run while the Userform is visible)
Do not forget to add fileOpenerForm.Hide later on.
Also Load fileOpenerForm and Unload fileOpenerForm may be useful

unable to close opened excel workbook

I am building a excel file with commandbuttons, userforms etc. that contain links to other workbooks.
For the commandbuttons on my sheet I use the same code as for the commandbuttons in my userforms:
workbooks.open "path"
with the userform commandbuttons ater this the following is added
unload me
When I open a workbook via a userform I am unable to close it afterwards. I must activate my workbook first, then activate the opened one and then can I close it
I have tried putting "unload me" befor and after the "workbooks.open" but this doesn't change anything.
I also tried the followin, also didn't work:
unload me
dim wb as workbook
set wb = workbooks.open"pathname"
wb.activate
anyone any ideas?
Example of how it is now:
Someone needs to make a price calculation. they open the prices userform in my file. they click on the button "calculationfile". The calculationfile opens. they make there calculation and now they are finished in the calculationfile. So they want to close it by clicking on the cross. But they can't click the cross. then they switch to my file on the taskbar and then switch back to the calculation file. now they are able of clicking the cross
I dont understand why they can't click it the first time but they can click it after switching between mine and the openend workbook.
I suspect this is due to improper form handling and the "default instance" recreating itself after you unload it. If you don't create your own instance of the form before you show it, VBA will do all kinds of squirrelly things when you use it after it's unloaded.
If all you need to do is open a workbook and unload the form, *don't increment the workbook's reference count before you unload the form. Also, don't attempt to run any other code after you call Unload Me from the form. The code you posted should simply be:
Workbooks.Open "pathname"
Unload Me
Of course the calling code for the form isn't in the question, but it can likely be solved there as well.
Unload only affects a UserForm.
Try adding a reference to the open workbook and then closing it like so:
dim wb as Workbook
set wb = Workbooks.Open "pathname"
wb.activate
' do whatever with it while it's open
wb.Close
If whatever you are doing is not automated, you will need a button on your form that will set the reference to the workbook and close it once the user has completed editing.
If you define the workbooks that you open as a variable - you will be able to close them easily. Keep in mind this does not save the workbook.
Dim DataBook As Workbook
Set DataBook = Workbooks.open ("pathname")
' Do something useful with the file
DataBook.Close
It is not completely clear what you are trying to ask here, but I'll give it my best in providing you a full answer. If you are having no success with the Unload Me statement when it comes to closing a user form, try specifying the full form name in VBA. That is:
Unload UserFormName
If you are trying to close the workbook you have opened (via the user form), you can use the Workbooks.Close method:
Dim wb as Workbook
Set wb = Workbooks.Open(Filename:="C:\example.xls")
wb.Activate
'Close workbook
wb.Close
'Unload form
Unload ExampleForm
More on the use of the Unload statement can be found here:- https://msdn.microsoft.com/en-us/library/aa445829(v=vs.60).aspx
And more on the use of the Workbooks.Close statement can be found here:- https://msdn.microsoft.com/en-us/library/office/ff838613.aspx
I'm not sure what's causing the behavior you describe (inability to click the "Close" X button in the active Excel window). However your current workflow is:
User interacts with form to review/access a file
User clicks a button on the form which unloads the form
User is then expected to manually close out of the file opened in (1)
A better solution would be to remove the third step, and close the workbook from one of the form's event-handlers (UserForm_QueryClose or UserForm_Terminate). Alternatively you could add this to a CommandButton's Click event, but that's not very different than requiring the user to manually close the file.
This could be as simple as:
Private Sub UserForm_Terminate()
' should be called when form Unloads
On Error Resume Next
Workbooks.Close "filename.xlsx"
End Sub
In this manner, the file will be closed any time the user closes or otherwise unloads the userform.
OK I think I found a way around it.
Let's say I have a workbook1 which has a form called ControlPage with command button that opens up workbook2.
Private Sub CommandButton1_Click()
Dim workbook2 As Workbook
Dim workbook1name As String
workbook1name = ThisWorkbook.name
Set workbook2 = Workbooks.Open("workbook2.xlsx")
ControlPage.Hide
Workbooks(workbook1name).Activate
Workbooks("workbook2.xlsx").Activate
End Sub
So basically because 'activate' bit doesn't seem to work properly when I try to activate workbook 2 straight away, I just activate the first, and then the second one ane after another. Twisted but did the trick for me.

How do I disable and enable macros on the fly?

I would like to test an Excel VBA app I made.
However the VBA code messes around with the visibility of cells and that's a pest when editing the sheet.
Is there an option is enable and disable macro's on the fly without having to
Close the sheet
Change the macro settings
Reopen the sheet
Close the sheet
Change the macro settings.
etc.
As far as I know, you can't enable / disable macros from an opened workbook on the fly.
Yet, you shouldn't have to because macros are only triggered thanks to a user click.
The only case I would see is for the Event Procedures (Worksheet_Change or else).
You could then create procedures to activate / deactivate events and call them from buttons in your worksbook:
Sub enableEvents()
Application.EnableEvents = True
End Sub
Sub disableEvents()
Application.EnableEvents = False
End Sub
You can also try these tips from Chris Pearson website using global vars you would change depending on your needs:
Public AbortChangeEvent As Boolean
And check if afterwards:
Private Sub Worksheet_Change(ByVal Target As Range)
If AbortChangeEvent = True Then
Exit Sub
End If
'
' rest of code here
'
End Sub
To disable macros on the fly, use "Application.EnableEvents = False" via the Immediate window in the VBA editor (and "Application.EnableEvents = True" to turn them back on).
You can also hold down SHIFT when you open a document to disable macros.
As of Excel 2010* there's actually an option on the "Developer" tab which allows you to disable macros as easy as ABC. Design Mode lets you do just that!
*Maybe even earlier versions.
I often fire Macros when opening a workbook but sometimes I don't want the Macro to fire so I can work on the code. So what I put a Macro in a separate workbook that does the following:
Disables macros
Opens the workbook in question
Enables macros
Then closes the original workbook
Leaves the second workbook open
Here's the code:
Sub OpenClose()
'Opens Workbook below with Macors disabled
'After it is open Macros are enabled
'This Workbook then closes without saving changes, leaving only the workbook below open
'************************************************************
'User only needs to change the workbook name on the next line
WorkbookToOpenNoMacros = "Gaby.xlsm"
'************************************************************
Dim wb As Workbook
Set wb = Application.ThisWorkbook
Application.EnableEvents = False
Application.Workbooks.Open (ActiveWorkbook.Path & "\" & WorkbookToOpenNoMacros)
Application.EnableEvents = True
wb.Saved = True
wb.Close SaveChanges:=False
End Sub
I have Office 2013 and I found a button on the VBA window that did this for me very easily.
There's a play, pause and stop button on the toolbar. In Excel, they are actually called, Run Macro, Break and Reset.
Click the Break button (pause) and any running macros should stop running. I only tested it on one macro but seems reasonable to presume that this will work in general.
Also, I believe those buttons were there for many versions of Excel, so it's worth checking earlier versions.