VBA Excel Toggle Button "Latching" - vba

I have the following code corresponding to three ToggleButtons in a VBA Program in Excel. When one button is clicked, it is supposed to stay "pressed" and the other two buttons are supposed to "release". However, with the code I have, I have to click on one button TWICE, once to release the other buttons and the other to keep the original one pressed.
However, if I add "ToggleButtonX.Value = True" to each of the Subs, when one button is clicked, it cannot release even after clicking another button. How could one configure this so that when one clicks on one button, that button stays pressed AND the other buttons get released?
EDIT: I would like to KEEP TOGGLEBUTTONS.
Private Sub ToggleButton1_Click()
ToggleButton2.Value = False
ToggleButton3.Value = False
End Sub
Private Sub ToggleButton2_Click()
ToggleButton1.Value = False
ToggleButton3.Value = False
End Sub
Private Sub ToggleButton3_Click()
ToggleButton1.Value = False
ToggleButton2.Value = False
End Sub

In addition to the OptionButton answer, which is probably easier and cleaner to implement, there's another way to do it as well by using logic that will only change the values of the other two buttons when one button is clicked. The code for the other buttons Click event will fire, but the variable sButton will determine that the code will only fire on the button that was physically pressed by the user.
Also note the use of Not Me.ToggleButton1.Value. This will ensure that button 2 and 3 are the opposite of button 1 with each click. The way your code was written, it would always revert the other buttons to False no matter what if the clicked button was True or False.
Option Explicit
Public sButton As String
Private Sub ToggleButton1_Click()
ButtonLoad 1
End Sub
Private Sub ToggleButton2_Click()
ButtonLoad 2
End Sub
Private Sub ToggleButton3_Click()
ButtonLoad 3
End Sub
Sub ButtonLoad(iButton As Integer)
Select Case iButton
Case 1
If sButton = "" Then
sButton = "1" 'set so that other buttons don't trigger
Me.ToggleButton2.Value = Not Me.ToggleButton1.Value
Me.ToggleButton3.Value = Not Me.ToggleButton1.Value
sButton = "" 'reset for next button click
End If
Case 2
If sButton = "" Then
sButton = "2"
Me.ToggleButton1.Value = Not Me.ToggleButton2.Value
Me.ToggleButton3.Value = Not Me.ToggleButton2.Value
sButton = ""
End If
Case 3
If sButton = "" Then
sButton = "3"
Me.ToggleButton2.Value = Not Me.ToggleButton3.Value
Me.ToggleButton1.Value = Not Me.ToggleButton3.Value
sButton = ""
End If
End Select
End Sub

By calling ToggleButtonx.Value = False you are simulating a click on that button and so it own code will run, and set the value of the button you just clicked to false.
Use instead the MouseDown event:
Private Sub ToggleButton1_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
ToggleButton2.Value = False
ToggleButton3.Value = False
End Sub
Private Sub ToggleButton2_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
ToggleButton1.Value = False
ToggleButton3.Value = False
End Sub
Private Sub ToggleButton3_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
ToggleButton1.Value = False
ToggleButton2.Value = False
End Sub

This is easily done with Option Buttons (If that works with the rest of your implementation)
Private Sub OptionButton1_Click()
OptionButton1.Value = True
OptionButton2.Value = False
OptionButton3.Value = False
End Sub
Private Sub OptionButton2_Click()
OptionButton1.Value = False
OptionButton2.Value = True
OptionButton3.Value = False
End Sub
Private Sub OptionButton3_Click()
OptionButton1.Value = False
OptionButton2.Value = False
OptionButton3.Value = True
End Sub

Related

ActiveX Combobox doesn't close automatically

I have an ActiveX Combobox in one of my main sheet which control/update a series of charts.
Private Sub cmBoxSelect_GotFocus()
Application.ScreenUpdating = False
With Me.cmBoxSelect
.List = Array("Grand Total", "Prod1", "Prod2", "Prod3", "Prod4", "Prod5")
.ListRows = 6
.DropDown
End With
Application.ScreenUpdating = True
End Sub
Private Sub cmBoxSelect_Change()
'series of codes which manipulates the charts, based on selection...
End Sub
I noticed that when I click the ComboBox and select one of its content, it leaves a blue highlight on the selection. So to prevent that, I added:
Private Sub cmBoxSelect_DropButtonClick()
Application.ScreenUpdating = False
ActiveCell.Activate
Application.ScreenUpdating = True
End Sub
It successfully removed the highlight.
However, it has a weird drawback. cmbSelect doesn't close automatically once user didn't select anything (once the combobox is active and the user click any cell in the sheet, it doesn't close out). It was working before I added the DropButtonClick event.
Did I missed anything or any wrong steps above? Thanks for your inputs!
EDIT#1
Seems I already found a solution by trial and error. I only added a blank Label and select it to remove the focus out of the ComboBox whenever there is a change. I also changed the DropButtonClick to LostFocus.
Private Sub cmBoxSelect_GotFocus()
Application.ScreenUpdating = False
With Me.cmBoxSelect
.List = Array("Grand Total", "Prod1", "Prod2", "Prod3", "Prod4", "Prod5")
.ListRows = 6
.DropDown
End With
Application.ScreenUpdating = True
End Sub
Private Sub cmBoxSelect_LostFocus()
ActiveCell.Select
End Sub
Private Sub cmBoxSelect_Change()
'series of codes which manipulates the charts, based on selection...
Me.Label1.Select
End Sub
You need to put the SelLength to 0 in multiple events to avoid highlighting:
so:
Me.cmBoxSelect.SelLength = 0
in:
Private Sub cmBoxSelect_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
Private Sub cmBoxSelect_KeyUp(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
Private Sub cmBoxSelect_LostFocus()
Private Sub cmBoxSelect_DropButtonClick()
Private Sub cmBoxSelect_Change()
Private Sub cmBoxSelect_GotFocus()
(you could add also Me.cmBoxSelect.SelStart = 0 )
Lets try this:
Not Event-triggered by a change, but by the dropbuttonclick
Private Sub changingComboBox(String s)
'series of codes which manipulates the charts, based on selection...
End Sub
Private Sub cmBoxSelect_DropButtonClick()
Dim s As String
s = cmBoxSelect.SelText
If (cmBoxSelect.SelText = cmBoxSelect.Value) Then
cmBoxSelect.Value = ""
cmBoxSelect.Value = s
Else
call changingComboBox(cmBoxSelect.Value)
End If
End Sub
How about that ?

Multiple toggle buttons on worksheet to trigger a macro

I have 20 toggle buttons set-up like
Public Sub ToggleButton1_Click()
Check_All
If ToggleButton1.value = True Then
ToggleButton1.BackColor = vbGreen
Else:
ToggleButton1.BackColor = vbRed
End If
End Sub
Public Sub ToggleButton2_Click()
Check_All
If ToggleButton2.value = True Then
ToggleButton2.BackColor = vbGreen
Else:
ToggleButton2.BackColor = vbRed
End If
End Sub
I'm attempting to get them triggered by application.onkey like:
Application.OnKey "%a", "Sheet1.ToggleButton1_Click"
Application.OnKey "%b", "Sheet1.ToggleButton2_Click"
And using the Check_all for when all the buttons are "True" it'll do the following that is supposed to revert the toggle buttons back to the "False" state before it triggers another "macro".
Sub Check_All()
Dim tb As Object
For Each tb In Me.OLEObjects
If tb.ProgId = "Forms.ToggleButton.1" Then
If tb.Object.value <> True Then Exit Sub
End If
Next
CommandButton0_Click
End Sub
Private Sub CommandButton0_Click()
Dim x As Integer
For x = 1 To 20
Worksheets("Sheet1").OLEObjects("ToggleButton" & x).Object.value = False
Next x
CommandButton3_Click
End Sub
But I can't seem to get the application.onkey to work and I'm completely lost now.
This is a system that is hooked up to programmable USB buttons and I'm really relying on the onkey to function, unless there's a better way???
You can assign macros to shortcut keys in excel. You need to simulate the toggle-button click like this:
Sub CtrlShiftA()
ToggleButton1.Value = Not ToggleButton1.Value
End Sub
Then have your toggle-button sub as you like:
Private Sub ToggleButton1_Click()
If ToggleButton1.Value = True Then
ToggleButton1.BackColor = vbGreen
Else
ToggleButton1.BackColor = vbRed
End If
End Sub
Then under View -> Macros -> View Macros click Options..:
Press Shift + A to have Ctrl + Shift + A as shortcut key:
Now click OK, and enjoy your shurtcut key.

How to handle Checkbox value in VBA?

I have the following example:
Private Sub setCheck(ByVal val1 As Boolean, ByVal val2 As Boolean, ByVal val3 As Boolean)
With userForm1
.checkboxOne.Value = val1
.checkboxTwo.Value = val2
.checkboxThree.Value = val3
End With
End Sub
Private Sub checkboxOne_Change()
Call setCheck(True, False, False)
End Sub
Private Sub checkboxTwo_Change()
Call setCheck(False, True, False)
End Sub
Private Sub checkboxThree_Change()
Call setCheck(False, False, True)
End Sub
It is possible to click a check only in one direction. That means, if I clicked the checkboxOne first time, I don't have the ability to check it again. What I need to do?
The problem that you have is after a checkbox's value has been initialized setting it's value will cause the checkbox's Click and Change events to fire. This causes an infinite loop which effectively locks the checkboxes.
The way around this is to use a class variable to ignore subsequent calls to setCheck during an update.
Private EditMode As Boolean
Private Sub setCheck(ByVal val1 As Boolean, ByVal val2 As Boolean, ByVal val3 As Boolean)
If Not EditMode Then
EditMode = True
With UserForm1
.checkboxone.Value = val1
.checkboxtwo.Value = val2
.checkboxthree.Value = val3
End With
EditMode = False
End If
End Sub
Private Sub checkboxOne_Change()
setCheck True, False, False
End Sub
Private Sub checkboxTwo_Change()
setCheck False, True, False
End Sub
Private Sub checkboxThree_Change()
setCheck False, False, True
End Sub
What about something like this?
Private Sub chkbx1_Click()
chkbx1.Enabled = False
chkbx1.Value = Checked
End Sub
Private Sub Form_Load()
Dim ctrl As Control
' reset it whenever you open the form. this could also be defined separately in the F4-properties of the checkbox
For Each ctrl In Me.Controls
If TypeName(ctrl) = "CheckBox" Then
ctrl.Enabled = True
ctrl.Value = False
End If
Next ctrl
End Sub
Not quite sure if you really want the checkbock disabled but with the Checked value per se...
since you're asking for mutually excluding control, you want Option Buttons
say you place three of them called "OptionButton1", "OptionButton2" and ""OptionButton3" then you will place the following in the Userform code pane:
Option Explicit
Private Sub OptionButton1_Click()
CheckOBs
End Sub
Private Sub OptionButton2_Click()
CheckOBs
End Sub
Private Sub OptionButton3_Click()
CheckOBs
End Sub
Sub CheckOBs()
Dim iOB As Integer
For iOB = 1 To CInt(Right(ActiveControl.Name, 1))
Controls("OptionButton" & iOB).Enabled = False
Next iOB
End Sub

VBA: chkbox_click event triggered by changing value chkbox

I have a userform which is dynamically filled by checkboxes. To improve usability I've added a checkbox "Select all" which either selects or deselects all checkboxes. This works perfectly. Now I want the "Select all" checkbox to be unchecked (value=False) automatically once one of the other checkboxes is unchecked.
In order to achieve this I've created a class module. This class module also does what it's supposed to. But, and here's my problem, once the value of "Select all" is changed, the "Select all" checkbox_click event is triggered, which means all other checkboxes are being unchecked as well, and that's obviously not what I want! I've already tried to use the MouseDown and MouseUp events instead, but these events behave irregular and often lead to the wrong results.
Question: How do I stop the Click event from running everytime the value of this checkbox is changed without the checkbox actually being clicked?
Here's my code:
Private colTickBoxes As Collection
Private Sub UserForm_Initialize()
Dim ChkBoxes As cls_RIRI
Dim ctrl As Control
'Controls are created on run time here
'Some events to change the height of the userform and the top value of several buttons
'Make sure click events work
Set colTickBoxes = New Collection
For Each ctrl In Me.Controls
If TypeName(ctrl) = "CheckBox" And Left(ctrl.Name, 1) = "M" Then
Set ChkBoxes = New cls_RIRI
ChkBoxes.AssignClicks ctrl
colTickBoxes.Add ChkBoxes
End If
Next ctrl
Set ctrlCHK = Nothing
Set ChkBoxes = Nothing
Set ctrl = Nothing
End Sub
And the class module:
Private WithEvents chkBox As MSForms.CheckBox
Public Sub AssignClicks(ctrl As Control)
Set chkBox = ctrl
End Sub
Private Sub chkBox_Click()
If chkBox.value = False Then UserForms(0).Controls("chkSelAll").value = False
End Sub
And the chkSelAll_Click sub:
Private Sub chkSelAll_Click()
Dim ctrl As Control
For Each ctrl In Me.Controls
If TypeName(ctrl) = "CheckBox" And Left(ctrl.Name, 1) = "M" Then
If chkSelAll.value = True Then
ctrl.value = True
Else
ctrl.value = False
End If
End If
Next
Set ctrl = Nothing
End Sub
Add a public variable, say blnBypassNonUIClick and set this, then when coming from the UI, by a human click set it to false, and when setting the select all the same. Your select all, shouldnt activate click if you're setting the .value by code. Something like this....
Public blnNonUI As Boolean
Private Sub CheckBox1_Click()
If Not blnNonUI Then
MsgBox "hello"
End If
End Sub
Private Sub UserForm_Click()
blnNonUI = True
Me.CheckBox1.Value = 1
blnNonUI = False
End Sub
Nathan_Sav gave me this idea and it works:
Public blnHumanClick As Boolean
Private Sub chkSelAll_Click()
If blnHumanClick = True Then
Dim ctrl As Control
For Each ctrl In Me.Controls
If TypeName(ctrl) = "CheckBox" And Left(ctrl.Name, 1) = "M" Then
If chkSelAll.value = True Then
ctrl.value = True
Else
ctrl.value = False
End If
End If
Next
Set ctrl = Nothing
blnHumanClick = False
End If
End Sub
Private Sub chkSelAll_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
blnHumanClick = True
End Sub

Remove shadow from ActiveX Option Button in Excel 2010 VBA

I was trying to emphasis the option button from activeX control when it is selected by user. I decided to show the shadow when it is selected and then hide the shadow when user selects other option button. The first process is working whereas the shadow cannot be removed even though I select other button. My VBA code is shown below:
Private Sub OptionButton1_Click()
OptionButton1.Shadow = False
If OptionButton1.Value = True Then
OptionButton1.Shadow = True
Else
OptionButton1.Shadow = False
End If
End Sub
Can anyone please help me to solve this?
In case of FORMS buttons you can use
Sub RemoveFormsButtonShadows()
'A.Leine 21/10/2015
For Each Button In ActiveSheet.Shapes
Button.Select
Selection.ShapeRange.Shadow.Visible = False
Next Button
End Sub
For that you have to create one sub which needs to be called from all the option buttons that you have. This common sub will simply remove the shadow from all option buttons. Here I am taking the example of 3 option buttons.
Option Explicit
Private Sub OptionButton1_Click()
RemoveShadow
If OptionButton1.Value = True Then _
OptionButton1.Shadow = True
End Sub
Private Sub OptionButton2_Click()
RemoveShadow
If OptionButton2.Value = True Then _
OptionButton2.Shadow = True
End Sub
Private Sub OptionButton3_Click()
RemoveShadow
If OptionButton3.Value = True Then _
OptionButton3.Shadow = True
End Sub
Sub RemoveShadow()
Dim objOpt As OLEObject
With ActiveSheet
For Each objOpt In .OLEObjects
If TypeName(objOpt.Object) = "OptionButton" Then
objOpt.Shadow = False
End If
Next
End With
End Sub