excel vba listbox additem - excel

I am running office 365 home on windows 10. I am programming Excel using VBA.
I have a data range in a worksheet row. I want the user to be able to select one item from this row of data. I am trying to populate ListBox or ComboBox with dta from the range row. Having read MS vba.reference documentation I decided to get my range data into an array and use listbox = myarray() and got "Object does not support this method or property." I tried looping through my data range and putting each item in using listbox.additem (mydata()) with the same result. On examination of the listbox prperties AddItem is not there. Seems they have been withdrawn or maybe never existed for Excel VBA.
Any suggestions?

If you are using Additem then you should only add a single item not an array. If you want to use an array you have to use List and the array should be one-dimensional
MyListBox.List=MyOneDArray
Personally I never use .List and an array with Listboxes because I found some circumstances in which it did not work as expected.

There are two ways you can do this:
loop through each item individually and use combobox.additem
Set the combobox.list = array (or variant)
See below for an example of both assuming you want to populate the data from cells A1 to A10 in 2 separate comboboxes:
Private Sub UserForm_Initialize()
Dim i As Integer
Dim arr As Variant
' looping through parameters 1-by-1
With UserForm1.ComboBox1
For i = 1 To 10
.AddItem ThisWorkbook.Sheets("Sheet1").Range("A" & i).Value
Next i
End With
' setting combobox list to arrauy
With UserForm1.ComboBox2
.List = ThisWorkbook.Sheets("Sheet1").Range("A1:A10").Value
End With
End Sub
Make sure to insert your code in the userform code and not the module code

Related

How to remove item from combobox in a userform?

I have a list of names in a sheet. I set these names as my RowSource for a combobox on a useform.
There are two Comboboxes involved. One starts full, the other starts empty.
I want when I click on a name from the first (full) combobox, said name to be added to the other combobox, and removed from the original combobox (and vice versa eventually).
I can't remove anything with RemoveItem.
I went the 'Menu.ListeAjoutAg.ListIndex' way to get my current selection's index ('Menu' is the UserForm and 'ListeAjoutAg' is the combobox), but it did not work.
Tried inputting through a variable I created real quick, 'b', but same result. No index number works. I checked and I only feed the function integers (0, 1, 3, 4...) that are correct and/or well within the scope of my list (about 45 names).
Private Sub ListeAjoutAg_Change()
a = Menu.ListeAjoutAg.Text
b = Menu.ListeAjoutAg.ListIndex
Menu.ListeRetirer.AddItem (a) ' goes fine till there
Menu.ListeAjoutAg.RemoveItem (b) 'and here it goes wrong
Menu.ListeRetirer.Enabled = True
Menu.ListeRetirer.Visible = True
End Sub
As already mentioned: You can't add or remove items from a Listbox if you have set the Rowsource property.
However, it is rather easy to fill a Listbox from a range - simply copy the cell values into an array and assign the array as List. See for example VBA Excel Populate ListBox with multiple columns
Put the following routine into your form and call it from the form Activate event.
Private Sub fillListBox(r As Range)
Me.ListeAjoutAg.Clear
Me.ListeAjoutAg.ColumnCount = r.Columns.Count
Dim data
data = r.Value
Me.ListeAjoutAg.List = data
End Sub
Private Sub UserForm_Activate()
Dim r As Range
' Replace this with the range where your data is stored.
Set r = ThisWorkbook.Sheets(1).Range("A2:C10")
fillListBox r
End Sub

Excel Combobox VBA issues multiple items

I have a dynamic range in a combo box that I use as an index with several concat formulas in the workbook. I fill the box on dropbuttonclick with
Private Sub ComboBox1_DropButtonClick()
'Updates on drop down
'This place row number in H3 making the dynamic vba combo box work like form control
Sheets("Home").Shapes("ComboBox1").Select
With Selection
.ListFillRange = "ParticipantData!$A$3:$A$" & Sheets("ParticipantData").Range("A3").End(xlDown).Row
lngrow = ActiveSheet.ComboBox1.ListIndex + 1
Range("H3") = lngrow
End With
End Sub
The issue is when I delete a value from Column A it throws a 438 error on me. The range changes quite often and I'd like to be able to add & delete and names as necessary. I typically copy and past values from a census and need to eliminate the .listfilRange 438 erro. I use the combobox to select a name which pulls data, generates a report and ultimate is saved as a pdf. lngrow is used as the row for the index of a dynamic range PartData in shee "ParticipantData".
Edit: Removed 2nd question
I know I have rofl vba skills, so thank you for your time helping me.

ComboBox list throgh Range in sheet

In userform I inserted ComboBox and i have to add list through Array following are the code. I want that whether it is possible that in ComboBox list will get from a Range in sheet (like in case of Data Validation)
Private Sub UserForm_Initialize()
ComboBox1.List = Array("Item1", "Item2", "Item3", "Item4")
End Sub
you can use the range in the sheet to create, even a named range, e.g.:
combobox1.list = range(cells(1,1),cells(100,1)).value
combobox2.list = sheets(1).range("NamedRange")
arr = array("1","2","3")
combobox3.list = arr
This is how you'd use a range to set the row source of a combo box. You can also do this in vba.
Me.combobox1.RowSource = "MyRange"
You can set this to a Table (ListObject) instead of a static range. Create a Table with your list of values, instead of just using a static range of cells. This way when you need to add to the list, you simply enter the new values, which are added to the Table. In my example, I have a Table named "Table1" and a column with the heading "Numbers". Then call this function:
Private Sub UserForm_Initialize()
ComboBox1.RowSource = "=Table1[Numbers]"
End Sub
You have to do this on the Iniitalize, since setting the RowSource from the ComboBox Properties will cause Excel to crash the first time you add an item to your list.
This gives you a list that you can edit without having to edit the code behind the UserForm.

Excel VBA: Selecting a range from a worksheet and use this data inside a form

I am trying to use a range to populate my combobox inside a form I've created. Now I can statically add items using the addItem method, but what if I have tables across various worksheets that contain the description and values - and want to use these as the source for the form.
Any clue?
Dim c
For Each c In Range("A1:A4")
ComboBox1.AddItem c.Value
Next
Hope this helps.

Dynamically set ListFillRange in Excel ComboBox

I tried doing something like:
cmbMyBox.ListFillRange = "E2"
But the combobox does not seem to populate.
First of all, for trying to set the listfillrange from VBA, you need to include the '=' sign, like this:
combobox.ListFillRange = "=E3:E13"
and not combobox.ListFillRange = "E3:E13", this won't work.
You could have a dynamic named range, for example:
listItems: "=Sheet1!$A$1:INDEX(Sheet1!$A:$A;COUNTA(Sheet1!$A:$A))"
Use VBA to set the ListFillRange like this: combobox.ListFillRange = "=listItems"
Again, use the '=' sign!!
This dynamic range listItems grows/shrinks dynamically, depending on what values you have in column A.
I know I'm answering really late, but I noticed a lot of people thinking named ranges always have to be fixed, while they can be dynamic as well...
How do you do this?
In Excel 2007 and higher, you go to the ribbon-tab "Formulas" and click on the button "Name Manager"
Instead of selecting cells and giving them a name in that upper-left box, you can manage all your defined named ranges here.
Create a new one, and give it the value (without quotes):
"=Sheet1!$A$1:INDEX(Sheet1!$A:$A;COUNTA(Sheet1!$A:$A))".
There you go...
P.S. When you let the dynamic named range change, you should use VBA to re-set the .ListFillRange such that the combobox will refresh its list-items.
Ok, don't mean to answer my own question again but this ListFillRange property on combobox for Excel was absolutely maddening. Here's the final code that I implemented.
Sheet1.Range("E3").CurrentRegion.Select
Dim example as Range
Set example = Selection
With cmbMyBox
.ListFillRange = example.Address(0, 0, x1A1, True)
End With
The trouble here was that I was trying to dynamically set the combobox using a dynamic range which changes depending on what user inputted values were given. As far as I understand I couldn't use a named range because named ranges are FIXED, e.g (A3:Z20) and cannot be adjusted.
I was facing similar issue, not being able to populate the ActiveX ComboBox with list reference peeked from a cell's validation rule.
Similarly to Firedrawndagger's own solution I went for manually translating the validation rule to a format that is understood by the .ListFillRange.
I realised also, that it needs to be in a Workbook-scope format, otherwise the call will not work from other sheets.
This works with All validation source formats, including: $A$1 / =NamedRange / =INDIRECT("Table1[Col2]")
The translation was:
Dim xStr As String
xStr = Target.Validation.Formula1
xStr = Right(xStr, Len(xStr) - 1)
xStr = Split(Range(xStr).Address(, , , True), "]")(1)
'...other irrelevant code
.ListFillRange = xStr
Private Sub ComboBox1_Change()
Me.ComboBox2.ListFillRange = "=" & ComboBox1.Value
End Sub
This also works. But you have to do either the defined names with the index and counta as already suggested, or you can refer to them twice while in a table. What I mean by that, is make your data a table. Refer to the column you want as the title of your option from Combobox1 and add a one to the name, For example Fruits1, then define a secondary named range that refers to Fruits1 and is called Fruits.
Fruits
Fruits1
Alternatively, this is how I do it:
Define a range name that includes header and trailer rows plus one data row to start, say "DataList"
Then define the following data range name sans the header and trailer records using the offset function.
Say "DataRange" = Offset(DataList,1,0,Rows(DataList)-2)
This is working fine on Excel 2010:
I have a list of items in column "AN" that changes (get bigger/shorter) every week. I have created a variable called "c" which contains the number of items in the list. By using this variable, the ComboBox (positioned on cells S7:U7) will now dinamically show the items actually contained in the list (no empty spaces or missing items in the combobox).
Code:
Dim rng As Range
Set rng = ActiveSheet.Range("S7:U7")
ActiveSheet.DropDowns.Add(rng.Left, rng.Top, rng.Width, rng.Height).Select
With Selection
.ListFillRange = "AN1:AN" & c
.LinkedCell = "$V$7"
.DropDownLines = 8
.Display3DShading = False
End With
I had a similar problem, i had an ActiveX Listbox in the worksheet. What worked for me is this:
Sheets(1).OLEObjects("ListBox1").ListFillRange = "Sheet2!A1:C20"
ActiveX OLEObjects are pretty straight forward.

Resources