VBA: Checkbox in Userform - Should be simple but not working - excel

I am new to Visual Basics (2 days so far), and the only other programming I've done is MATlab.
I am trying to have the program print different numbers in different columns in Excel, depending if a checkbox in a userform is checked or not. There are 26 checkboxes in total - along with some textboxes - and I'm trying to use a For Each Control loop to run through all the checkboxes.
I've looked up a few tutorials and some forums, but when I try to run a test, the code doesn't work. More specifically, no errors show up but the "Testing if it Works?" is not printed anywhere.
Private Sub Add_Button_Click()
Dim Ctrl As Control
For Each Ctrl In DataInput.Controls
If TypeName(Ctrl) = "Checkbox" Then
If Ctrl.Value = True Then
Sheets("Data").Range("A1") = "Testing if it Works?"
End If
End If
Next
End Sub
I've followed the same setup as all the other forums or tutorials I've come across, but nothing seems to be happening. Any advice is appreciated.

EDIT: This answer only applies when putting checkboxes directly on the Excel sheets, not in a user form as was asked. Feel free to downvote!
I played around with it and it was not entirely simple at all. It's a bit different whether you're using Form controls or ActiveX controls. The code below works for me, though I'm not entirely sure they're the best ways.
With ActiveX controls:
Private Sub Add_Button_Click()
For Each Ctrl In ActiveSheet.OLEObjects
If TypeName(Ctrl.Object) = "CheckBox" Then
If Ctrl.Object = True Then
Sheets("Data").Range("A1") = "Testing if it Works?"
End If
End If
Next
End Sub
With Form controls
Private Sub Add_Button_Click2()
For Each Item In Me.Shapes
If Item.FormControlType = xlCheckBox Then
If Item.DrawingObject = 1 Then
Sheets("Data").Range("A1") = "Testing if it Works?"
End If
End If
Next
End Sub

Related

Combobox.dropdown in Excel shows outside the userform

I have created a userform and included a combobox populated with numbers 1 to x in userform.initialize and then added .setfocus and .dropdown commands. For some strange reason the combobox (with dropdown) appears on my lefthand screen outside the userform. The combobox also appears on the userform, but without the dropdown displayed. The screen combobox is active and if I click a number in the dropdown list the code accepts this input.
I have tried deleting the combobox and inserting another one with a different name, but the behaviour persists. If I remove the .dropdown command, the combobox appears correctly on the userform without the screen copy and I can click the userform box and display and use the dropdown list.
On reading an unrelated post, I tried adding .visible=false, followed by .visible=true before the .dropdown command, but that didn't stop the behaviour.
I have tried exporting, deleting and re-importing the userform, but the behaviour persists.
The code I am using (in userform_initialize sub) is:
With cbxGroup 'combobox
.Clear
For i = 1 To PlayGroups
.AddItem i
Next
.ListIndex = -1
.Visible = False
.Visible = True
.SetFocus
.DropDown
End With
Has anyone come across such behaviour before and can explain what has happened, and maybe how to fix it. I can just recreate the userform, but it seems a lot of unnecessary work. I am using Office 365
I can confirm the behaviour.
I strongly assume that this is related to the fact that you are using the Initialize-Trigger. When this trigger is executed, the form is still in the creation-process and some internal properties (eg the exact screen position) are likely not calculated. As a consequence, when calling DropDown, the Combobox is painted on the screen but not at the right position.
You can keep the code to fill the combobox in the Initialize-Trigger, but you should move the SetFocus and DropDown-commands to the Activate-Trigger
Private Sub UserForm_Initialize()
fillCombo
End Sub
Private Sub UserForm_Activate()
showCombo
End Sub
Sub fillCombo()
With Me.cbxGroup
.Clear
Dim i
For i = 1 To PlayGroups
.AddItem i
Next
.ListIndex = -1
End With
End Sub
Sub showCombo()
With Me.cbxGroup
.SetFocus
.DropDown
End With
End Sub

Checking textbox value in a multipage userform

I have a userform with multiple pages, each with textboxes that I want to make sure are numbers before I dump them back into a worksheet.
I have other normal userforms that do this:
Private Sub myTextBox_Exit(ByVal Cancel As MSForms.ReturnBoolean)
OnlyNumbers
End Sub
Private Sub OnlyNumbers()
If TypeName(Me.ActiveControl) = "TextBox" Then
With Me.ActiveControl
If Not IsNumeric(.Value) And .Value <> vbNullString Then
MsgBox "Sorry, only numbers allowed"
.Value = vbNullString
End If
End With
End If
End Sub
This works fine, but when I try to do something similar with this multipage userform it doesn't work.
I tried using
Me.ActiveControl.ActiveControl
but get a "Object doesn't support this property or method" run time error. This would work when the textboxes are inside a frame, but it seems like pages are not treated the same way.
Yeah, this one is tricky. The MultiPage control you can think of as the parent of the controls that sit on top of it. What you need to do is select the MultiPage control first, then select the active control from there.
It looks like:
Me.MultiPage1.Pages(Me.MultiPage1.Value).ActiveControl.Name
The Pages property allows you to select which page you want to select. You can get this by using the index of the MultiPage control (the Index starts at 1). Then you can call the ActiveControl and receive the expected control.
Hope it helps!

Limit to only 1 selected checkbox

I have imported a table with check-boxes from Access to Excel. Is it possible to set the check-boxes where only one check-box can be selected from that imported table when using Excel?
In the comments Jeeped made an excellent point that radio buttons already have the functionality that you are looking for. On the other hand -- if you prefer the aesthetics of checkboxes then you can certainly use them. I created a userform with two checkboxes in a frame (and no other controls in the frame) and also included a label for displaying the chosen option. The following code deselects all other checkboxes in the frame when one is selected. I used a non-local Boolean variable to circumvent the other checkbox's event handlers while they were being changed to avoid a sort of echo effect I ran into where the events were firing when I didn't want them to (perhaps there is a less kludgy way to do that). The code easily extends to any number of checkboxes in a grouping frame.
Dim selecting As Boolean 'module level variable
Private Sub SelectOne(i As Long)
Dim c As Control
selecting = True
For Each c In Frame1.Controls
If c.Name <> "CheckBox" & i Then c.Value = False
Next c
DoEvents
Label1.Caption = i & " selected"
selecting = False
End Sub
Private Sub CheckBox1_Click()
If Not selecting Then SelectOne 1
End Sub
Private Sub CheckBox2_Click()
If Not selecting Then SelectOne 2
End Sub
I think this works best and its much easier - at least for a few boxes - for more you could write some formulas in excel and drag down then copy as values and copy paste text from excel into vba. Anyway, here it's how I did it:
I went and created code under each button - quite basic
Private Sub DateCheckBox1_Click()
If DateCheckBox1.Value = True Then
DateCheckBox2.Value = False
DateCheckBox3.Value = False
End If
End Sub
Private Sub DateCheckBox2_Click()
If DateCheckBox2.Value = True Then
DateCheckBox3.Value = False
DateCheckBox1.Value = False
End If
End Sub
Private Sub DateCheckBox3_Click()
If DateCheckBox3.Value = True Then
DateCheckBox2.Value = False
DateCheckBox1.Value = False
End If
End Sub

Excel VBA Drag and Drop

I'm having some difficulty finding a workable solution (been looking for 2 days now).
Hopefully you can help me figure it out.
Purpose - I'm trying to use VBA to drag and drop text between listboxes
(see image)
Note: I know there are Pivot Wizards already, I'm not so interested in them (long story)
Question
Is there any solution that you know of that could help me move "Column A" to any of the other listbox?
If you don't know of a solution, a blog or site might be helpful as well.
Further to my comments above here is the most simple way to do it.
Create a Userform with 2 Listboxes and 1 Command Button as shown in the below image.
And paste this code in the Userform Code area
Dim i As Long
Private Sub UserForm_Initialize()
For i = 1 To 10
ListBox1.AddItem i
Next i
End Sub
Private Sub CommandButton1_Click()
If ListBox1.ListIndex = -1 Then
MsgBox "Please select an item from listbox1"
Exit Sub
End If
ListBox2.AddItem ListBox1.List(ListBox1.ListIndex)
ListBox1.RemoveItem (ListBox1.ListIndex)
End Sub
HTH

Bugs in Excel's ActiveX combo boxes?

I have noticed that I get all sorts of annoying errors when:
I have ActiveX comboboxes on a worksheet (not an excel form)
The comboboxes have event code linked to them (eg, onchange events)
I use their listfillrange or linkedcell properties (clearing these properties seems to alleviate a lot of problems)
(Not sure if this is connected) but there is data validation on the targeted linkedcell.
I program a fairly complex excel application that does a ton of event handling and uses a lot of controls. Over the months, I have been trying to deal with a variety of bugs dealing with those combo boxes. I can't recall all the details of each instance now, but these bugs tend to involve pointing the listfillrange and linkedcell properties at named ranges, and often have to do with the combo box events triggering at inappropriate times (such as when application.enableevents = false). These problems seemed to grow bigger in Excel 2007, so that I had to give up on these combo boxes entirely (I now use combo boxes contained in user forms, rather than directly on the sheets).
Has anyone else seen similar problems? If so, was there a graceful solution? I have looked around with Google and so far haven't spotted anyone with similar issues.
Some of the symptoms I end up seeing are:
Excel crashing when I start up (involves combobox_onchange, listfillrange->named range on another different sheet, and workbook_open interactions). (note, I also had some data validation on the the linked cells in case a user edited them directly.)
Excel rendering bugs (usually when the combo box changes, some cells from another sheet get randomly drawn over the top of the current sheet) Sometimes it involves the screen flashing entirely to another sheet for a moment.
Excel losing its mind (or rather, the call stack) (related to the first bullet point). Sometimes when a function modifies a property of the comboboxes, the combobox onchange event fires, but it never returns control to the function that caused the change in the first place. The combobox_onchange events are triggered even when application.enableevents = false.
Events firing when they shouldn't (I posted another question on stack overflow related to this).
At this point, I am fairly convinced that ActiveX comboboxes are evil incarnate and not worth the trouble. I have switched to including these comboboxes inside a userform module instead. I would rather inconvenience users with popup forms than random visual artifacts and crashing (with data loss).
I don't have a definitive answer for you, but I can tell you that I stopped using ListFillRange and LinkedCell for ActiveX controls about 10 years ago. I don't recall what particular problems I encountered. I just remember coming to the conclusion that whatever little time they saved me isn't worth the brain ache of trying to track down the bugs. So now I populate the controls through code and deal with output in the events.
My active-x combo box works fine when my Dell is docked but resizes to a larger font each time it is clicked when the Dell is undocked - very strange. I added resizing code which works when undocked, but both .height and .scaleheight fail when docked and when triggered programmatically (even stranger).
Sheet2.Shapes("cb_SelectSKU").Select
Selection.ShapeRange.Height = 40
Selection.ShapeRange.ScaleHeight 0.8, msoFalse, msoScaleFromTopLeft
I then added my own enableevents-like switch so that the resizing only occurs when a user selects a combobox value, not when anything is affected while a macro is running.
Select Case strHoldEvents
Case Is = "N" 'Combobox resizing fails with error when triggered programatically (from SaveData)
Call ShowLoadShts
Sheet2.Shapes("cb_SelectSKU").Select
Selection.ShapeRange.Height = 40
Selection.ShapeRange.ScaleHeight 0.8, msoFalse, msoScaleFromTopLeft
Case Else
End Select
Finally that seems to work, whether docked or undocked, whether triggered by the user or during a procedure. We'll see if it holds...
I have a partial reply for the Dell users, and for your formatting problem
The formatting and display problem is another known-but-undocumented issue in Excel.
Many flat-panel monitors (including laptop displays) are unable to render fonts correctly in textbox controls on an Excel spreadsheet: you've got a mild version of this problem.
Our company has recently upgraded to new (and much larger!) monitors, and I can at last use textboxes, labels and combo boxes in worksheets. Our old Samsung screens displayed text controls correctly, but any manual or VBA-driven updates resulted in an illegible jumble of overlapping characters.
Listboxes don't have the problem: it's the 'textbox' part of your combo box that has the issue. Try manipulating a listbox in VBA event procedures: it's a kludge but it works.
In-Cell dropdowns from Data Validation lists don't have the problem. If you set up a validation list for a cell, then set the data validation error messages to empty strings, you can enter free-form text in the cell; the drop-down list is advisory, not a mandatory limit-to-list.
The problem is sometimes ameliorated (but never completely fixed) by using the Terminal or System fonts in your Active-X control.
The problem is sometimes ameliorated (but never completely fixed) by using a VBA event to nudge or resize your Active-X control by 0.75 mm.
Check if your laptop manufacturer has released an upgrade to the display drivers.
...And that's everything I know about the font rendering problem. If Mike (with his Dell laptop) is reading this: Good luck with those workarounds - to the best of my knowledge, there's no real 'fix'.
The stability problem was a major headache for me until Excel 2003 came out: using any Active-X control in the sheet was a source of instability. The Jury's still out on Listbox controls embedded in a sheet, even in Excel 2003: I still avoid using them.
So I was facing the same issues. I had a file with drop down lists on which I had superimposed the combobox to fight the issue of illegibility when zooming out too much. This was what my code looked like INITIALLY:
'=========================================
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim str As String
Dim cboTemp As OLEObject
Dim ws As Worksheet
Set ws = ActiveSheet
On Error GoTo errHandler
If Target.Count > 1 Then GoTo exitHandler
Set cboTemp = ws.OLEObjects("ComboBox1")
On Error Resume Next
If cboTemp.Visible = True Then
With cboTemp
.Top = 10
.Left = 10
.ListFillRange = "Treatment"
.LinkedCell = Target.Address
.Visible = False
.Value = ""
End With
End If
On Error GoTo errHandler
If Target.Validation.Type = 3 Then
'if the cell contains a data validation list
Application.EnableEvents = False
'get the data validation formula
str = Target.Validation.Formula1
str = Right(str, Len(str) - 1)
With cboTemp
'show the combobox with the list
.Visible = True
.Left = Target.Left
.Top = Target.Top
.Width = Target.Width + 15
.Height = Target.Height + 5
.ListFillRange = ws.Range(str).Address
.LinkedCell = Target.Address
End With
cboTemp.Activate
'open the drop down list automatically
Me.ComboBox1.DropDown
End If
exitHandler:
Application.ScreenUpdating = True
Application.EnableEvents = True
Exit Sub
errHandler:
Resume exitHandler
End Sub
'====================================
'Optional code to move to next cell if Tab or Enter are pressed
'from code by Ted Lanham
'***NOTE: if KeyDown causes problems, change to KeyUp
'Table with numbers for other keys such as Right Arrow (39)
'https://msdn.microsoft.com/en-us/library/aa243025%28v=vs.60%29.aspx
Private Sub ComboBox1_KeyDown(ByVal _
KeyCode As MSForms.ReturnInteger, _
ByVal Shift As Integer)
Select Case KeyCode
Case 9 'Tab
ActiveCell.Offset(0, 1).Activate
Case 13 'Enter
ActiveCell.Offset(1, 0).Activate
Case Else
'do nothing
End Select
End Sub
'====================================
I was facing all sorts of issues but as primarily mentioned on this thread, the LinkedCell issue was the biggest. My selection from the drop down menu would go wherever on the sheet I had clicked last, instead of the cell I had chosen the drop down box from, and in process, also disturbing the code of wherever the selection would go. I used a simple ONE LINE code to make sure my program in ActiveX runs only when its a drop down menu. I used this before the LinkedCell command ran:
If Target.Validation.Type = 3 Then
'... all the normal code here...
End If
So my code now looks like this:
'... Code as before
If Target.Validation.Type = 3 Then
' NEW CODE LINE ABOVE
If Target.Count > 1 Then GoTo exitHandler
Set cboTemp = ws.OLEObjects("ComboBox1")
On Error Resume Next
If cboTemp.Visible = True Then
With cboTemp
.Top = 10
.Left = 10
.ListFillRange = "Treatment"
.LinkedCell = Target.Address
.Visible = False
.Value = ""
End With
End If
End If
' End of the new If
Unbelievably, this worked. And now my excel sheet isn't misbehaving anymore. Hope this helps.
For this reason, I use cells with data validation lists when putting combo boxes on a spreadsheet.

Resources