Command Still Executes Despite Cancel Button - excel

I have a button the executes a user form to display with a required password before executing the buttons command, however when the user form is displaying it freezes the rest of the sheet. On the user Form a I created a cancel button so that the user can exit out of the UserForm should he not know the password and use the other buttons I have on the sheet. When the user clicks the cancel button, it still executes the command even though he/she did not put a password in. The user Form works properly when you enter the correct password/incorrect password, its only when you click cancel that it does not work. Could any on please offer any help? see my code below for the button and the code for my cancel button
Sub Feeder_Schedule()
UserForm1.Show
If Sheets("Bulk_Data").Visible = xlVeryHidden Then
Sheets("Bulk_Data").Visible = True
End If
Sheets("Bulk_Data").Select
Sheets("Home").Visible = xlVeryHidden
End Sub
code for the Cancel button
Private Sub CommandButton1_Click()
Unload Me
End Sub

If you want to make it right change/add to your code of the userform
Option Explicit
' USERFORM CODE
Private m_Cancelled As Boolean
' Returns the cancelled value to the calling procedure
Public Property Get Cancelled() As Variant
Cancelled = m_Cancelled
End Property
Private Sub buttonCancel_Click()
' Hide the Userform and set cancelled to true
Hide
m_Cancelled = True
End Sub
' Handle user clicking on the X button
Private Sub UserForm_QueryClose(Cancel As Integer _
, CloseMode As Integer)
' Prevent the form being unloaded
If CloseMode = vbFormControlMenu Then Cancel = True
' Hide the Userform and set cancelled to true
Hide
m_Cancelled = True
End Sub
Your code could then look like that
Sub Feeder_Schedule()
Dim frm As UserForm1
Set frm = New UserForm1
frm.Show
If Not frm.Cancelled Then
If Sheets("Bulk_Data").Visible = xlVeryHidden Then
Sheets("Bulk_Data").Visible = True
End If
Sheets("Bulk_Data").Select
Sheets("Home").Visible = xlVeryHidden
End If
End Sub

Related

How to pass variable from Form to Workbook VBA

I want to keep a variable from Form to Workbook Events, it works from Form to Module, but doesn't work from Form to Workbook Event, the Variable "Salvar" stay as "Empty" rather than "True"...
'WorkBook Event
Public Salvar As Boolean
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
UserForm_Salvar.Show 'Calls "Private Sub Botao_Salvar_Click()"
If SaveAsUI = True Then
If Salvar = True Then
Cancel = False
Salvar = False
Else
Cancel = True
End If
End If
End Sub
'UserForm
Private Sub Botao_Salvar_Click()
Dim PassWord As Variant
PassWord = Senha_TextBox
If PassWord = 123 Then
Unload UserForm_Salvar
Salvar = True
End If
End Sub 'Go back to "Workbook_BeforeSave"
You don't really need a global variable if you declare the form as an object, which is the better practice anyway, and then handle it correctly. Use any of the form's properties or the form's controls' properties to convey the message. I recommend to use the Tag property. Here is the code in the worksheet's module. Observe that I named the form FrmSalvar.
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
' 091
Dim Form As FrmSalvar
If SaveAsUI = True Then
Set Form = New FrmSalvar ' create a new instance of the form
With Form
.Show ' the Form takes control
' code resumes here with Form hidden but still in memory
Cancel = (Val(.Tag) <> True) ' True = -1
End With
Unload Form ' only now the form is destroyed
Set Form = Nothing
End If
End Sub
and the code in the Form's code sheet.
Private Sub Botao_Salver_Click()
' 091
Dim PassWord As String ' Textboxes handle text = strings
PassWord = Senha_TextBox.Value ' this is a string, even if numeric
If PassWord = "123" Then
Me.Tag = -1 ' write something to the Tag property
Else
MsgBox "The password is incorrect", vbInformation, "Access denied"
End If
Me.Hide ' hide the form
End Sub
The line Cancel = (Val(.Tag) <> True) in the BeforeSave procedure will crash if the user closed the form using the X button. This is because that button effectively unloads the form before your code can do it. In your system, that action should be paramount to "no password". Therefore this code will remedy the situation.
On Error Resume Next
Cancel = (Val(.Tag) <> True)
If Err.Number Then Cancel = True
That's a more dignified exit than gathering your skirts and fleeing the scene in panic. However, there is also a method by which you can simply not allow the form to be closed that way. I use the two event procedures below in most of my forms.
Private Sub CmdCancel_Click()
' 091
Me.Hide
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
' 091
Cancel = (CloseMode <> vbFormCode)
If Cancel Then CmdCancel_Click
End Sub
Read up about the QueryClose event here. In its above incarnation it just cancels what the user pressed and suggests alternative code which could be simply Me.Hide. I have Me.Hide in the procedure that responds to the Cancel button on my form and I rather invoke that procedure than allowing a second cancel exit from the form in my code. In this way there are just two exits from my form, with OK or with Cancel. Pressing the X is handled in the same way as when Cancel was pressed. Either way, the Me.Tag is preserved until the bitter end.
Change the value of Salvar before Unloading the UserForm.
If PassWord = 123 Then
Salvar = True
Unload UserForm_Salvar
End If

Entire Application Disappears (runs in background) instead of opening worksheet "Sheet1" in VBA

I have 2 Userforms. In userform1, sheet to open is selected together with some textbox. In Userform2, there are additional option boxes and a command button to unload Userform2 and Activate worksheet 1 but it won't load...i used to be able to run it until i added a code to prompt user to complete fields..not sure what is wrong with my code that it won't proceed opeining the worksheet anymore
Userform1 Code:
Private Sub CommandButton1_Click()
If TextBox1.Value = "" Then
MsgBox "Pls. enter data"
Cancel = True
Exit Sub
End If
If Sheet1.Value = True Then
Unload UserForm1
UserForm2.Show
Userform2 Code:
*'to prompt user to complete fields*
Private Sub CommandButton1_Click()
If OptionBox1.Value = False And OptionBox2.Value = False Then
MsgBox "Pls. select option"
Cancel = True
Exit Sub
End If
*'to open worksheet "Sheet1"*
If UserForm1.Sheet1.Value = True Then
Worksheets("Sheet1").Activate
Application.Visible = True
Unload UserForm2
End If
End Sub
Once you unload UseForm1 it's no longer accessible from UserForm2 - you should instead Hide UserForm1 until you're done with it, and only then Unload it.

My excel userform becomes unresponsive the next time I load it

I have two forms, a login form to authenticate users to enter the system and a main form to work with if the authentication is successful. I work with an access database to search for the valid users and also to populate lists in the main form.
And here is the code for that:
Private Sub CancelCommandButton_Click()
CloseDatabase
Unload Me
End Sub
Private Sub ConfirmCommandButton_Click()
...
End Sub
Private Sub UserForm_Initialize()
ConnectDatabase
End Sub
Private Sub OpenMainForm()
Unload Me
MainForm.Show
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = vbFormControlMenu Then
Cancel = True
End If
End Sub
And here is the code for managing main form load-up and close:
Public Sub UpdateControls()
PopulateUserList
End Sub
Private Sub UserForm_Activate()
sTag = Split(Me.Tag, "|")
If sTag(0) <> "1" Then
Me.MainFormMultiPage.Pages(0).Enabled = False
Me.MainFormMultiPage.Value = 1
Else
Me.MainFormMultiPage.Pages(0).Enabled = True
Me.MainFormMultiPage.Value = 0
UpdateControls
End If
UserLabel1.Caption = sTag(1)
UserLabel2.Caption = sTag(1)
UserLabel3.Caption = sTag(1)
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = vbFormControlMenu Then
' Tip: If you want to prevent closing UserForm by Close (×) button in the right-top corner of the UserForm, just uncomment the following line:
' Cancel = True
Dim answer As Integer
answer = MsgBox("ÂíÇ ãØãÆäíÏ ˜å ãí ÎæÇåíÏ ÇÒ ÓÇãÇäå ÎÇÑÌ ÔæíÏ¿", vbYesNo + vbQuestion, "ÎÑæÌ ÇÒ ÓÇãÇäå")
If answer = vbYes Then
CloseDatabase
Else
Cancel = True
End If
End If
End Sub
Private Sub UserForm_Terminate()
loginForm.Show
End Sub
When I close the main form by clicking 'X' button, the login form reappears and the main form is closed; But when I login again (preferably using the same credentials) the main form is displayed but totally unresponsive (No list population, 'X' button doesn't work or any other controls in the form).
What should I do? Does the code in the UserForm_CloseQuery() unload the main form and all of its macros and I can't get the required events back to function or am I missing something?
It's not a time I started coding VBA and I can't make the head or tail of it easily when new problems arise. Any help would be appreciated. Thanks
Assuming your forms are modal, change the login form code to:
Private Sub OpenMainForm()
Me.Hide
MainForm.Show
Me.Show
End Sub
and remove the Userform_Terminate code from the main form. That will mean that the login form automatically shows when the main form is closed.

Returning a value or Cancel from Excel userform

I have a sub that calls a userform to show and would only like to proceed if the user didn't click my Cancel button. I don't want to put all my other sub calls within the userform.
Is it possible to have a userform return a value or a way to check if the user clicked a particular button?
I suppose I can use a global variable, but was wondering if I could pass things to and from a userform.
I prefer to use properties.
Inside your userForm
Private m_bCancel As Boolean
Public Property Get Cancel() As Boolean
Cancel = m_bCancel
End Property
Public Property Let Cancel(ByVal bCancel As Boolean)
m_bCancel = bCancel
End Property
Code for the cancel button
Private Sub cmdCancel_Click()
Me.Cancel=True
Me.Hide
End Sub
Call the userForm from outside like this
sub loadForm()
dim frm
set frm= new UserForm1
frm.show
if frm.Cancel then
Msgbox "Cancelled"
end if
End Sub

Userform Cancel Button _Intermittently_ Unresponsive?

The attached VBA procedures are for a progress bar userform. Everything works as expected, except that the cancel button is intermittently unresponsive.
I say intermittently because, 95% of the time I have to click the cancel button numerous times before the procedure stops. I can see the button click event being animated, but the procedure isn't being interrupted. It looks as though something is stealing focus from the cancel button before the button down event can occur.
The escape and window close buttons respond as expected with one click.
What do I need to do to make the cancel button respond correctly? Thanks!
Update: I noticed that when I click and hold down on the cancel button, instead of the button staying "down" it gets kicked back up. So apparently something is resetting the button state to up, fast enough that the procedure is not catching the down state to fire the click event.
Here is the code in the userform module (named UserForm1):
Private mbooUserCancel As Boolean
Public Property Get UserCancel() As Boolean
UserCancel = mbooUserCancel
End Property
Private Property Let UserCancel(ByVal booUserCancel As Boolean)
mbooUserCancel = booUserCancel
End Property
Public Sub UpdateProgress(CountTotal As Long, CountProgress As Long)
On Error GoTo Error_Handler
ProgressBar1.Value = CountProgress / CountTotal * 100
DoEvents
Error_Handler:
If Err.Number = 18 Then CommandButton1_Click
End Sub
Private Sub CommandButton1_Click()
Hide
UserCancel = True
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
Cancel = True
CommandButton1_Click
End Sub
Private Sub UserForm_Activate()
With Application
.Interactive = False
.EnableCancelKey = xlErrorHandler
End With
End Sub
Private Sub UserForm_Terminate()
Application.Interactive = True
End Sub
Here is the code for the module (named Module1) that calls the UserForm1:
Sub TestProgress()
On Error GoTo Error_Handler
Dim objUserForm As New UserForm1
Dim lngCounter As Long
Dim lngSubCounter As Long
With objUserForm
.Show vbModeless
DoEvents
For lngCounter = 1 To 5
If .UserCancel Then GoTo Exit_Sub
For lngSubCounter = 1 To 100000000
Next lngSubCounter
.UpdateProgress 5, lngCounter
Next lngCounter
Application.Wait Now + TimeValue("0:00:02")
.Hide
End With
Exit_Sub:
If objUserForm.UserCancel Then
MsgBox "User Cancelled from UserForm1"
End If
Exit Sub
Error_Handler:
If Err.Number = 18 Then
Unload objUserForm
MsgBox "User Cancelled from Module1"
End If
End Sub
Works for me on the first click every time. Try unloading any add-ins or any other code that could be running inside the container app and see if that helps.
If people are still in need of the answer, well I researched & cracked it!
For the click on cancel button, code should be;
Private Sub CommandButton1_Click()
Unload Me
'this bit ends all macros
End
End Sub
The answer is to use modal userforms for progress bars so that the button click event can fire without getting obscured by processing in the calling procedure.

Resources