how to check if workbook is closing in deactivate event - vba

SOLVED
Is there any way to check if workbook is closing when the code is in workbook_deactivate procedure? so i can inform a different message to users depending on whether they are just leaving to another workbook or they are closing the file. like following
Private Sub Workbook_Deactivate()
if thisworkbook.closing then
msgbox "message1"
else
msgbox "message2"
end if
End Sub
i've searched on the net but no solution at all.
so any help would be appreciated
SOLUTION
i've thought of a trick. i'm putting the value 1 in Z1000(if it is available) in before_close event and in deactivate, i'm checking if Z1000's value. that's it.
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Range("Z1000").Value = 1 'wherever is avaliable
Me.Saved = True
End Sub
Private Sub Workbook_Deactivate()
If Range("Z1000").Value = 1 Then
MsgBox "quitting"
Else
MsgBox "deactivating"
End If
End Sub

You can detect that using the BeforeClose Event
Private Sub Workbook_BeforeClose(Cancel As Boolean)
' set Cancel to true to prevent it from closing
End Sub

Related

How do you prevent repeated MsgBox firing in the Form_Delete event?

I have a datasheet form which is making it easy for users to select all records and delete. I thought of writing a VBA code that prevents users from deleting the records if more than 20 records are selected. Then I wrote this code but the problem is that the message fires for every record. Has someone ever come across this? Please see below.
Private Sub Form_Delete(Cancel As Integer)
If Me.SelHeight > 20 Then
Cancel = True
MsgBox ("Bulk deletion is not allowed!")
End If
End Sub
If you get confused about BeforeDelConfirm event not fired, like I got, check if theConfirm Record ChangesOption is set. If not, event is not raised.
UsingBeforeDelConfirmandAfterDelConfirm, this task is a lot simpler.
On top of form module
Option Explicit
Dim deleteCount As Long
Private Const MaxDeleteRows As Long = 20 ' set this constant to the number of rows that can be deleted at once
event code:
Private Sub Form_AfterDelConfirm(Status As Integer)
If deleteCount > MaxDeleteRows Then
MsgBox ("Bulk deletion is not allowed!")
End If
deleteCount = 0
End Sub
Private Sub Form_BeforeDelConfirm(Cancel As Integer, Response As Integer)
If deleteCount > MaxDeleteRows Then
Cancel = True
End If
Response = acDataErrContinue
End Sub
Private Sub Form_Delete(Cancel As Integer)
If deleteCount = 0 Then
deleteCount = Me.SelHeight
End If
End Sub
Private Sub Form_Deactivate()
' Application.SetOption "Confirm Record Changes", False ' needed if you want to have Confirm Record Changes off elsewhere
End Sub
Private Sub Form_Activate()
' Application.SetOption "Confirm Record Changes", True ' needed if you want to have Confirm Record Changes off elsewhere (turns it on here)
End Sub

Workbook_BeforeClose does not work

What I understand from this "Workbook_BeforeClose" is that a command should work after when click "X" to close Excel.
My code is;
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Sheets("Makro").Range("A2") = 0
End Sub
When I reopen this excel workbook, I want to see that Range "A2" is zero ("0"). But I reopen the excel, it is not zero. I cannot understand.
I wonder if I misunderstood this vba code.
If you help me about this, I would be appreciate you.
Try it as,
Option Explicit
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Me.Worksheets("Makro").Range("A2") = 0
Me.Save
End Sub
If you don't want it saved then change it to,
Option Explicit
Private Sub Workbook_Open()
Me.Worksheets("Makro").Range("A2") = 0
End Sub
Private Sub Auto_Open()
Sheets("Makro").Range("A2") = 0
End Sub
or
Private Sub Auto_Close()
Sheets("Makro").Range("A2") = 0
End Sub
codes solved my problem.
Thank you.
You can try this method:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
With Sheets("Sheet1").Range("a2")
.Value = "ABC"
End With
End Sub
Found this question trying to fix my issue, turns out their code was correct.
There's no need for Option Explicit or a Save
Just make sure you have the
Private Sub Workbook_BeforeClose(Cancel As Boolean)
in the ThisWorkbook Window. It won't work if it's in one of the sheets or modules.

Close workbook with Userform

I have made a User form in Excel, so when i open the xlsm-file it only opens the user form, and the workbook is hidden.
But when i close the user form with the [X]-button I want it to close both the workbook and the user form without saving.
When I close the user form now, and try to open the same file again, it says that it is already/stil open.
Start up code:
Private Sub Workbook_Open()
Application.Visible = False
Fordelinger.Show vbModeless
End Sub
Close code:
Private Sub Fordelinger_Deactivate()
Application.Quit
Workbooks("EstimatDOK.xlsm").Close True
End Sub
Can anyone help? :)
may be you wanted this code in the UserForm code pane
Private Sub UserForm_Terminate()
ThisWorkbook.Close
End Sub
you can use the below code to restrict close (X) button
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = 0 Then
Cancel = True
MsgBox "The X is disabled, please use a button on the form to Exit.", vbCritical
End If
End Sub
or
Private Sub UserForm_Terminate()
ThisWorkbook.Close savechanges:=False
Application.Quit
End Sub

Determine which command button was clicked to open userform

I have two command buttons (cmd1 and cmd2) on userform1, when clicked each show the same userform (userform2). Within the initialize or load sub is it possible to determine which command button was clicked on userform1 and therefore show the form differently? I imagine the code in either the initialize or load sub on userform2 to have the following skeleton:
if (cmd1 was clicked)
' do stuff relating to 1
elseif (cmd2 was clicked)
' do stuff relating to 2
else
' error handling
End if
The respective "stuff" could be moved into the event handler for cmd1 and cmd2 however, if the method described above can be used it will be a lot simpler and cleaner.
Use a Public Variable in UserForm1 and then test it in UserForm2_Initialize Event.
Something like this in UserForm1:
Public whatsclicked As String
Private Sub CommandButton1_Click()
whatsclicked = "CommandButton1"
UserForm2.Show
End Sub
Private Sub CommandButton2_Click()
whatsclicked = "CommandButton2"
UserForm2.Show
End Sub
And then in UserForm2:
Private Sub UserForm_Initialize()
Select Case UserForm1.whatsclicked
Case "CommandButton1": MsgBox "CommandButton1 loaded form."
Case "CommandButton2": MsgBox "CommandButton2 loaded form."
Case Else 'Do something else
End Select
End Sub
you can do it also without public variable.
i won't show an example where you can simply write something in a cell or hidden sheet, instead i just pass the wanted info directly .
this time whatsclicked is the name of a label in userform2,
in userform1, before calling userform2:
Private Sub CommandButton1_Click()
load UserForm2
with UserForm2
.whatsclicked.caption= "CommandButton1"
.Show
end with
End Sub
Private Sub CommandButton2_Click()
load UserForm2
with UserForm2
.whatsclicked.caption= "CommandButton2"
.Show
end with
End Sub
Of course, you will have to hide the text of whatsclicked to the user (same color as font or background...)
You can use ActiveControl for this as when you click a control it becomes active/focussed:
Private Sub CommandButton1_Click()
Debug.Print Me.ActiveControl.Name
End Sub
Private Sub CommandButton2_Click()
Debug.Print Me.ActiveControl.Name
End Sub
So more in line with your example:
Private Sub CommandButton1_Click()
Call DoStuff
End Sub
Private Sub CommandButton2_Click()
Call DoStuff
End Sub
Private Sub DoStuff()
select case Me.ActiveControl.Name
case "CommandButton1"
' do stuff relating to 1
case "CommandButton2"
' do stuff relating to 2
case else
'error etc.
end select
End Sub

Access/VBA: "Run-time error 2169. You can't save this record at this time"

Using: Access 2013 with ADO connection to SQL Server back-end database
A form in my Access database is dynamically bound at runtime to the results of a SELECT stored-procedure from SQL Server, and allows the user to make changes to the record.
It has 2 buttons: Save and Cancel.
It is shown as a pop-up, modal, dialog form, and it has a (Windows) Close button at the top right corner.
I've put VBA code to ask the user whether he wants to Save, Ignore or Cancel the close action.
But there are problems and it gives the aforementioned error if Cancel is clicked. There are also other problems, like, after the error occurs once, then any further commands (Save or Cancel or closing the form) don't work - I think this is because the VBA interpreter has halted due to the earlier error. Another complication is that arises - I now need to end the MS-Access process from Windows Task Manager, doing this and then restarting the database and then opening this form will give an error and the form won't load. When the form is then opened in Design mode, I can see the connection string for the form is saved in the Form's Record Source property (this happens only sometimes), and which looks something like this:
{ ? = call dbo.tbBeneficiary_S(?) }.
Here is my code:
Dim CancelCloseFlag As Boolean
Dim SavePrompt As Boolean
Private Sub Form_BeforeUpdate(Cancel As Integer)
Dim a As Integer
If SavePrompt Then
a = MsgBox("Do you want to save changes?", vbQuestion + vbYesNoCancel, "Changes made")
Select Case a
Case vbNo:
Me.Undo
CancelCloseFlag = False
Case vbYes:
'do nothing; it will save the changes
CancelCloseFlag = False
Case vbCancel:
Cancel = True
CancelCloseFlag = True
End Select
End If
End Sub
Private Sub Form_Dirty(Cancel As Integer)
SavePrompt = True
End Sub
Private Sub Form_Error(DataErr As Integer, Response As Integer)
If DataErr = 2169 Then
Response = acDataErrContinue
End If
End Sub
Private Sub Form_Load()
LoadBeneficiaryDetails
End Sub
Private Sub Form_Unload(Cancel As Integer)
If CancelCloseFlag Then
Cancel = True
End If
End Sub
Private Sub btCancel_Click()
If Me.Dirty Then
SavePrompt = True
End If
DoCmd.Close
End Sub
Private Sub btSave_Click()
SavePrompt = False
DoCmd.Close
End Sub
I'm stuck and would like to know how others go about this issue? Basically I want to offer the user the choice Save, Ignore, Cancel when the user attempts to close the form with either Cancel button or the (Windows) close button. If the user chooses Cancel, then it should just return to the form without changing or undoing any changes to the data. The solution may be simple but it escapes my overworked mind.
Thanks in advance!
Please try the following code - I tested against all six scenarios and the proper action is taken.
Option Compare Database
Option Explicit
Dim blnAction As Integer
Dim blnBeenThereDoneThat As Boolean
Private Sub Form_BeforeUpdate(Cancel As Integer)
If blnBeenThereDoneThat = True Then Exit Sub
blnBeenThereDoneThat = True
blnAction = MsgBox("Do you want to save changes?", vbQuestion + vbYesNoCancel, "Changes made")
Select Case blnAction
Case vbNo:
Me.Undo
Case vbYes:
'do nothing; it will save the changes
Case vbCancel:
Cancel = True
End Select
End Sub
Private Sub Form_Error(DataErr As Integer, Response As Integer)
If DataErr = 2169 Then
Response = acDataErrContinue
End If
End Sub
Private Sub Form_Load()
LoadBeneficiaryDetails
End Sub
Private Sub Form_Unload(Cancel As Integer)
If blnAction = vbCancel Then
blnBeenThereDoneThat = False
Cancel = True
End If
End Sub
Private Sub btCancel_Click()
If Me.Dirty Then
Form_BeforeUpdate (0)
End If
If blnAction = vbCancel Then
blnBeenThereDoneThat = False
Exit Sub
ElseIf blnAction = vbYes Then
DoCmd.Close
Else
DoCmd.Close
End If
End Sub
Private Sub btSave_Click()
If Me.Dirty Then
Form_BeforeUpdate (0)
End If
If blnAction = vbCancel Then
Exit Sub
Else
DoCmd.Close
End If
End Sub