Getting a value from ComboBox - vba

I have created a combo-box via VBA code.
Sub CreateFormControl()
ActiveSheet.DropDowns.Add(0, 0, 100, 15).Name = "ComboBox1"
ActiveSheet.Shapes("ComboBox1").ControlFormat.RemoveAllItems
Dim i As Integer
With ActiveSheet.Shapes("ComboBox1").ControlFormat
For i = 1 To 25
.AddItem i
Next i
End With
ActiveSheet.Shapes.Range(Array("ComboBox1")).Select
Selection.OnAction = "ComboBox1_Change"
Range("B2").Select
End Sub
The problem here is, when I select an item in the ComboBox, it gives me a
Run-time error 424. Object required
It doesn't show the value selected. I also tried to change my declaration, Sub CreateFormControl() to Public Sub CreateFormControl(), but it's still not working.
Sub ComboBox1_Change()
MsgBox (ComboBox1.Value) 'The error is here
End Sub

Try the code below, try to replace ActiveSheet with a qualifed Worksheet, like Worksheets("YoutSheetName").
Sub ComboBox1_Change()
Dim ws As Worksheet
Dim MyDropDown As DropDown
' try not to use ActiveSheet, replace "Sheet1" with your sheet's name
Set ws = Worksheets("Sheet1") ' ActiveSheet
Set MyDropDown = ws.Shapes("ComboBox1").OLEFormat.Object ' <-- set my Object with "ComboBo1" drop-down
MsgBox MyDropDown.List(MyDropDown.ListIndex) '<-- display the value of the selected item
End Sub
Below is a "cleaner" way to add a new DropDown to a Worksheet without using ActiveSheet, Select and Selection (just use fully qualified objects).
Sub CreateFormControl Code
Option Explicit
Sub CreateFormControl()
Dim MyDropDown As DropDown
Dim i As Long
' set the drop-down object to the new created drop-down (replace "Sheet1" with your sheet's name)
Set MyDropDown = Worksheets("Sheet1").DropDowns.Add(0, 0, 100, 15)
' modify the drop-down properties
With MyDropDown
.Name = "ComboBox1"
.RemoveAllItems
For i = 1 To 25
.AddItem i
Next i
.OnAction = "ComboBox1_Change"
End With
End Sub

Related

ComboBox trying to set selected item results in Compile error

I'm trying to select an item in a ComboBox in a UserForm. I found the .Selected(index)=True code almost everywhere but for me it sais:
Compile error: Method or data member not found.
My code:
Private Sub UserForm_Initialize()
Dim worksheetList As New ArrayList
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
worksheetList.Add ws.Name
Next ws
sourceWorksheets.List = worksheetList.toArray
destinationWorksheets.List = worksheetList.toArray
sourceWorksheets.Selected(1) = True 'Error here
End Sub
Am I doing something wrong? I couldn't really find any other function which would set the "default" item.
As #Rory keeps saying - use ListIndex to select an item in the list control.
This piece of code will add each sheet name to the list control and then select the first item:
Private Sub UserForm_Initialize()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
Me.worksheetList.AddItem ws.Name
Next ws
Me.worksheetList.ListIndex = 0
End Sub
I think the OP was trying to use the code similar to below, but this still needs the ListIndex=0.
Private Sub UserForm_Initialize()
Dim ws As Worksheet
With CreateObject("System.Collections.ArrayList")
For Each ws In ThisWorkbook.Worksheets
.Add ws.Name
Next ws
Me.worksheetList.List = .ToArray
End With
Me.worksheetList.ListIndex = 0
End Sub
Edit: The code assumes the list control is called worksheetList.
Edit 2: A slightly different version. It reverses the items in the list when you click the form.
It's still Me.worksheetList.ListIndex = 0 to select the item in the list control though.
Option Explicit
Public MyArrayList As Variant
Private Sub UserForm_Initialize()
Dim ws As Worksheet
Set MyArrayList = CreateObject("System.Collections.ArrayList")
With MyArrayList
For Each ws In ThisWorkbook.Worksheets
.Add ws.Name
Next ws
.Sort
Me.worksheetList.List = .ToArray
End With
Me.worksheetList.ListIndex = 0
''This will only work in a listbox, not a combobox.
''Select items in row numbers that are even (ListIndex 0,2,4, etc)
''MultiSelect must be 1 - fmMultiSelectMulti or 2 - fmMultiSelectExtended
' Dim x As Long
' For x = 0 To Me.worksheetlist.ListCount - 1
' If x Mod 2 = 0 Then
' Me.worksheetlist.Selected(x) = True
' End If
' Next x
End Sub
Private Sub UserForm_Click()
With MyArrayList
.Reverse
Me.worksheetList.List = .ToArray
End With
Me.worksheetList.ListIndex = 0
End Sub
To check whether particular element (indicated by index) is selected you should do workaround like this:
ComboBox1.Value = ComboBox1.List(i)
where i is given index. It has to be done like that, because there is no propertry like SelectedIndex in VBA ComboBox.
Keep in mind, that indexing starts with 0 !

VBA - Hide certain column in every worksheet of workbook when checkbox is not selected

I am trying to hide every "A" column in my workbook when a certain checkbox in my user form is not selected.
I have 6 worksheets in my one workbook.
I have 6 checkboxes.
When a checkbox is not selected, I'd like to hide the column that it's associated with.
Ex: When the "Advice" checkbox is not checked, I'd like to hide the "A" column in EVERY worksheet in my workbook.
Thank you!
I tried this:
shtFinancial.Range("D").EntireColumn.Hidden = Not cbAdvice.Value
And this:
If cbAdvice.Value = True Then
shtFinancial.Range("D").EntireColumn.Hidden
Checkboxes in VBA are really funky. Here is one method:
Sub cbAdvice_Click()
Dim CheckBox As Shape, ws As Worksheet
Set CheckBox = Sheet1.Shapes("cbAdvice")
For Each ws In ActiveWorkbook.Worksheets
If CheckBox.OLEFormat.Object.Value = 1 Then
ws.Columns("A:A").EntireColumn.Hidden = False
Else
ws.Columns("A:A").EntireColumn.Hidden = True
End If
Next ws
End Sub
I created two active x control boxes "CheckboxColA" and "CheckboxColB" and gave them the following code for a change of state:
Sheet1("Worksheet Controls")
Private Sub CheckboxColA_Change()
Call changeColAVisiblity(CheckboxColA.Value, "A")
End Sub
Private Sub CheckBoxColB_Change()
Call changeColAVisiblity(CheckBoxColB.Value, "B")
End Sub
Then created the following code in "module1"
Sub changeColAVisiblity( _
cbState As Boolean, _
changeColumn As String)
Dim ws As Worksheet
For Each ws In ActiveWorkbook.Worksheets
'If statement Assumes sheet with contols should not change
If ws.Name <> "CheckBox Controls" Then
ws.Columns(changeColumn).Hidden = cbState
End If
Next
End Sub

Excel VBA user form to display the sheet which is selected

I have created a userform which has a listbox (ListBox1)which list down the sheet names and I can double click on the list and it will take me to that sheet. I have a back button (CommandButton2) when I click on back button it will take me to the previous selected sheet.
I want to link my list box and back button so that when I click on back button the my listbox (ListBox1)should highlight the sheet where my back button (CommandButton2) has directed to.
Please find below my codes:
Private Sub UserForm_Initialize()
Dim Sh As Worksheet
'for each loop the add visible sheets
For Each Sh In ActiveWorkbook.Sheets
'add sheets to the listbox
Me.ListBox1.AddItem Sh.Name
Next Sh
End Sub
Private Sub ListBox1_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
'declare the variables
' modifed code for ListBox double-click event, store the sheet name before switching to the selected item
Dim i As Long
LastSelectedSht = ActiveSheet.Name ' <-- save the current active sheet before selecting a new one
For i = 0 To ListBox1.ListCount - 1
If ListBox1.Selected(i) Then
Worksheets(ListBox1.List(i)).Activate
End If
Next i
End Sub
Private Sub CommandButton2_Click()
Dim TmpSht As String
TmpSht = ActiveSheet.Name ' <-- save the current active sheet
' select the previous sheet (stored in LastSelectedSht)
If LastSelectedSht = "" Then
MsgBox "Error, no sheet stored , is it your first time running ? "
Else
Sheets(LastSelectedSht).Select
End If
LastSelectedSht = TmpSht ' <-- use the temp variable to store the latest active sheet
' reset the userform
Unload Me
frmNavigation.Show
End Sub
No need for al those loops to seek selected item, you can simplify things a bit as follows:
Option Explicit
Dim LastSelectedSht As String '<--| use as UserForm scoped variable to store the name of "last" sheet selected
Private Sub UserForm_Initialize()
Dim Sh As Worksheet
With Me.ListBox1
'for each loop the add visible sheets
For Each Sh In ActiveWorkbook.Sheets
.AddItem Sh.Name 'add sheets names to the listbox
Next Sh
LastSelectedSht = ActiveSheet.Name ' <-- store the currently active sheet name as the "last" one
.Value = LastSelectedSht '<--| initialize listbox selection with the currently active sheet name
End With
End Sub
Private Sub ListBox1_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
' modifed code for ListBox double-click event, store the sheet name before switching to the selected item
LastSelectedSht = ActiveSheet.Name
Worksheets(ListBox1.Value).Activate '<--| activate the sheet whose name has been dblclicked
End Sub
Private Sub CommandButton2_Click()
Sheets(LastSelectedSht).Activate
Me.ListBox1.Value = LastSelectedSht
' reset the userform
Unload Me
frmNavigation.Show
End Sub
This sub will change the selected item in the list box.
Private Sub SetListBox(Lbx As MSForms.ListBox, _
Itm As String)
Dim i As Integer
With Lbx
For i = 0 To .ListCount - 1
.Selected(i) = Not CBool(StrComp(.List(i), Itm))
Next i
End With
End Sub
Call it from your procedure which activates the previous worksheet with a line of code like this one.
SetListBox ListBox1, TmpSht
Make sure that TmpSht holds the name of the newly activated sheet at the time you make the call or pass the name of that sheet instead of TmpSht.

Refresh combo box after list update vba excel

I'm trying to auto update a combobox list. It updates correctly only when I close and then open the workbook, or when I press the stop button on VBA and run the macro again. I have the following VBA code.
Private Sub UserForm_Initialize()
Dim cod As Range
Dim pro As Range
Dim cli As Range
Dim ws As Worksheet
Dim ws5 As Worksheet
Set ws = Worksheets("ListaProductos")
Set ws5 = Worksheets("ListaClientes")
For Each cod In ws.Range("CodigoProductoLista")
With Me.codigo
.AddItem cod.Value
.List(.ListCount - 1, 1) = cod.Offset(0, 1).Value
End With
Next cod
For Each cli In ws5.Range("ClienteLista")
With Me.cliente
.AddItem cli.Value
.List(.ListCount - 1, 1) = cli.Offset(0, 1).Value
End With
Next cli
No.Value = True
calendario2.Visible = False
calendario2.Refresh
calendario = Date
Me.codigo.SetFocus
End Sub
Thanks!
You could call the UserForm_Initialize procedure again, but you will have to clear the lists first. You could use it in a commandbutton, or in an event for instance.
That Initialize event will only trigger when the form is loading. Add a button to your form called cmdRepopulate and use this code instead:
Option Explicit
Private Sub UserForm_Initialize()
PopulateCodigoProductoLista
PopulateClienteLista
FinishingOff
End Sub
Private Sub PopulateCodigoProductoLista()
Dim rngData As Range
With Worksheets("ListaProductos").Range("CodigoProductoLista")
Set rngData = .Resize(.Rows.Count, 2)
End With
PopulateComboUsingRange Me.codigo, rngData
End Sub
Private Sub PopulateClienteLista()
Dim rngData As Range
With Worksheets("ListaClientes").Range("ClienteLista")
Set rngData = .Resize(.Rows.Count, 2)
End With
PopulateComboUsingRange Me.cliente, rngData
End Sub
Private Sub FinishingOff()
No.Value = True
calendario2.Visible = False
calendario2.Refresh
calendario = Date
Me.codigo.SetFocus
End Sub
Private Sub PopulateComboUsingRange(cboDataDestination As MSForms.ComboBox, _
rngDataSource As Range)
Dim lngCounter As Long
With cboDataDestination
.Clear
For lngCounter = 1 To rngDataSource.Rows.Count
.AddItem rngDataSource.Cells(lngCounter, 1)
If rngDataSource.Columns.Count = 2 Then
.List(.ListCount - 1, 1) = rngDataSource.Cells(lngCounter, 2)
End If
Next
End With
End Sub
Private Sub cmdRepopulate_Click()
PopulateCodigoProductoLista
PopulateClienteLista
FinishingOff
End Sub
There are some limitations (because it's too late), notably the generic combo population routine but in its current for it should be good for you. The code will run on the form's Initialize event and whenever you click the repopulate button. I decided to work with your named ranges as they were - no changes.
Note the use of a generic proc to populate the combo. If you had other combos on other forms in this same workbook, you could move that proc to a separate module, change it to Public (rather than Private) and save yourself a lot of typing by reusing the code.

Selecting a range by mouse and setting parameters

I am trying to do the following with Excel 2010 VBA:
set a toggle button on a form.
move to the worksheet
use the mouse to select groups (range) of cells
set a cell parameter (background colour) to the back colour of the toggle button
.
.
.
continue select cells or deselect the toggle button.
What I have so far is this but I get a global range error on the line setting the colour:
Public Sub ToggleButton1_Click()
Dim ActRange As Range
Dim ActSheet As Worksheet
Dim bgndColour As Variant
bgndColour = ToggleButton1.BackColor
Set ActSheet = ActiveSheet
Set ActRange = Selection
ActSheet.Select
ActRange.Select
Range(ActRange).Interior.Color = bgndColour
End Sub
ActRange is already a range. No need to use the Range() object
Try this
ActRange.Interior.Color = bgndColour
Your code can be reduced to
Public Sub ToggleButton1_Click()
If TypeName(Selection) <> "Range" Then
MsgBox "Select a range first."
Exit Sub
End If
Selection.Interior.Color = ToggleButton1.BackColor
End Sub
I dont like to add inecesary lines, I see you can resume your code in
Selection.Interior.Color = bgndColour
if that is not working what is wrong is your bgndcolour variable