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?
Related
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
I have set up a new, empty, modeless userform, to fix my problem with the least amount of code involved.
For when the workbook is opened, the following code is executed to hide Excel and show the userform. It's the only code for the workbook.
Private Sub Workbook_Open()
UserForm1.Show
If Application.Windows.Count <> 1 Then
Application.Windows("test.xlsm").Visible = False
Else
Application.Visible = False
End If
End Sub
I have an empty userform with one single button. The only code for this userform is:
Private Sub CommandButton1_Click()
Application.Windows("test.xlsm").Visible = True
Application.Visible = True
Unload Me
End Sub
The last thing is a button on the first worksheet, to start the same process as when the workbook is opened. Its code:
Sub Button1_Click()
UserForm1.Show
If Application.Windows.Count <> 1 Then
Application.Windows("test.xlsm").Visible = False
Else
Application.Visible = False
End If
End Sub
Now my problem:
When I open the workbook, the userform shows up, but excel and the active window stay visible as well. However, if I click the button on the worksheet, Excel, or the window, are hidden as they should. Also, Excel, not the userform, has focus after loading everything.
The first time I ran this, it worked fine. I suspect changing the ShowModal setting in the editor screwed it up somehow, but that's just me guessing. Anyway, it doesn't work anymore as intended, no matter the modal setting now.
If I just run
Application.Visible = False
instead of the "if"-clause, Excel still stays visible and of course so does the active window.
This is driving me nuts.
What am I missing?
Edit: Link to my test file: Test File on my Dropbox
Might have to start it twice, because when the macros are blocked at startup and only activated after excel has completely loaded, the code works as intended.
Edit: I was able to test this on an excel 2010 pc and there the problem doesn't exist. So it might have something to do with the way newer Office Apps handle stuff.
I found myself having the exact same problem - modeless form opened with Workbook_Open() event that's also supposed to hide excel app (working on Excel 2016, 32bit).
The reason why it's working with UserForm property ShowModal set to True is because: the execution is suspended - it's waiting for user to interact with the UserForm that was shown.
If we change ShowModal to False (or call UserForm.Show vbModeless) then the execution is never suspended and once we reach End Sub of our Workbook_Open(), Excel appears to set Application.Visible = True on its own.
Only solution I've found thus far is this one - basically you suspend the execution by adding an infinite loop so Excel only gets to end of this event once you get rid of (Unload/Hide) the form that was shown previously.
My version looks like this:
Private Sub Workbook_Open()
Dim App As Object
Set App = startMenu
App.Show vbModeless
While App.Visible
DoEvents
Wend
End Sub
Then just to make sure that Excel is closed once that modeless UserForm is closed I've added this:
Private Sub UserForm_Terminate()
CloseApp
End Sub
Public Sub CloseApp()
ThisWorkbook.Saved = True
If Not OtherWorkbooksOpen Then
Application.Quit
Else
ThisWorkbook.Close
End If
End Sub
Public Function OtherWorkbooksOpen()
If Application.Workbooks.Count > 1 Then
OtherWorkbooksOpen = True
Else
OtherWorkbooksOpen = False
End If
End Function
EDIT:
Solution without infinite loop - schedule hiding of Excel:
Private Sub Workbook_Open()
Dim App As Object
Set App = startMenu
App.Show
If Not OtherWorkbooksOpen Then
Application.OnTime Now + TimeValue("00:00:01"), "HideExcel"
End If
End Sub
I think the userform1.show needs to be called after the execution of if statement.
Private Sub Workbook_Open()
If Application.Windows.Count <> 1 Then
Application.Windows("test.xlsm").Visible = False
Else
Application.Visible = False
End If
UserForm1.Show
End Sub
Not an answer, but I can't post this as a comment. This works for me - the user form appears, the application is hidden. I used "<>2" as I have a personal workbook. Can you confirm what happens for you?
Private Sub Workbook_Open()
If Application.Windows.Count <> 2 Then
Application.Windows("test.xlsm").Visible = False
Else
Application.Visible = False
End If
UserForm1.Show False
End Sub
I had the same issue, but I notice the form loads before the excel file. So I put a redundancy calling the application.visible = false, in the form.
Basically after clicking anything in the form, it will call the application.visible = false and the excel window will hide.
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.
I have spreadsheet which uses events upon opening, therefore anytime I try to close the file, the save changes dialog box appears.
Is there a way to prevent this?
You can add a function in VBA to ThisWorkbook to let Excel think that the file has been saved. This will prevent any save prompts.
If you don't want to save your workbook:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Me.Saved = True
End Sub
If you want to save your workbook:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Me.Save
End Sub
Here documentation for deleting work sheet.
So, you need to use as follow:
'Stopping Application Alerts
Application.DisplayAlerts=FALSE
'~~~~~~deleting sheet~~~~~
'Enabling Application alerts once we are done with our task
Application.DisplayAlerts=TRUE
Private Sub Workbook_BeforeClose(Cancel As Boolean)
ThisWorkbook.Close SaveChanges:=False
End Sub
This may sound silly but I'm trying to prevent saving in Excel Workbook by using the code below in ThisWorkbook:
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Cancel = True
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Application.ThisWorkbook.Saved = True
End Sub
However, after pressing Ctrl + s, and close the workbook, when reopening it, the code wasn't saved.
Any idea why this happen ?
This is a good thing - it means your code is working right. Your code prevented you from saving the workbook yourself. I have this in a couple applications I have made, the way around it is to make a sub as follows:
sub saveTheWB()
Application.EnableEvents = False
ThisWorkbook.Save
Application.EnableEvents = True
end sub
You have to run this sub every time you want to save.
That's right because the Workbook_BeforeSave event handler is firing and cancelling the save operation.
In the Immediate window of The IDE, run Application.EnableEvents = False before saving your workbook and it will save with the code.
Don't forget to run Application.EnableEvents = True after!