How to remove item from combobox in a userform? - excel

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

Related

excel vba listbox additem

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

Evaluating use of INDIRECT function taken from Cell Validation

I have a number of cells which have validation lists that are based on the use of the INDIRECT function. In this case there are two variables - one is the currently selected State (as reference through the named range dtState) and another based on a separate selection already made by the user in a different cell. The function in the Validation List for the cell is:
=INDIRECT("dtHdrPlates"&dtSize&dtState)
dtsize : could equal "70" or "90"
dtState : couldequal "VIC" or "QLD"
Naturally there is a named range for all combination of "dtHdrPlates" and the possible options of dtSize and dtState. The INDIRECT function in the Cell Validation list gives me a list that changes based on the selections in other cells.
dtHdrPlates70VIC
dtHdrPlates90VIC
dtHrdPlates70QLD
dthrdPlates90QLD
This works well thanks to advice previously obtained in this forum - thanks!
I am now trying to implement the use of a Combo Box over top of this cell, positioned, populated, made visible, activated and if relevant, dropped down by VBA Code; and removed once the use leaves the control.
Where I'm currently stuck is populating the ListFillRange of the ComboBox in the sheet - based on the INDIRECT function in the Validation.Formula1 of the cell the combo box is intended to supplant.
Sub BuildComboBox(rngCell as Range)
' This procedure checks to see if the Cell concerned is a list, and if so creates a combobox over top of the cell with the appropriate contents.
Dim rngCell as Range ' the cell concerned
Dim ws as Worksheet
Dim Dim cbo As OLEObject
If rngCell.Validation.Type = xlValidateList Then
Set ws = Excel.ActiveSheet
Set cbo = ActiveSheet.OLEObjects("ComboBox")
cbo.Left = rngCell.Left
cbo.Top = rngCell.Top
cbo.Width = rngCell.Width
cbo.Height = rngCell.Height
CBO.LISTFILLRANGE = RNGCELL.VALIDATION.FORMULA1
cbo.LinkedCell = rngCell.Address
If rngCell.Validation.ShowError = True Then
CBO.MATCHREQUIRED = TRUE
Else
CBO.MATCHREQUIRED = FALSE
End If
cbo.Visible = True
cbo.Activate
If rngCell.Value2 = "" Then
CBO.DROPDOWN
End If
End If
End Sub
I am stuck in three places in the above code (where the code is in CAPITALS).
What I would like to solve at the moment is how to get the indirect function taken from the cell validation list (rngCell.Validation.Formula1) and have it converted to the named range acceptable to cbo.ListFillRange - at the moment it comes across as =INDIRECT("dtHdrPlates"&sglLBWWallThickness&dtState) which does not work.
I've been playing with the EVALUATE function but just can't get it to parse the text coming from the Validation.formula1
If while you're looking at this you could also steer me towards how to change the status of an ActiveX ComboBox's MatchRequire property - and how to force it to DropDown, that would be lovely too.
Thanks, Regards, Ken

Selected row in listbox copied to another listbox

I have a listbox within a userform with a few rows of filtered data. I would like to be able to select one of the rows and have it appear in another listbox (just the values within that selected row, none of the others)
My current code is just:
Private Sub SelectHousingList_Click()
HousingList.Text = SelectHousingList.Selected(Row)
End Sub
With 'HousingList' being the listbox that I'd like the values to move to.
And 'SelectHousingList' being the rows of filtered data.
Previously in this code I've used code similar to this to select from a list of values (but not with a whole row of values).
Private Sub MaterialList_Click()
SelectedMaterialText.Value = MaterialList.Text
Worksheets("FSC PSC PFC").Range("D4").Value = SelectedMaterialText.Value
End Sub
The second line of code allows for the selected item in the list to be copied to a textbox.
If you need more of my code I can supply you with it.
This may be a simple question but I can't seem to find the answer anywhere or figure out code that allows it to happen.
Thank you in advance!
If I understand your requirements, this should do what you need for a single column:
Private Sub SelectHousingList_Click()
HousingList.AddItem SelectHousingList.Value
End Sub
If there are 2 columns, then this:
Private Sub SelectHousingList_Click()
HousingList.AddItem SelectHousingList.List(SelectHousingList.ListIndex)
HousingList.List(HousingList.ListCount - 1, 1) = SelectHousingList.List(SelectHousingList.ListIndex, 1)
End Sub
You'll need to add additional lines for every column beyond 2, changing the index for each one.
This code retrieves in an array (or string) all the columns values on the selected row. It fills the second listbox with as many columns first one has:
Private Sub SelectHousingList_Click()
Dim arrRow() As Variant, i As Long
ReDim arrRow(Me.SelectHousingList.ColumnCount)
For i = 0 To SelectHousingList.ColumnCount
arrRow(i) = Me.SelectHousingList.List(i, Me.SelectHousingList.ListIndex)
Next i
Debug.Print Join(arrRow, ", ")
With Me.HousingList
.ColumnCount = Me.SelectHousingList.ColumnCount
.AddItem arrRow(0)
For i = 1 To UBound(arrRow)
.List(.ListCount - 1, i) = arrRow(i)
Next i
End With
End Sub

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.

Filling a combobox with values in VBA

I am having trouble filling a combobox with options from a range.
The user selects the range with a refedit, the ComboBox must then be populated with the values of the selected cells. If the user changes the ref the old data must be removed and repopulated with the new data.
Below is my current code. Compiles right, but doesn't work.
I'm not attached to a ComboBox per se, but I need to populate a list with the values from a column so the user can select the one they want to use as "key" The first set is a sample of what is in a row. I would want these options offered as the choices for the dropdown.
You can download a copy of what I'm working on at http://ge.tt/2dbV5Yt/v/0?c
Store # Address City ST Zip Market Radius
Private Sub rngHeader_Exit(ByVal Cancel As MSForms.ReturnBoolean)
Dim selRng As Range
Set selRng = Range(rngHeader.Value)
'//Erase any items that are in there
For I = 1 To cmbKeyCol.ListCount
cmbKeyCol.RemoveItem 0 'Remove the top item each time
Next I
'Below here is the part that I'm having trouble with. This is one of my attempts, but
'I've changed this thing probably 20 times since asking the question
'//Build new list of items from the header row.
For Each cell In selRng.Cells
cmbKeyCol.AddItem cell.Value
Next
End Sub
why don't you use this instead:
cmbkeyCol.RowSource = selRng.Address 'Assuming you already got your range right.
This adds all the items in the range specified instead of iterating through them 1 by 1.
Edit 1:
Dim list as variant
list = selRng.Value
list = Application.Transpose(list)
cmbkeyCol.List = list
Hope this works.
Edit 2:
Dim list as variant
list = rngHeader.value
list = Application.Transpose(list)
cmbkeyCol.List = list
I assumed that selRng is the source range in Edit 1 well in fact it is rngHeader.
Hopefully this works now.

Resources