How do I refer to a controls object, on a worksheet, using a variable name? - vba

I have added a ListBox to a SHEET (not to a "UserForm")
I did this using the mouse.
I clicked the little Hammer and Wrench icon.
This ListBox seems to be easily referenced using code such as this:
ListBox1.Clear
or
ListBox1.AddItem("An option")
However, I have three of these ListBoxes (named, conveniently, ListBox1, ListBox2, and ListBox3) and I want to write a function to populate them with array data, like this:
Call populate_listbox(ListBox2, designAreaArray)
Where the first argument is the listbox name, the 2nd is the data.
But I do not know how to send "ListBox2" correctly, or refer to it correctly within the function.
For example:
Dim controlName as string
controlName = "ListBox1"
doesn't work, even if I define the function as follows:
Sub populate_listbox(LB As ListBox, dataArray As Variant)
Dim i As Integer: i = 0
For i = LBound(dataArray, 2) + 1 To UBound(dataArray, 2) ' Skip header row
LB.AddItem (dataArray(index, i))
Next i
End Sub
Clearly it results in a mis-matched data type error. I've tried defining "controlName" as a ListBox, but that didn't work either...
Though perhaps it is my reference to the listBox that is incorrect. I've seen SO MANY ways to refer to a control object...
MSForms.ListBox.
ME.ListBox
Forms.Controls.
Worksheet.Shapes.
The list goes on an on, and nothing has worked for me.

Try this:
Dim cMyListbox As MSForms.ListBox
Set cMyListbox = Sheet1.ListBox1 '// OR Worksheets("YourSheetName").Listbox1
cMyListbox.AddItem("An option")
Also you can populate a listbox without having to loop through the array, try this:
Dim cMyListbox As MSForms.ListBox
Dim vArray As Variant
Set cMyListbox = Sheet1.ListBox1
vArray = Range("A1:A6").Value
cMyListbox.List = vArray

Change the sub signature to match this:
Sub populate_listbox(LB As MSForms.ListBox, dataArray As Variant)
Now you can pass it like you were trying to originally.
NOTE: This only works if you used the "ActiveX" version of the listbox. I'm assuming you are because you are able to call ListBox1 straight from a module.
PS: The ActiveX controls are members off of the parent sheet object. So if you have the listbox1 on sheet1, you can also call it like Sheet1.ListBox1 so you don't get confused if you end up with multiple sheets with multiple listboxes. Also, you may want to change the name just to make it easier on yourself.

Dim controlName As OLEObject
Set controlName = Sheet1.OLEObjects("ListBox1")
Call populate_listbox(controlName, designAreaArray)
Sub populate_listbox(LB As OLEObject, dataArray As Variant)
Dim i As Integer: i = 0
For i = LBound(dataArray, 2) + 1 To UBound(dataArray, 2) ' Skip header row
LB.Object.AddItem (dataArray(Index, i))
Next i
End Sub

To access the state of a checkbox Active-X control on Sheet1:
Dim checkBox1 As Object
Set checkBox1 = Sheet1.OLEObjects("CheckBox1").Object
MsgBox checkBox1.Value

Related

Populate 10 comboboxes from the same array using VBA in MS Word

I want to create one and the same array to be used for my 10 comboboxes. When the OnClick procedure is activated for a ComboBox, the combobox will be filled with the array.I am no programmer but I use simple VBA to solve some problems. Now I have encountered problems and have no idea how to solve it. Previously, I have only used Excel and linked cell. Now it's Word ...
I want all tests to be visable in the first column of my combobox and the colors in the second column.
My array
Test1, Blue
Test2, Green
Test3, Yellow
Test4, Black
I have tried to google around but feel I can not put everything together.
Private Sub Document_Open()
' The location of my array?
End Sub
Private Sub ComboBox1_Click()
' Load object with array, code for each combobox?
End Sub
I'm trying to create a simple order form. I use ActiveX components and document protection.
Use the DropButtonClick event of the ComboBox to perform actions when the user clicks the dropdown button of a ComboBox control.
Since you want to use the same code for all your ComboBoxes, create a single procedure for populating the list and pass the ComboBox object to it.
To me, it seems simplest to store the list as a delimited string, then use the Split function to break that up. First, the items are split into an array. Then loop through that array and split again to get the two entries for a list item, using these to populate a third array that will be assigned to the ComboBox, using the List method.
Private Sub ComboBox1_DropButtonClick()
PopulateList ComboBox1
End Sub
Private Sub ComboBox2_DropButtonClick()
PopulateList ComboBox2
End Sub
Sub PopulateList(cb As MSForms.ComboBox)
Dim sListVals As String
Dim aList As Variant, aCols As Variant, aItems As Variant
Dim i As Long
'cb.Clear
sListVals = "Test1,Blue;Test2,Green;Test3,Yellow;Test4,Black"
aList = Split(sListVals, ";")
ReDim aItems(UBound(aList), 1)
For i = LBound(aList) To UBound(aList)
aCols = Split(aList(i), ",")
aItems(i, 0) = aCols(0)
aItems(i, 1) = aCols(1)
Next
cb.List = aItems
End Sub

Passing Cell Values into a combo box list

I am looking to pass cells values into the list for a combo box in Excel.
I have created an array to pass the cell values into but they aren't getting to the combo box list when they are being called. I need the cell values to display as the drop down items and all that displays is the blank space:
Sub Clear_Invoice_Data()
Dim Arr As Variant
Arr = Range("A1:A5").Value
frmAddLineItem.ddlProduct.List = Arr
End Sub
It is called by a button from a User form:
Private Sub cmdClearAll_Click()
Call Button_Functions.Clear_Invoice_Data
i = 18
End Sub
Pictures of problem: (no values)
There is another (rougher) method found here to do this if you so choose. Also make sure you define the Sheet name you are sourcing the data from:
Sub AddItemsToBox()
Dim itemcell As Range
For Each itemcell in Sheets("Source Sheet Name").Range("A1:A5")
frmAddLineItem.ddlProduct.AddItem itemcell.Value
Next itemcell
End Sub
Using ComboBox, you can use .List property of the same to populate worksheet values to combox box.
Check this below example:
ComboBox1.List = Worksheets("Sheet1").Range("A1:A5").Value
If you want to use Array,
Dim Arr As Variant
Arr = Worksheets("Sheet1").Range("A1:A5").Value
ComboBox1.List = Arr
I am just getting into VBA and I am doing exactly this. I think the way I found is pretty easy and straightforward. I'll share it in case it can help someone
Declare variable to store table from Worksheet as "range". Make sure
it's outside of sub routines so it can be called by any function
Dim myTable As Range
Store table values in declared variable. Then select which column (range) of values you want to store in your combo box.
Private Sub UserForm_Initialize()
Set myTable = Worksheets("dataSheetName").Range("A2:B6")
Me.myComboBox.List = myTable.Columns(1).Value
End Sub ```

Manipulating ListBoxes as Objects

I am working on a VBA userform that includes ListBoxes.
So far, when I had to manipulate one or more, I always proceeded like this in my subs, with dlg as the dialogbox name, and it did not pose any problem, given that I never wanted to do anything complicated:
Dim List1 As Object
...
List1 = dlg.GetControl("CBXname")
...
List1.addItem("String",index)
...
Now I would like to do the following in this Sub
...
If (List1.Exists(Cell1.String) = False) Then
List1.addItem(Cell1.String,k)
End If
...
List1.Clear
...
But I can do neither since List1 is an Object. However, if I decide to declare List1 as a Listbox instead, I do not know how to get the proper control on the ListBox from the dialogbox (the current getcontrol gives me an error).
One of the issues with your code is that listbox objects do not have an "exists" property. To check if a value already exists in your listbox items, you will need to loop through the items.
dim i as integer
for i = 0 to List1.listcount - 1
if List1.column(0, i) = myvalue then
'myvalue exists in List1, skip
else
List1.additem myvalue
end if
next i
Where myvalue is whatever value you are trying to add to the listbox. But that brings us to the second issue in your code which is where you add "Cell1.String". If you are trying to add a value from a worksheet range you will need to refer to that range's value, as worksheet ranges do not have a "string" property as you use it here. Ie. Cell1 = Range("A1").value
As for getting control of the listbox, you can simply refer to the objects name as an object of the form. For example, dlg.List1, if the object's name is List1.
Here is a general purpose routine you can call for any list box. The calling code assumes a list box called ListBox1, a text box called TextBox1, and a Command Button called CommandButton. When you click on the button, it searches the listbox for the text from textbox1.
Private Function ExistsInListbox(ByRef aListBox As msforms.ListBox, ByVal Item As String) As Boolean
Dim booFound As Boolean
booFound = False
Dim t As Integer
ExistsInListbox = False
For t = 0 To aListBox.ListCount - 1 'correction, aListBox not ListBox1
If Item = aListBox.List(t) Then
'if we find a match, short-circuit the loop
booFound = True
Exit For
End If
Next
ExistsInListbox = booFound
End Function
private sub CommandButton_click()
Dim answer As String
Dim val As Boolean
val = ExistsInListbox(Me.ListBox1, TextBox1.Text)
If val Then
answer = "found"
Else
answer = "Not Found"
End If
MsgBox "found-" & answer
End Sub

Removing items from multiple comboboxes

I have 7 comboboxes. All these comboboxes have same source.
With Sheets("Data_Sheet")
Sheets("UI_Interface").ComboBox2.ListFillRange = "Data_Sheet!E2:E" & .Cells(Rows.Count, 5).End(xlUp).Row
End With
Same code has been written for other combobxes.
Now when a value from combobx1 is selected it should not be present in other comoboxes.
When i try to do this with following code but i'm getting error with this code.
j = ComboBox1.ListIndex
ComboBox2.RemoveItem (j)
I tried some different attributes too for removing the value but all gave some exception.
What is incorrect in this code?
The RemoveItem method works properly for me unless I use the .ListFillRange method to populate the combobox. If you use the .List method instead, it should work. To do that, you have to convert the range to an array.
REVISED
Thanks to enderland for pointing out that you are working with form controls on a worksheet, not in a user form. So the approach should be similar but you won't be able to use the ListFillRange method. Not a big deal, we can easily take that range, convert it to a variant/array, and use the List method.
Option Explicit
Private Sub Worksheet_Activate()
'## Sets default list for ComboBoxes on this sheet
SetComboBoxLists ComboBox1
SetComboBoxLists ComboBox2
End Sub
Private Sub ComboBox1_Change()
'## event handler for a combobox, repeat as needed
'## Repopulate the list, otherwise you may get
' an Index out of Range error or Invalid Argument error,
' or the RemoveItem method will remove the wrong item
SetComboBoxList ComboBox2
'## Now, remove the item selected in ComboBox1
ComboBox2.RemoveItem ComboBox1.ListIndex
End Sub
Private Sub SetComboBoxLists(cBox As MSForms.ComboBox)
'## Subroutine to fill the list in each combobox as needed
Dim lstRange As Variant
'## Populate the array variable to use for the combobox.List method:
' double-check that I put the parentheses in the right place!
With Sheets("Data_Sheet")
lstRange = .Range("E2:E" & .Cells(Rows.Count, 5).End(xlUp).Row)
End With
'## Populate the combobox with the list
cBox.List = lstRange
End Sub
Note that if any of your code manipulates (e.g., resizes, removes rows, etc) the range, you'll need to re-apply the List method.

How can I dynamically construct a textbox object reference?

I asked a similar question Here and now I need to do the same thing again but this time using VBA in Excel 2010.
Essentially I have numerous text boxes with generic names (i.e. textbox1,textbox2 etc). How can I programically construct the object reference so that I can create a loop?
EDIT:
It is a regular textbox on a worksheet. When I start a sub for this worksheet I can reference the textboxes with the following line:
TextBox1.LinkedCell = "B2"
This is what your after:
Dim oleObj As OLEObject
'Dim oleTxtBox As TextBox
For Each oleObj In Sheet1.OLEObjects
If oleObj.OLEType = xlOLEControl Then
If Mid(oleObj.progID, 1, 14) = "Forms.TextBox." Then
Set oleTxtBox = oleObj.Object
oleTxtBox.PasswordChar = "*"
End If
End If
Next
Just using PasswordChar as an example field from the TextBox object, but it wouldn't actually left me Dim as a TextBox