String.contains not working - vb.net

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

Related

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

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.

How do I compare two listboxes?

I have two listboxes (1: Primary, 2:Secondary).
These listboxes contain numbers. The Primary Listbox contains 7 numbers, and the Secondary Listbox contains 6 numbers.
I want to compare the values of the Primary Listbox to those of the Secondary.
This comparison should yield three results:
Result #1:
X number of values were found to be common.
Result#2:
All numbers matched.
Result#3:
No matches found.
This is what I have so far:
If lstPrimaryNumbers.Items.Count = 0 Or lstSecondaryNumbers.Items.Count = 0 Then
MessageBox.Show("There is nothing to compare.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End If
For i As Integer = 0 To lstPrimaryNumbers.Items.Contains
For j As Integer = 0 To lstSecondaryNumbers.Items.Contains
If i = j Then
MessageBox.Show(i & " " & j & " matched!")
End If
Next
Next
PLEASE NOTE:
I HAVE CHANGED MY ENTIRE INTERFACE, SO THIS POST IS OBSOLETE AND I HAVE NO USE FOR IT NOW. THANK YOU EVERYONE FOR YOUR SUPPORT!
I will leave this for the moderators to decide whether to remove this post or keep it for other users reference.
I will flag this post.
The matching items could be found with
Dim r = lb1.Items.Cast(Of Int32).Where(Function (x) lb2.Items.Contains(x))
MessageBox.Show(String.Join(",", r) & " matched")
If you want to have a full match, then use IEnumerable.All to check
Dim a = lb1.Items.Cast(Of Int32).All(Function (x) lb2.Items.Contains(x))
If a Then
MessageBox.Show("Full Match")
End If
Finally if you want only know if some items match then use IEnumerable.Any
Dim b = lb1.Items.Cast(Of Int32).Any(Function(x) lb2.Items.Contains(x))
If Not b Then
MessageBox.Show("No matches where found")
End If
I have assumed that your items are integers, but if you add them as strings then you need to change the Cast(Of Int32) to Cast(Of String)
First, I got the contents of the ListBoxes into arrays with a little linq. Then using the .Intersect method found the matches. And displayed the .Count. You iterate the result with a For Each
Private Sub OPCode()
Dim id1() As Integer = (From i In ListBox1.Items Select CInt(i)).ToArray
Dim id2() As Integer = (From i In ListBox2.Items Select CInt(i)).ToArray
Dim Matches As IEnumerable(Of Integer) = id1.Intersect(id2)
MessageBox.Show(Matches.Count.ToString)
End Sub
'TextBox1.Multiline = True is set at design time
'Expand the text box size so several lines will be visible
For Each Match As Integer In Matches
TextBox1.Text &= (CStr(Match) & Environment.NewLine)
Next

For each loop, compare to next item on the list

I am writing an application where I bring change history of items from the database and place them on the table using For Each loop. I would, however, like to show in table what information has changed in each edit. Is it possible to compare variables of each item to the variables of next loop in For Each loop?
Something like:
For Each k As Examplemodel In Model
'Find next item on the loop after current one somehow
Dim nextItem = Model.Item(k+1) 'something like this
If k.ItemsName <> nextItem.Itemsname 'if the name has changed in edit
'show result in bold
Else
'show result in normal font weight
End If
Next
Is this possible and if not, what's the best way to achieve this?
You can't do it in a foreach loop directly.
If your Model class have indexers you can easily convert it into a for loop:
If Model.Count > 1 Then
For i as Integer = 0 to Model.Count - 2 ' Note the -2 here !!!
Dim Item As Examplemodel = Model(i)
Dim NextItem As Examplemodel = Model(i + 1)
if Item.ItemsName <> NextItem.ItemsName then
'show result in bold
else
'show result in normal font weight
end if
Next
'show result of NextItem here, since the last item doesn't get shown in the loop
Else
'show result of only item here
End If
If not, you can use a workaround like this:
Dim PrevItem as Examplemodel = Nothing ' Assuming a reference type
For Each k As Examplemodel In Model
If Not IsNothing(PrevItem) AndAlso k.ItemsName <> Prev.Itemsname 'if the name has changed in edit
'show result (of PrevItem!!!) in bold
Else
'show result (of PrevItem!!!) in normal font weight
End If
PrevItem = k
Next
'show result (of PrevItem (currently the last item in Model) in normal font weight
You should use a normal for loop:
Dim numbers() As Integer = New Integer() {1, 2, 4, 8}
Sub Main()
For index As Integer = 0 To numbers.Length - 2
Dim currentInt As Integer = numbers(index)
Dim nextInt As Integer = numbers(index + 1)
Console.WriteLine(currentInt)
Console.WriteLine(nextInt)
Next
End Sub
Another approach to use LINQ Aggregate extension method, which use first item of collection as initial value. So every item will have access to previous one.
Public Class ItemChanges
Public Property Item As ExampleModel
Public Property Changes As New Hash(Of String)
End Class
Public Function Check(previous As ItemChanges, current As ItemChanges) As ItemChanges
If current.Item.Name <> previous.Item.Name Then
current.Changes.Add(Nameof(current.Name))
End
Return current
End Function
' assume model is collection of items
Dim itemWithChanges =
model.Select(Function(m) New ItemChanges With { .Item = m })
.Aggregate(AddressOf(Check))
.ToList()
Then you can use calculated result as you want - every item will have a hash of property names which had changed
If checkedItem.Changes.Contains(Nameof(checkedItem.Item.Name)) Then
' use bold font or different color
End

Listbox Remove Spaces

I am trying to use this code to remove spaces from a listbox but it is not working
Dim word As String() = {" "}
For i As Integer = 0 To ListBox5.Items.Count - 1
For Each Word As String In word
If ListBox5.Items(i).ToString.Contains(Word) Then
ListBox5.Items(i) = ListBox5.Items(i).ToString.Replace(Word, String.Empty)
End If
Next
Next
any help would be appreciated a lot.
You define a string array with one value and its static, why?
It seems you could do this simply by coding it like this
scan every item and replace " " with string.empty,
don't bother checking if it exists, just run the replace statement on every item
For i As Integer = 0 To ListBox5.Items.Count - 1
ListBox5.Items(i) = ListBox5.Items(i).ToString.Replace(" ", String.Empty)
Next
try this code
For i As Integer = 0 To ListBox5.Items.Count - 1
ListBox5.Items(i) = ListBox5.Items(i).ToString.Replace(" ", Nothing)
Next
fist we have to loop through the listbox items. we declared the items from index 0 to the final item index,ie listbox.items.count-1 . this is stored in a variable i. next all the items ,say from 0 to count-1 is replaced.
istBox5.Items(i).ToString.Replace(" ", Nothing) " " indicates a space and'nothing' indicates null.you can also use regex.replace here by importing system.regularexpressions.

Check if listbox contains textbox

I know I could use .FindString for this but for some reason it is not working.
Basically,if listbox items contains just a PART of textbox text,it does action.
Here's the example of not-working code :
Dim x As Integer = -1
x = ListBox1.FindString(TextBox1.Text)
If x > -1 Then
'dont add
ListBox2.Items.Add("String found at " & x.ToString)
Else
End If
The FindString method returns the first item which starts with the search string (MSDN). If you want to match the whole item, you would have to use FindStringExact (MSDN). If you want to perform more complex searches, you would have to iterate through all the elements in the ListBox.
UPDATE:
Code delivering the exact functionality expected by the OP.
For i As Integer = 0 To ListBox1.Items.Count - 1
If (ListBox1.Items(i).ToString.Contains(TextBox1.Text)) Then
ListBox2.Items.Add("String found at " & (i + 1).ToString) 'Indexing is zero-based
Exit For
End If
Next