Is there a way to detect if user clicked a disabled button? - excel

Hey, I have an UserForm into which an user inputs varius profile
fields.
Once it's filled in, there is verification - if anything goes astray,
the CommandButton, named save_button is disabled
What I want to achieve is: If user clicks on the button, whilst it is in the disabled state, to display a MsgBox saying he needs to correct the incorrectly filled in field
For Demonstration purposes, I'm not gonna paste here the validation procedures, so let's just pretend that the save_button.Enabled = False is set from the getgo. Produces the same result.
save_button.Enabled = False ' already ran before, pretend this executes it
Private Sub save_button_Click()
If save_button.Enabled = False Then
MsgBox "Clicked disabled button"
End If
End Sub
Issue is, once a CommandButton is set to .Enabled = False then it can no longer be officially clicked (hence it can't even trigger the Click() procedure)
My next thought was to use the MouseUp as a substitute. Issue is,
this triggers on any miniscule movement over the button and I don't want to bombard the user with MsgBoxes
Can you think of any alternatives, as to how to detect if user clicked the disabled button?

When a control is disabled, the click event bubbles up the tree. In your case, I guess the user form will get the click instead. If you put your save button inside a frame, that will get the click if the button is disabled. It is fairly easy to make the frame invisible, by setting
Caption to ""
BorderStyle to fmBorderStyleNone
SpecialEffect to fmSpecialEffectFlat
And then size the frame so that is the same size as the button.
The code is easy:
Private Sub YourNewFrame_Click()
MsgBox "Save button disabled!"
End Sub
Tip: If you draw the frame, cut your button and paste it inside your new frame, it will be placed properly. Properly, as in in the right part of the hierarchy. Visually, you will have to do manually.

I want to offer another approach based on my comment to your question.
In the below gif, you will see that the 'Create Form' does not become enabled until all the necessary information is provided. You don't see it in the gif so much, but each entry that requires validation also has it behind the scenes in code.
The essential code behind that action is this:
Sub checkFields()
Select Case True
Case Len(Me.formTitleLine1) = 0, Len(Me.formPrefix) = 0, Len(Me.formNumber) = 0, Len(Me.formProduct) = 0, Len(Me.formEditionMonth) = 0, Len(Me.formEditionYear) = 0
Me.createForm.Enabled = False
Case Else
Me.createForm.Enabled = True
End Select
End Sub
And it's called on the afterUpdate event of each relevant box:
Private Sub formEditionYear_AfterUpdate()
checkFields
End Sub
With one small change to the checkFields sub, you can only show the save button once everything has been filled in correctly. That change would be:
Me.createForm.Visible
instead of
Me.createForm.Enabled

Related

Can two checkboxes be linked in a way that only one will ever be checked?

I am working on moving a form over to Excel. Due to the style of form I have to replicate the form with no changes.
On the form there are two check boxes, one for Full and one for partial.
I have the code spit out a warning box if both are selected. I think it would be easier to make it so that if one is checked the other will automatically uncheck.
' ERROR CHECK FULL/PARTIAL
If [F8] = True And [F9] = True Then
MsgBox ("FAI can not be both a Full and Partial")
ELSE
'actual code in middle.
END IF
There are two ways to do this. With Radio buttons, or checking if the other box is checked.
With radio buttons is simpler if one of them must be selected no matter what. You can enclose radio buttons on different frames to "group" them together as in the screenshot below. You can see that one on each frame is selected and you can only select one of the two on each frame.
If you really want to use a Checkbox, you can use the code below.
Private Sub CheckBox1_Click()
If Me.CheckBox1 = True Then
If Me.CheckBox2 = True Then Me.CheckBox2 = False
End If
End Sub
Private Sub CheckBox2_Click()
If Me.CheckBox2 = True Then
If Me.CheckBox1 = True Then Me.CheckBox1 = False
End If
End Sub
The first If checks if this is a click to Check the box, if it is, then it will check if the second box is already checked, if it is, it will un-check it.
This is assuming you are creating a UserForm, and these are not CheckBoxes on an Excel Sheet. The implementation would be the same, but the code will be slightly different.

Multipage tabs visible, but inactive

I have a user form with multipage. I would like to have the tabs of a multipage visible on top, so the user knows on which page he is and how many there are left. But I would like to disable the possibility to jump between the tabs by pressing on the tab name. Instead only next and back buttons would be available to navigate between the pages. Is it possible just by using the properties, or do I have to write the code for the mulipage change?
create form with one multipage control
then add this code ... click form background to see result
Private Sub UserForm_Click()
If UserForm1.MultiPage1.Pages(0).Enabled Then
UserForm1.MultiPage1.Pages(1).Enabled = True ' must always have at least one enabled
UserForm1.MultiPage1.Pages(0).Enabled = False ' otherwise it looks bad
Else
UserForm1.MultiPage1.Pages(0).Enabled = True ' reverse statements, and you will see
UserForm1.MultiPage1.Pages(1).Enabled = False
End If
End Sub

Enable Command Buttons based on Combobox

I have a userform that needs to display different options based on the user that is opening the form. Some of these options should only be enabled once a selection has been made in a combobox, but I can't seem to find a way to get them to update after a combobox selection is chosen.
What I'm using is:
Private Sub cbCharts_AfterUpdate()
If Me.cbCharts Is "" Then
Me.bQuickEntry.Enabled = False
Me.bView.Enabled = False
Exit Sub
ElseIf UserDep = "Quality Control" Then
Me.bQuickEntry.Enabled = True
Me.bView.Enabled = True
Me.bAdjust.Enabled = True
Else
Me.bView.Enabled = True
Me.bQuickEntry.Enabled = True
End If
End Sub
Where cbCharts is the combobox in question, and bQuickentry, bView and bAdjust are the buttons.
Using this code, the buttons don't enable until I click somewhere else on the form, instead of immediately after making the selection. Then, if I clear the combobox Excel hangs and has to be force closed.
I've tried instead using Private Sub cbCharts_OnExit with the same code, but it doesn't do anything at all.
I know I can just leave all the buttons enabled and visible add a verification step to the code for each button to ensure that there is a valid combobox selection before proceeding, but I would prefer to enable and set their visibility to prevent user confusion, as some of these buttons will not be usable by the majority of spreadsheet users.
What am I doing wrong?
Try putting your code into the cbCharts_Click() event function instead. This event is fired as soon as the user selects an item in the list.

Excel VBA Calling the Calendar via Command Button in a form

I have just added in Calendar 12.0 from the tools > Additional Controls. Calendar works fine and I have it spitting the date out to the right cells. What I would like, however, is to really make the calendar visible from a command button as my form contains a bunch of fields and I don't want to bog up the form with this calendar. I have tried Calendar1.show but the .show isn't an option.
So ultimately I need a command button to show the calendar, allow the user to select (I have that) and then close the calendar. Any help? I thank you in advance!!
bdubb
In this snippet, CommandButton1 is from the ActiveX controls, not the form controls. It requires that you click the button to show the calendar (which pops up next to the button you clicked), and click the button again to hide the calendar.
Private Sub CommandButton1_Click()
If Not Calendar1.Visible Then
Calendar1.LinkedCell = "A1"
Calendar1.Top = Sheet1.CommandButton1.Top
Calendar1.Left = Sheet1.CommandButton1.Left + Sheet1.CommandButton1.Width + 1
Calendar1.Visible = True
Else
Calendar1.Visible = False
End If
End Sub
Obviously, different buttons would require different linked cells, but it does mean that you could have a single calendar control that it displyed by multiple buttons (if that is what you want).
Unfortunately, it would appear that you cannot hide the control while any of its events are firing (e.g AfterUpdate). It just doesn't want to disappear!!
Hide/Close a calendar control still not works (new year 2015 = almost four years later) but I think I found a workaround to hide the control after firing events.
I have a Calendar1_AfterUpdate(), which launches before Calendar1_Click(). Code is placed directly in a worksheet and NOT in a module.
Private Sub Calendar1_AfterUpdate()
Range("a1") = Me.Calendar1.Value
' Next two lines does not work within AfterUpdate
' When running step by step it seems to work but the control is
' visible when End Sub has run
Me.Calendar1.Visible = True
Me.Calendar1.Visible = False
End Sub
To that I simply added
Private Sub Calendar1_Click()
Me.Calendar1.Visible = True
Me.Calendar1.Visible = False
End Sub
Please note that the control for some reason must be made visible before hiding.
Why it does not work directly in Calendar1_AfterUpdate() is a mystery to me.
Next problem is to hide the control when I remove the mouse. Mouse-events seems to be impossible in a calendar control ...

Disable button on a userForm

I'm trying to figure out how to disable a button within my userForm if a certain cell within my spreadsheet equals a certain number. I tried the code stated below, but it isn't working.
Private Sub UserForm_Initialize()
Label2 = Sheets("DATA").Range("AM2").Value
Label4 = Sheets("DATA").Range("AO2").Value
Label7 = Format(Sheets("DATA").Range("R8").Value, "Currency")
If Sheets("DATA").Range("AL10").Value = 10 Then
ActiveSheet.Shapes("CommandButton1").Select
UserFormact_Upgrade.CommandButton1.Enabled = False
Else
End If
End Sub
Your code should be working, as you're on the right path.
To test it, simply create a new form and add this code, you'll see it should work. Maybe you're having problems within the IF clause?
Besides, you don't need to select the shape prior to disabling it; just disable it right away.
Private Sub UserForm_Initialize()
CommandButton1.Enabled = False
End Sub
I know this is old, but got to this thread trying to solve my problem, and found a solution that wasn't mentioned here. So in case someone gets here like I did, and this didn't quite get them where they needed to go, I thought this might help.
I had a userform with a drop down box called cmdADAMFields, and I didn't want my submit button called FieldsSubmitButton to be enabled until I selected something from the dropdown box.
I had to break up my argument into two different private subs vs one larger If-Then-Else statement.
First, I put:
Private Sub UserForm_Activate()
If cmbADAMFields.ListIndex = -1 Then FieldsSubmitButton.Enabled = False
End Sub
Then when for my pulldown's private sub when it's value changed I wrote:
Private Sub cmbADAMFields_Change()
FieldsSubmitButton.Enabled = True
End Sub
The proper place for setting Enabled property is in Activate event (associated with Show method) and not Initialize event (associated with Load instruction).
The below code disable the button CommandButton1 when AL10 cell >= 10.
Private Sub UserForm_Activate()
CommandButton1.Enabled = ( Sheets("DATA").Range("AL10") < 10 )
End Sub
For buttons you can choose between normal buttons (property Enabled=False and property Visible=true), disabled buttons (property Enabled=False and property Visible=true) and invisible buttons (property Enabled=False and property Visible=False), that it is a cleaner interface, in most cases.
Concerning text boxes, besides normal, disabled and invisible status, there is a locked status, that is enabled and visible, but cannot be user edited. (property Locked = True)
A locked control only can be changed by VBA code. For instance, someone can includes date text boxes, that it's filled using a secondary popup date form with Calendar control.

Resources