I'm trying to do is check first the item in listbox if the value in textbox is already in listbox.
Private Sub txtSS_PreviewKeydown(ByVal sender As Object, ByVal e As System.Windows.Forms.PreviewKeyDownEventArgs) Handles txtSS.PreviewKeyDown
If e.KeyCode = Keys.Tab Then
For Each a As String In String.Join(vbCrLf, ListBox1.Items.Cast(Of String))
If txtSS.Text = a Then
MsgBox("It's already barcoded!")
txtSS.Text = ""
End If
Next
If txtMS.Text = txtSS.Text Then
MsgBox("This is already MAIN SERIAL! kindly check your barcoding serial", MsgBoxStyle.Exclamation)
txtSS.Text = ""
txtSS.Select()
Else
ListBox1.Items.Add(txtSS.Text)
txtSS.Clear()
txtSS.Select()
End If
End If
End Sub
But my code is not working.
the 'a' value of my for each is get only the first char of my listbox.
Think about this expression, used with the For Each
loop:
String.Join(vbCrLf, ListBox1.Items.Cast(Of String))
The result of the expression is one string. When you use a string with a For Each
loop, it doesn't go line by line. Rather, the loop runs for every character in the string, one character at a time, just as you saw. If you want each item in the ListBox, you don't need to use Join()
at all:
For Each a As String In ListBox1.Items.Cast(Of String)()
Or I could refactor the whole method to be MUCH shorter and with less nesting:
Private Sub txtSS_PreviewKeydown(ByVal sender As Object, ByVal e As System.Windows.Forms.PreviewKeyDownEventArgs) Handles txtSS.PreviewKeyDown
If e.KeyCode <> Keys.Tab Then Exit Sub
If ListBox1.Items.Any(Function(a) txtSS.Text = DirectCast(a, String)) Then
MsgBox("It's already barcoded!")
Else If txtMS.Text = txtSS.Text Then
MsgBox("This is already MAIN SERIAL! Kindly check your barcoding serial.", MsgBoxStyle.Exclamation)
Else
ListBox1.Items.Add(txtSS.Text)
End If
txtSS.Clear()
txtSS.Select()
End Sub
This also fixes another bug in the original code, where the "It's already barcoded!" result didn't exit the method. The next If
check would still have run, where the empty string isn't likely to match the main serial number, and so the method would still likely add a blank line to the bottom of the ListBox. That will no longer happen.
While I'm here, I see you're looking at the Tab key and using bar codes. Most barcode readers by default will send a return key (Cr/Lf) at the end of the scanned text. You can add code to handle this, as well, and possibly make things much easier and faster for you users to do repeated scans.