I'm running some VBA code in Excel and I made a a combo box that will turn red and set the focus on it when there is no value entered.
If cmb = "" Then
cmb.BackColor = vbRed
lbl.ForeColor = vbRed
cmb.SetFocus
Exit Sub
Else
cmb.BackColor = vbWhite
lbl.ForeColor = vbBlack
End If
As I have many combo boxes on my form, I want to build a function or procedure that I can call for any combo box that I want.
Can anyone help?
Here's a general function that you can pass a ComboBox to:
Function ValidateComboBox(c As ComboBox) As Boolean
If Len(c.Text) = 0 Then
c.BackColor = vbRed
Controls(c.Tag).ForeColor = vbRed ' Set associated label color, also
c.SetFocus
ValidateComboBox = False
Else
c.BackColor = vbWhite
Controls(c.Tag).ForeColor = vbBlack ' Set associated label color, also
ValidateComboBox = True
End If
End Function
You call it like this, for example when the form is submitted:
' [OK] clicked. Submit form...
Private Sub cmdOK_Click()
If Not ValidateComboBox(ComboBox1) Then Exit Sub
If Not ValidateComboBox(ComboBox2) Then Exit Sub
If Not ValidateComboBox(ComboBox3) Then Exit Sub
...
End Sub
The tricky part is that you have a label that corresponds to each combo box that needs to be updated as well. You can either design the function to accept both a ComboBox control and a Label control and pass both each time, or you take advantage of the combo box's Tag property, as I've done above. For each combo box, just enter the name of the corresponding Label control into its Tag property using the Properties window in the designer.
For example, if ComboBox1 has a label named Label1, then enter "Label1" (without the quotes) into ComboBox1's Tag property. The routine above will look for the label/control with that name and set its color appropriately as well.
Related
I have two toggle buttons, each on a different sheet.
The code of the toggle button is stored on the sheet level:
Private Sub MoveButton_Click()
ClickToggleButton "move", ActiveSheet.Name
'ToggleButtonPressed sSHEET2NAME
End Sub
The ClickToggleButton function is stored on the module level (because I want to use the same function for both buttons).
In my case while clicking one toggle button, the other button on the other sheet must be pressed, this works out well:
'switch button state to the same over the 2 sheets
Select Case sheetName
Case sSHEET1NAME
Worksheets(sSHEET2NAME).OLEObjects(sBUTTONMOVENAME).Object.Value = Worksheets(sSHEET1NAME).OLEObjects(sBUTTONMOVENAME).Object.Value
Case sSHEET2NAME
Worksheets(sSHEET1NAME).OLEObjects(sBUTTONMOVENAME).Object.Value = Worksheets(sSHEET2NAME).OLEObjects(sBUTTONMOVENAME).Object.Value
End Select
Now I only need to change the text (caption) on both buttons depending on the value you are in, I got error 438 "Object doesn't support this property or method" on this line:
Worksheets(ActiveSheet.Name).OLEObjects(sBUTTONMOVENAME).Caption = sButtonDescription
I guess it has to do with the fact where my code was stored ? I can change the value of the object but can't change the caption.
Thanks for your help.
You set the caption of the button like you set the value - you need to use the Object-property of the OLEObject.
The OLEObject is just a wrapper around different kind of objects, while the Object-property is the button (or checkbox, or textbox or...) itself:
ActiveSheet.OLEObjects(sBUTTONMOVENAME).Object.Caption = sButtonDescription
You can also set other properties like Font, Color and the like:
With ActiveSheet.OLEObjects(sBUTTONMOVENAME).Objectws.OLEObjects(1).Object
.Font.Size = 14
.FontBold = True
.FontName = "Broadway"
.ForeColor = vbRed
.BackColor = vbYellow
End With
Situation
I have two form control check boxes. I am trying to write a code that will allow only either of them to be true.
my code is
Sub CheckBox2_Click()
If CheckBox1.Enabled = True Then
CheckBox2.Enabled = False
Else
If CheckBox2.Enabled = True Then
CheckBox1.Enabled = False
End If
End If
End Sub
I have this code in module and have assigned the same macro for both the checkboxes. I get run-time error 424. I beleive this is very basic problem but I unable to dela with it.
Thank you
Please, test the following way. Form check boxes do not have a click event, as ActiveX ones have. You should associate the next sub to both of them. The check boxes I tested, have their names as "Check Box 1" and "Check Box 2". You have to change yours according to the reality in your case, Please, copy the next code in a standard module and then associate it to both used check boxes:
Option Explicit
Sub FormCheckBoxChange()
If ActiveSheet.CheckBoxes(Application.Caller).value = 1 Then
Select Case Application.Caller
Case "Check Box 1": ActiveSheet.CheckBoxes("Check Box 2").value = -4146
Case "Check Box 2": ActiveSheet.CheckBoxes("Check Box 1").value = -4146
End Select
End If
End Sub
Use instead of the used check box names, the appropriate ones for your case.
In case of Form text boxes, their value is not True and False as in case of ActiveX ones. It is 1 and -4146...
Are you sure you want to enable/disable the checkboxes.
Following code makes sure that either one of both boxes is checked.
Public Sub checkbox2_onClick()
Dim oCb1 As Object
Set oCb1 = Table1.Shapes("Checkbox1").OLEFormat.Object
Dim oCb2 As Object
Set oCb2 = Table1.Shapes("Checkbox2").OLEFormat.Object
If oCb2.Value = 1 Then oCb1.Value = 0
End Sub
Public Sub checkbox1_onClick()
Dim oCb1 As Object
Set oCb1 = Table1.Shapes("Checkbox1").OLEFormat.Object
Dim oCb2 As Object
Set oCb2 = Table1.Shapes("Checkbox2").OLEFormat.Object
If oCb1.Value = 1 Then oCb2.Value = 0
End Sub
I have a userform with multiple control types (TextBox, ComboBox, Button, Check box, Label).
I want to check the value in each TextBox and ComboBox and change the color of the box to red if there is no value.
The problem using "Controls" collection is that some controls do not have a value property i.e. Label. So I want to write code where there will be no need to define the type of control inside the body of the loop as the type is already specified at the declaration level.
Loop through the controls and if textbox or combobox and value ="" then change color to red
Private Sub CommandButton1_Click()
Dim crt As Control
For Each crt In Me.Controls
If TypeName(crt) = "TextBox" Or _
TypeName(crt) = "ComboBox" Then
If crt.Value = "" Then
crt.BackColor = vbRed
Else
crt.BackColor = vbWhite
End If
End If
Next
End Sub
really struggling with this one, found a solution for the time being but it's not really a satisfactory one.
I have a workbook with two user forms, one to input data and one to search for previously entered data and a third user form designed as a date picker form which is set to activate on entry of a designated date text box.
Individually I have no problem, the user clicks the text box and the date picker form appears, they make their selection which closes the date picker form and adds the date to the text box. On the "input data" form I have a multi page with a single date selection text box on each of the two pages, on the "find data" form I have an option to search a single date or a range, 3 date selection text boxes in total.
now I am noticing that userform1 (input data) is prompting a run time error 91 - object variable or With block variable not set and is flagging the first line for userform2 in the code whenever I select a date from the date picker form.
what I did notice however was that the correct date was still being entered into the textbox so as a fix I added an 'On error goto' line above the highlighted line which is allowing the action to take place without interruption. What I did notice was that now if I enter a date anywhere on userform2 (find data) and then close the form and decide I want to enter data instead, the text box on userform1 will contain whatever the previous selection was on userform2. What is especially puzzlng about this to me is that the initialize event for UF1 enters the current date in the date text box.
see code below, is there a much better way to write this? I hope I explained well enough, please let me know if I can provide additional details to help.
Sub CloseDatePicker(save As Boolean)
If UserForm1.MultiPage1.Value = 0 Then
UserForm1.tbDate.Text = Calendar1.Value
UserForm1.cbMember.SetFocus
ElseIf UserForm1.MultiPage1.Value = 1 Then
UserForm1.tbDate2.Text = Calendar1.Value
UserForm1.cbMember2.SetFocus
End If
On Error GoTo dpexit
If UserForm2.ActiveControl.Name = "TextBox1" Then
UserForm2.TextBox1.Text = Calendar1.Value
End If
If UserForm2.ActiveControl.Name = "TextBox2" Then
UserForm2.TextBox2.Text = Calendar1.Value
ElseIf UserForm2.ActiveControl.Name = "TextBox3" Then
UserForm2.TextBox3.Text = Calendar1.Value
End If
dpexit:
Me.Hide
End Sub
Right out the gate, the first problem I see with your code is you're trying to change the value of a text box with the .Text property. I've personally never had luck with using .Text to set value as it consitently throws Err:91. Instead I've found it's better to use .Value.
Sub CloseDatePicker(save As Boolean)
If UserForm1.MultiPage1.Value = 0 Then
UserForm1.tbDate.Value = Calendar1.Value
UserForm1.cbMember.SetFocus
ElseIf UserForm1.MultiPage1.Value = 1 Then
UserForm1.tbDate2.Value = Calendar1.Value
UserForm1.cbMember2.SetFocus
End If
' On Error GoTo dpexit 'disabled this for you to test your code
If UserForm2.ActiveControl.Name = "TextBox1" Then
UserForm2.TextBox1.Value = Calendar1.Value
End If
If UserForm2.ActiveControl.Name = "TextBox2" Then
UserForm2.TextBox2.Value = Calendar1.Value
ElseIf UserForm2.ActiveControl.Name = "TextBox3" Then
UserForm2.TextBox3.Value = Calendar1.Value
End If
dpexit:
Me.Hide
End Sub
I want to disable a button with VBA code like this:
ActiveSheet.Shapes("Button 1").ControlFormat.Enabled = False
I tried:
Set b1 = ActiveSheet.Buttons("Button 1")
b1.Enabled = False
And:
Me.Shapes("Button 1").ControlFormat.Enabled = False
My button name is correct, because it doesn't give me an error message, so the code is completely run through.
After this script I can click on that button and the assigned macro runs. Nothing should happen when I click on it.
Disabling a Form button (not talking ActiveX here) does not prevent the assigned macro to run and does not gray out the button. The code below does exactly that based on the version got from Excel. If you did not assign a name to your Form button, you can also use (Buttons(1).
If Excel version = 16 or higher the button is "enabled" by making it black and assigning my macro, else the button is "disabled" by making it gray and assigning no action to it.
Code can e.g. reside in Private Sub Worksheet_Activate() within sheet "Test Sheet"
If Application.Version < 16 Then
Worksheets("Test Sheet").Buttons("button_name").Font.Color = 8421504
Worksheets("Test Sheet").Buttons("button_name").OnAction = ""
Else
Worksheets("Test Sheet").Buttons("button_name").Font.Color = 0
Worksheets("Test Sheet").Buttons("button_name").OnAction = "'Name of the workbook.xlsm'!my_macro_name"
End If
Probably you are using ActiveX Button. Try this:
Sheets("Sheet1").CommandButton1.Enabled = False '--->change sheet name as required
EDIT:
______________________________________________________________________________
For a Form control Button the following line
ActiveSheet.Shapes("Button 1").ControlFormat.Enabled = False
disables the button i.e. click event will no longer work but the appearance of the button does not change which gives an impression that the button is still active. So work around for that is to change the color of the text of the button as follows:
Sub disable_button_2()
Dim myshape As Shape: Set myshape = ThisWorkbook.Worksheets("Sheet1").Shapes("Button 2")
With myshape
.ControlFormat.Enabled = False '---> Disable the button
.TextFrame.Characters.Font.ColorIndex = 15 '---> Grey out button label
End With
End Sub
And to bring back button to its original state write:
Sub activate_button_2()
Dim myshape As Shape: Set myshape = ThisWorkbook.Worksheets("Sheet1").Shapes("Button 2")
With myshape
.ControlFormat.Enabled = True '---> Enable the button
.TextFrame.Characters.Font.ColorIndex = 1 '---> Highlight button label
End With
End Sub
I suggest to create a shadow button/shape with exactly same size/position, but different color (fill and/or text to your liking) and no macro/action attached. Then just change the .visible property of your primary shape. Visible = button is active; not visible button is e.g. grayed out and has no action/is passive.
Only tested on Excel 2016 x86
I continued to receive errors utilizing .ControlFormat. solutions.
After much searching I found another solution that worked great for my needs of disabling Shapes/Buttons.
To mimic the .Enabled property of a uf control, you might toggle the .OnAction property of a shape.
Function ShapeIsEnabled(aShape As Shape) As Boolean
ShapeIsEnabled = (aShape.OnAction <> "")
End Function
Sub EnableShapeMacro(aShape As Shape)
aShape.OnAction = aShape.AlternativeText
End Sub
Sub DisableShapeMacro(aShape As Shape)
aShape.AlternativeText = aShape.OnAction
aShape.OnAction = vbNullString
End Sub
Note the use of the .AlternativeText property to store the macro name.
source: mikerickson
https://www.excelforum.com/excel-programming-vba-macros/1267897-disable-action-of-macro-enabled-shape.html#post5080833