Listbox.List(i) error - Method or Data Member not Found - vba

I'm trying to use a multi-select listbox so users can select cleaning tasks they have completed and mark them as done. While looping through the list I want to see if the item is selected and create a record if so. When I try to use the .List method to return the data from a specific row, I keep getting the method not found error.
I originally did not have the forms 2.0 library loaded so I thought that was the issue, but that did not resolve the problem. I've also compacted and repaired thinking it might just be an odd fluke, but that did not help either.
'loop through values in listbox since its a multi-select
For i = 0 To listCleaningTasks.ListCount - 1
If listCleaningTasks.Selected(i) Then
'add entry to cleaning log
Set rsCleaning = CurrentDb.OpenRecordset("SELECT * FROM cleaning_log;")
With rsCleaning
.AddNew
.Fields("cleaning_task_id") = Form_frmCleaning.listCleaningTasks.List(i)
.Fields("employee_id") = Me.cmbUser
.Fields("cleanroom_id") = Me.cmbCleanroom
.Fields("cleaning_time") = Now()
.Update
.Close
End With
End If
Next i
Any ideas?

Use .listCleaningTasks.ItemData(r) to pull bound column value from row specified by index.
Use .listCleaningTasks.Column(c, r) to pull value specified by column and row indices.
Open and close recordset only one time, outside loop.
Really just need to loop through selected items, not the entire list.
Dim varItem As Variant
If Me.listCleaningTasks.ItemsSelected.Count <> 0 Then
Set rsCleaning = CurrentDb.OpenRecordset("SELECT * FROM cleaning_log")
With rsCleaning
For Each varItem In Me.listCleaningTasks.ItemsSelected
`your code to create record
...
.Fields("cleaning_task_ID") = Me.listCleaningTasks.ItemData(varItem)
...
Next
.Close
End With
Else
MsgBox "No items selected.", vbInformation
End If

Of course the solution of June7 is correct. If you need to store the selected items and then later recall and re-select the list box items, consider to get the selected items comma delimited using this function
Public Function GetSelectedItems(combo As ListBox) As String
Dim result As String, varItem As Variant
For Each varItem In combo.ItemsSelected
result = result & "," & combo.ItemData(varItem)
Next
GetSelectedItems = Mid(result, 2)
End Function
Store it into one column of a table and after reading it back pass it to this sub:
Public Sub CreateComboBoxSelections(combo As ListBox, selections As String)
Dim N As Integer, i As Integer
Dim selectionsArray() As String
selectionsArray = Split(selections, ",")
For i = LBound(selectionsArray) To UBound(selectionsArray)
With combo
For N = .ListCount - 1 To 0 Step -1
If .ItemData(N) = selectionsArray(i) Then
.Selected(N) = True
Exit For
End If
Next N
End With
Next i
End Sub
This will select items in your ListBox as they were before.

Related

Take list box selection, add value to other list box without allowing duplicates

I have two list boxes on a form I am making. The first list box is linked to a table with various company names. The goal I am after is after double clicking a companies name, the value is inserted in the second list box.
It worked fine until I tried to add code to prevent duplicates from appearing in the second list box, so you couldn't accidentally insert the same company twice. I have tried several different iterations, but with no luck. Anyone able to help with this one? My end goal would be for a msgbox to pop up alerting the user that duplicates are not allowed.
Private Sub ContractorLstbx_DblClick(Cancel As Integer)
Dim found As Boolean
found = False
Dim ID As Long
Dim Contractor As String
For Each newItem In Me.ContractorLstbx.ItemsSelected
For j = 0 To Me.SelectedContractorLst.ListCount - 1
If (Me!ContractorLstbx.ItemData(newItem).Column(1) = Me.SelectedContractorLst.ItemData(j).Column(1)) Then
found = True
Exit For
End If
Next j
If found = False Then
ID = Me.ContractorLstbx.ItemData(newItem)
Me.SelectedContractorLst.AddItem ContractorLstbx!.ItemData(newItem).Column(0) & ";" & Me!ContractorLstbx.ItemData(newItem).Column(1)
End If
found = False
Next newItem
End Sub
This is the full code for your solution. I tried it on test sample and working fine. just copy and paste the code. If you need your comparison to be case sensitive (I mean A <> a) then use Option Compare Binary as in my code below. If it is required to be case insensitive (A = a) just leave the default Option Compare Database or better force it using Option Compare Text
Option Compare Binary
Private Sub ContractorLstbx_DblClick(Cancel As Integer)
Dim found As Boolean
found = False
Dim ID As Long
Dim Contractor As String
For i = 0 To Me.ContractorLstbx.ItemsSelected.Count - 1
For j = 0 To Me.SelectedContractorLst.ListCount - 1
If (Me.ContractorLstbx.Column(1, Me.ContractorLstbx.ItemsSelected(i)) = Me.SelectedContractorLst.Column(1, j)) Then
found = True
Exit For
End If
Next j
If found = False Then
ID = Me.ContractorLstbx.ItemData(Me.ContractorLstbx.ItemsSelected(i))
Me.SelectedContractorLst.AddItem (ContractorLstbx.Column(0, Me.ContractorLstbx.ItemsSelected(i)) & ";" & Me.ContractorLstbx.Column(1, Me.ContractorLstbx.ItemsSelected(i)))
End If
found = False
Next i
End Sub

Problems with Null in VBA

I want the code to display the selection in ListBox1 in a MsgBox and "Select a Capacity" if ListBox1 is empty/not selected.
If I try to use IsEmpty(), then ListBox1.Value is Null.
If I use IsNull(), then ListBox1.Value is "".
Private Sub CommandButton3_Click()
Dim Cap As Integer
If IsNull(ListBox1) = True Then
MsgBox "Select a Capacity"
Exit Sub
End If
Cap = Left(ListBox1.Value, 2)
MsgBox Cap
End Sub
Any suggestions would be appreciated.
You could try:
If ListBox1.ItemsSelected.Count = 0 Then
MsgBox "Select a capacity"
Exit Sub
End If
Cap = Left(ListBox1.Value, 2)
The IsEmpty function is used to check is a variable of type Variant has been initialised. It cannot be used to check if a ListBox contains any entries.
The IsNull function checks if a variable has been set to Null. This doesn't help with checking a ListBox for entries.
Instead, use If ListBox1.ListCount = 0 Then to check if the ListBox is empty and use If ListBox1.ListIndex = -1 Then to check if any entries have been selected.
If the ListBox allows multiple selections at once then, as mentioned by #shoegazer100, use something like:
Dim rowNumber As Long
For rowNumber = 0 To (ListBox1.ListCount - 1)
If ListBox1.Selected(rowNumber) Then
' do something
End If
Next rowNumber
to determine which rows are currently selected (if Selected returns True for a particular row then the corresponding row in the ListBox is selected)

Comparison of two listbox in VBA

I am new at VBA.So kindly help me on this matter.
My UserForm has two ListBox controls in it, each with two columns. For example, ListBox1
Name Item
A 20
B 30
and listbox2:
Name Item
A 20
B 40
When I click a CommandButton, the procedure below attempts to compare both ListBox controls and returns whether or not the data in each column of data is correct. I believe the best approach would be to first compare Column 1 of ListBox1 with Column 1 of ListBox2. If those are identical, then compare the second columns of both ListBox controls. The procedure is supposed to return a MsgBox that says "Correct" if all columns are identical. Otherwise, the program should return a mismatch error. Here is the code I've tried so far.
Private Sub CommandButton1_Click()
Dim p As Integer, Tabl()
Redim Tabl(0)
For i = 0 To ListBox1.ListCount - 1
p = p + 1
Redim Preserve Tabl(p)
Tabl(p) = ListBox1.List(i)
Next i
For i = 0 To ListBox2.ListCount - 1
If IsNumeric(Application.Match(ListBox2.List(i), Tabl, 0)) Then
Msgbox"Correct"
End If
Next i
End Sub
Unfortunately, the program only calculates the first column repeatedly. How can I compare multiple columns?
Based on your description and a small evaluation of what your code does, you may be overthinking this. How about the following?
Private Sub CommandButton1_Click()
Dim myMsg As String
Dim byeMsg As String
myMsg = "Same name chosen."
byeMsg = "Those names don't match."
If ListBox1.Value = ListBox2.Value Then
MsgBox myMsg
Else
MsgBox byeMsg
End If
End Sub
Of course, instead of displaying a message using MsgBox, you could just as easily replace it with any code you need.

Using selected values in an Excel list box to formulate the legend

I am attempting to pass the selected values from a list box in Excel to legend in a chart. Specifically, I have data of certain companies in the following format
And I also have a list box, globalList, which contains the names of companies that can be selected. Selected companies' data will then be passed onto a chart using VBA.
However, the problems I encounter are in the following sections:
Initialising a variable to hold values selected in the globalList
listMax = globalList.ListCount - 1
`this creates the upper bound for the list box
For i = 0 To (globalList.ListCount - 1)
If globalList.Selected(i) = True Then
companiesSelected = companiesSelected + 1
End If
If i = listMax Then
Exit For
End If
Next i
`the above is used to retrieve the number of companies that have been selected by a user - whether =0 or > 0
Dim myLegend() As String
ReDim myLegend(0 To (globalList.ListCount - 1))
For i = 0 To (globalList.ListCount - 1)
If globalList.Selected(i) = True Then
myLegend(i) = globalList.List(i)
End If
If i = listMax Then
Exit For
End If
Next i
`this is the array object in which I intend to store company names selected in the list box.
The problem is that even though the above creates the myLegend string array, it also contains empty array items for the companies that may not have been selected by the user in the list box.
And even if I am able to remove these empty items from the array, the following problem occurs
Passing the held values from my variable to my chart
For i = 1 To companiesSelected
myChart.SeriesCollection(i).Name = myLegend(i)
Next i
Problem here is that myLegend array starts from 0, while SeriesCollection seems to start from 1. So I am unable to pass the string values for selected items to the legend of my chart's.
Could somebody please point out how to circumvent these problems?
Many thanks in advance!
Here is a code to extract the selected items into an one-based array of String (without empty items):
Dim i As Integer
Dim iCount As Integer
Dim myLegend() As String
iCount = 0
With globalList
ReDim myLegend(1 To .ListCount)
For i = 0 To .ListCount - 1
If .Selected(i) = True Then
iCount = iCount + 1
myLegend(iCount) = .List(i)
End If
Next i
End With
If iCount > 0 Then
ReDim Preserve myLegend(1 To iCount)
Else
ReDim myLegend(1 To 1)
myLegend(1) = "Nothing here!"
End If

String.contains not working

I'm trying to filter a list based on input from a textbox. If the item doesn't contain the string, it is deleted from the list. Here is my subroutine:
Sub filterlists(filter As String)
Dim removalDifferential As Integer = 0
For colE As Integer = 0 To RadListView1.Items.Count
Try
Dim itemEpp As ListViewDataItem = Me.RadListView1.Items(colE)
Dim jobname As String = itemEpp(0)
If Not jobname.Contains(filter) Then
' MsgBox(jobname & " Contains " & filter)
RadListView1.Items.RemoveAt(colE - removalDifferential)
removalDifferential = removalDifferential + 1
End If
Catch
End Try
Next
End Sub
Currently this is not deleting the correct items. The TRY is there because when you delete an item the list index changes (which means the for loop length is wrong and will throw outofbounce errors). Any other loop options that will work here?
Assuming you really do want to delete any LVI which simply contains the filter text, you should loop backwards thru the items (any items, not just Listview items) so the index variable will in fact point to the next correct item after a deletion:
For n As Integer = RadListView1.Items.Count-1 to 0 Step -1
If radListView1.Items(n).Text.Contains(filter) Then
RadListView1.Items.RemoveAt(n)
End If
Next