Get data from cmd, split the values and insert them into textboxes - vb.net

I'm trying to read battery information from cmd. How can I extract each value and put them in their respective textbox, as shown in the image below?
Here's my code:
Private Results As String
Private Delegate Sub delUpdate()
Private Finished As New delUpdate(AddressOf UpdateText)
Private Sub UpdateText()
TextBox11.Text = Results
End Sub
Private Sub batt_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim CMDThread As New Threading.Thread(AddressOf CMDAutomate)
CMDThread.Start()
End Sub
Private Sub CMDAutomate()
Dim myprocess As New Process
Dim StartInfo As New System.Diagnostics.ProcessStartInfo
StartInfo.FileName = "cmd" 'starts cmd window
StartInfo.RedirectStandardInput = True
StartInfo.RedirectStandardOutput = True
StartInfo.UseShellExecute = False 'required to redirect
StartInfo.CreateNoWindow = False 'creates no cmd window
myprocess.StartInfo = StartInfo
myprocess.Start()
Dim SR As System.IO.StreamReader = myprocess.StandardOutput
Dim SW As System.IO.StreamWriter = myprocess.StandardInput
SW.WriteLine("adb shell dumpsys battery") 'the command you wish to run.....
SW.WriteLine("exit") 'exits command prompt window
Results = SR.ReadToEnd 'returns results of the command window
SW.Close()
SR.Close()
'invokes Finished delegate, which updates textbox with the results text
Invoke(Finished)
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim value As String = TextBox11.Text
Dim topic_start As String = topic_start = value.LastIndexOf("AC Powered:") + 1
Dim topic As String = value.Substring(topic_start, value.Length - topic_start)
TextBox1.Text = topic.ToString
End Sub
Button1 is labeled Get Battery Information in the image.

Private Sub UpdateText()
Dim xList As New List(Of KeyValuePair(Of String, String))
Results = Results.Replace(vbLf, "")
Dim LineSplit() As String = Results.Split(vbCr)
For Each xLine As String In LineSplit
If xLine <> "" Then
xList.Add(New KeyValuePair(Of String, String)(xLine.Split(":")(0), xLine.Split(":")(1).Trim.Replace(" ", "")))
End If
Next
'do some work here to put the values in the right textboxes
End Sub
You can make yourself a custom control made of a label and a textbox that you use in your app. Then you just pass each entry of the list to your custom controls. Makes it easier to add or remove fields without having tons of IF then or a big Select Case

Here one way to extract values from text that is separated with new lines (Enviroment.NewLine) using IndexOf(), Substring() methods and Length property:
Private Sub UpdateGUI()
Dim lines As String() = TextBox1.Text.Split(New String() {Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries)
For Each itm In lines
MsgBox(itm.Substring(itm.IndexOf(":") + 1, itm.Length - itm.IndexOf(":") - 1))
Next
End Sub

Unless your TextBoxes are named exactly like the value in your return string (you'd have to convert the space to some other character anyways), there really isn't any way to do this except to manually code each case. Something like this should do it, just change the name of the TextBoxes accordingly:
Private Sub UpdateText()
Dim lines() As String = Results.Split(vbCrLf.ToCharArray, StringSplitOptions.RemoveEmptyEntries)
For Each line In lines
Dim values() As String = line.Split(":")
Select Case values(0).ToUpper.Trim
Case "AC POWERED"
TextBox1.Text = values(1).ToUpper.Trim
Case "USB POWERED"
TextBox2.Text = values(1).ToUpper.Trim
Case "WIRELESS POWERED"
TextBox3.Text = values(1).ToUpper.Trim
Case "STATUS"
TextBox4.Text = values(1).ToUpper.Trim
Case "HEALTH"
TextBox5.Text = values(1).ToUpper.Trim
Case "PRESENT"
TextBox6.Text = values(1).ToUpper.Trim
Case "LEVEL"
TextBox7.Text = values(1).ToUpper.Trim
Case "SCALE"
TextBox8.Text = values(1).ToUpper.Trim
Case "VOLTAGE"
TextBox9.Text = values(1).ToUpper.Trim
Case "TEMPERATURE"
TextBox10.Text = values(1).ToUpper.Trim
Case "TECHNOLOGY"
TextBox11.Text = values(1).ToUpper.Trim
Case Else
MessageBox.Show(line, "Unknown Value")
End Select
Next
End Sub
If you named your TextBoxes in a predictable manner, then you can use Controls.Find() and shorten the code to the below. For instance, change spaces to underscore, and prepend "txt" in front: "txtAC_Powered", "txtUSB_Powered", "txtStatus", "txtHealth", etc. Case does NOT matter as a match will be found regardless. This means you're doing the manual work in naming your controls, as opposed to writing a long select case statement (or something else):
Private Sub UpdateText()
Dim lines() As String = Results.Split(vbCrLf.ToCharArray, StringSplitOptions.RemoveEmptyEntries)
For Each line In lines
Dim values() As String = line.Split(":")
Dim ctlName As String = "txt" & values(0).Replace(" ", "_").Trim
Dim ctl As Control = Me.Controls.Find(ctlName, True).FirstOrDefault
If Not IsNothing(ctl) Then
ctl.Text = values(1).ToUpper.Trim
End If
Next
End Sub

Related

Search through text file and return a line of text

I am trying to create a program that will search a text file for a line of text and then return the full line of information.
Example line: Joe Blogs JBL 1234
Search: Joe Blogs
Search returns: Joe Blogs JBL 1234
To make it as simple as possible, I have 2 text boxes & 1 button.
Textbox1 = search
Textbox2 = Search results
Button = Search button
Can anyone tell me how to do this because I'm finding it really difficult. I'm new to VB coding so the simplest of code would be helpful!
This is what I have so far:
Imports System.IO
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
' Input Text Error
If TextBox1.TextLength = 0 Then
MsgBox("Please enter a Staff Name or Staff Code", MsgBoxStyle.Information, "Error")
End If
'Perform Search
Dim strText As String = SearchFile("F:\Documents\Documents\Visual Studio 2015\Projects\ExtentionLocator\ExtentionLocator\Extentionlist.txt", TextBox1.Text)
If strText <> String.Empty Then
TextBox2.Text = strText
End If
End Sub
'Search Function
Public Shared Function SearchFile(ByVal strFilePath As String, ByVal strSearchTerm As String) As String
Dim sr As StreamReader = New StreamReader(strFilePath)
Dim strLine As String = String.Empty
Try
Do While sr.Peek() >= 0
strLine = String.Empty
strLine = sr.ReadLine
If strLine.Contains(strSearchTerm) Then
sr.Close()
Exit Do
End If
Loop
Return strLine
Catch ex As Exception
Return String.Empty
End Try
End Function
'Clear Button
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
TextBox2.Text = ""
TextBox1.Text = ""
End Sub
' Open The text file
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Process.Start("C:\Users\kylesnelling\Documents\Visual Studio 2015\Projects\ExtentionLocator\ExtentionLocator\Extentionlist.txt")
End Sub
End Class
Whenever I perform a search, all I get back is the last line of the text file... does anyone know why?
As Alex B has stated in comments, line If strLine.Contains("textbox1.text") should be If strLine.Contains(strSearchTerm)
Also you are not passing in the search item to the function. The below line you have passed in the string textbox1.text as a string rather than the text inside the textbox. Hence why you never find the line you are searching for and always returns the last record of your file.
Dim strText As String = SearchFile("F:\Documents\Documents\Visual Studio 2015\Projects\ExtentionLocator\ExtentionLocator\Extentionlist.txt", "textbox1,text")
This line should be:
Dim strText As String = SearchFile("F:\Documents\Documents\Visual Studio 2015\Projects\ExtentionLocator\ExtentionLocator\Extentionlist.txt", textbox1.text)
Also with this line Dim sr As StreamReader = New StreamReader("F:\Documents\Documents\Visual Studio 2015\Projects\ExtentionLocator\ExtentionLocator\Extentionlist.txt") why have you used the same path destination when you have already passed in this file location in the variable strFilePath.
line should be Dim sr As StreamReader = New StreamReader(strFilePath)
Its best to use the variables being passed into the function otherwise this function won't be very useful to other parts of code that may be referencing it or if search terms or filepaths change.
Updated from comments:
strLine.ToUpper.Contains(strSearchTerm.ToUpper) this line will make both text uppercase and the word you are searching for to uppercase, which will allow them to ignore case sensitivity, so for example, "text" can match with "Text" by both being converted to "TEXT" when used to compare.
Give this a try friend.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim searchResult As String = SearchFile("F:\Documents\Documents\Visual Studio 2015\Projects\ExtentionLocator\ExtentionLocator\Extentionlist.txt", _
"text to search for")
Me.TextBox2.Text = searchResult
End Sub
Public Shared Function SearchFile(ByVal strFilePath As String, ByVal strSearchTerm As String) As String
Dim fs As New System.IO.StreamReader(strFilePath)
Dim currentLine As String = String.Empty
Try
Dim searchResult As String = String.Empty
Do While fs.EndOfStream = False
currentLine = fs.ReadLine
If currentLine.IndexOf(strSearchTerm) > -1 Then
searchResult = currentLine
Exit Do
End If
Loop
Return searchResult
Catch ex As Exception
Return String.Empty
End Try
End Function

How to change filepath when check a radiobutton? Visual basic

My problem here is that i have 3 radiobuttons for 3 different categories:
Huse Folii and Altele.
The idea is when i select a radiobutton,the filepath will change to Huse,Folii or Altele.
For example i tried to make _path :
Dim _path As String = IO.Path.Combine("C:\Descriere\Huse\")
then use the _path here:
Dim ioFile As New System.IO.StreamReader(_path + "a.txt")
but it didn't worked,for sure i do something wrong,but i can't find how or where to use that _path...
Here is the code:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
On Error Resume Next
TextBox1.Clear()
If RadioButton1.Checked = True Then
Dim _path As String = IO.Path.Combine("C:\Descriere\Huse\")
End If
If RadioButton2.Checked = True Then
Dim _path As String = IO.Path.Combine("C:\Descriere\Folii\")
End If
If RadioButton3.Checked = True Then
IO.Path.
Dim _path As String = IO.Path.Combine("C:\Descriere\Altele\")
End If
Dim ioFile As New System.IO.StreamReader(_path + "a.txt")
Dim lines As New List(Of String)
Dim rnd As New Random()
Dim line As Integer
While ioFile.Peek <> -1
lines.Add(ioFile.ReadLine())
End While
line = rnd.Next(lines.Count + 1)
TextBox1.AppendText(lines(line).Trim())
ioFile.Close()
ioFile.Dispose()
Dim ioFile2 As New System.IO.StreamReader(path:=+"core.txt")
Dim lines2 As New List(Of String)
Dim rnd2 As New Random()
Dim line2 As Integer
While ioFile2.Peek <> -1
lines2.Add(ioFile2.ReadLine())
End While
line2 = rnd2.Next(lines2.Count + 1)
TextBox1.AppendText(lines2(line2).Trim())
ioFile2.Close()
ioFile2.Dispose()
Dim ioFile3 As New System.IO.StreamReader(path:=+"x.txt")
Dim lines3 As New List(Of String)
Dim rnd3 As New Random()
Dim line3 As Integer
While ioFile3.Peek <> -1
lines3.Add(ioFile3.ReadLine())
End While
line3 = rnd3.Next(lines3.Count + 1)
TextBox1.AppendText(lines3(line3).Trim())
ioFile3.Close()
ioFile3.Dispose()
TextBox1.Text = Replace(TextBox1.Text, "BRAND", TextBox2.Text)
TextBox1.Text = Replace(TextBox1.Text, "MODEL", TextBox3.Text)
Dim count As Integer = 0
count = TextBox1.Text.Split(" ").Length - 1
Label5.Text = "Caractere:" & Len(TextBox1.Text)
End Sub
You are using IO.Path.Combine but you have nothing to Combine at the place of use in your code. You have to use IO.Path.Combine later in your code because this is a method to Combine part of a path and a filename e.g. set your _path first and combine in a second step. Please note this code is not tested for your needs, because your coding is not clear to me.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim directoryName As String = "D:\"
On Error Resume Next
TextBox1.Clear()
If RadioButton1.Checked = True Then
directoryName = "D:\Descriere\Huse"
End If
If RadioButton2.Checked = True Then
directoryName = "D:\Descriere\Folii"
End If
If RadioButton3.Checked = True Then
'//--- IO.Path.
directoryName = "D:\Descriere\Altele"
End If
Dim ioFile As New System.IO.StreamReader(System.IO.Path.Combine(directoryName, "a.txt"))
...
Dim ioFile2 As New System.IO.StreamReader(System.IO.Path.Combine(directoryName, "core.txt"))
...
Dim ioFile3 As New System.IO.StreamReader(System.IO.Path.Combine(directoryName, "x.txt"))
...
End Sub
Please use the debugger of your IDE because your code isn't clean e.g. a hanging aroung IO.Path.

Textbox replace and split not working vb.net

I've been struggling way too much with simple things, like the one i'm posting.
I'm developing a UI in vb.net that gathers some information from a machine. The information is collected to a TextBox:
Private Sub ReceivedText(ByVal [text] As String)
If Me.TextBox2.InvokeRequired Then
Dim x As New SetTextCallBlack(AddressOf ReceivedText)
Me.Invoke(x, New Object() {(text)})
Else
Me.TextBox2.Text &= [text]
End If
End Sub
Then i gather that information either to a datagridview or to some labels to display simple information.
Sub dgv()
Dim sup2 = TextBox2.Text.Replace("#", "").Replace(">", " "c)
Dim sup() = sup2.Split(" "c, "#", vbCrLf, vbTab)
With DataGridView1
.Rows(0).Cells(0).Value = sup(1).ToString
.Rows(0).Cells(1).Value = sup(7).ToString
.Rows(0).Cells(3).Value = sup(4).ToString
End With
Button5.Enabled = True
Button6.Enabled = True
End Sub
This works just fine !!!
But when i try to populate the labels, with the code below, it just won't work!
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Thread.Sleep(250)
Dim final = TextBox2.Text.Replace("#", "").Replace("SN", " "c)
Dim final2() = final.Split(" "c, "#", vbCrLf, vbTab)
Label1.Text = final2(0).ToString
Textbox2.Text= final2(0).ToString
End Sub
Can someone help me? The label gets no text.. and the textbox gets all of it.
Btw, the textbox is multiline and if i paste the text in microsoft word it comes with tabs and extra spaces.
Edit: printscreen from microsoft word below [ related to Multiline Textbox to Datagridview ]
Edit2: This is so strange ..
If i do this
Label1.Text = "Testing" & TextBox2.Text
it only shows "Testing" on the label..
If you set the label to AutoSize, it will automatically grow with whatever text you put in it. (This includes vertical growth.)
Before assign value to the label1,
Use the below code
Label1.MaximumSize = new Size(100, 0)
Label1.AutoSize = true
your code would be like
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Thread.Sleep(250)
Dim final = TextBox2.Text.Replace("#", "").Replace("SN", " "c)
Dim final2() = final.Split(" "c, "#", vbCrLf, vbTab)
Label1.MaximumSize = new Size(100, 0)
Label1.AutoSize = true
Label1.Text = final2(0).ToString
Textbox2.Text= final2(0).ToString
End Sub

vb.net change combobox options depending on selected item in 2 previous comboboxes

I am creating a program which someone can input a search into a textbox and then narrow down the results using a series of comboboxes (or just use the comboboxes to search through everything).
The program looks like this: form 1
I have made the options in the 2nd combobox change using the following code:
Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
Dim type As String = ComboBox1.SelectedItem
Dim make As String = ComboBox2.SelectedItem
Dim model As String = ComboBox3.SelectedItem
Dim version As String = TextBox2.Text
Dim memory As String = TextBox3.Text
Dim problem As String = TextBox4.Text
Dim casenumber As Integer = Int(Rnd() * 9999) + 1000
If type = "Phone" Then
ComboBox2.Items.Clear()
Dim file As New System.IO.StreamReader("E: \phone.txt")
For i = 1 To 20
q(i) = file.ReadLine() & vbNewLine
ComboBox2.Items.Add(q(i))
Next
ElseIf type = "Tablet" Then
ComboBox2.Items.Clear()
Dim file As New System.IO.StreamReader("E:\tablet.txt")
For i = 1 To 20
q(i) = file.ReadLine() & vbNewLine
ComboBox2.Items.Add(q(i))
Next
ElseIf type = "Desktop computer" Then
ComboBox2.Items.Clear()
Dim file As New System.IO.StreamReader("E:\pc.txt")
For i = 1 To 20
q(i) = file.ReadLine() & vbNewLine
ComboBox2.Items.Add(q(i))
Next
ElseIf type = "Laptop" Then
ComboBox2.Items.Clear()
Dim file As New System.IO.StreamReader("E:\laptop.txt")
For i = 1 To 20
q(i) = file.ReadLine() & vbNewLine
ComboBox2.Items.Add(q(i))
Next
'Else
'Dim objwriter As System.IO.StreamWriter
'objwriter = My.Computer.FileSystem.OpenTextFileWriter("E:\unknown.txt", True)
'File.AppendText("type:" And ComboBox1.Text And "make" & ComboBox2.Text And "model: " & ComboBox3.Text And "version: " And TextBox2.Text & "memory" And TextBox3.Text)
End If
End Sub
However,the code won't work to change what is in the 3rd box. I have repeated the following code for each option:
Private Sub ComboBox2_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox3.SelectedIndexChanged
Dim type As String = ComboBox1.SelectedItem
Dim make As String = ComboBox2.SelectedItem
Dim model As String = ComboBox3.SelectedItem
Dim version As String = TextBox2.Text
Dim memory As String = TextBox3.Text
Dim problem As String = TextBox4.Text
If type = "Phone" Then
If make = "apple" Then
ComboBox2.Items.Clear()
Dim file As New System.IO.StreamReader("E:\apple.txt")
For i = 1 To 20
q(i) = file.ReadLine() & vbNewLine
ComboBox3.Items.Add(q(i))
Next
ElseIf make = "samsung" Then
ComboBox2.Items.Clear()
Dim file As New System.IO.StreamReader("E:\samsung.txt")
For i = 1 To 20
q(i) = file.ReadLine() & vbNewLine
ComboBox3.Items.Add(q(i))
Next
ElseIf make = "htc" Then
ComboBox2.Items.Clear()
Dim file As New System.IO.StreamReader("E:\htc.txt")
For i = 1 To 20
q(i) = file.ReadLine() & vbNewLine
ComboBox3.Items.Add(q(i))
Next
ElseIf make = "Nokia" Then
ComboBox2.Items.Clear()
Dim file As New System.IO.StreamReader("E:\Nokia.txt")
For i = 1 To 20
q(i) = file.ReadLine() & vbNewLine
ComboBox3.Items.Add(q(i))
Next
ElseIf make = "Blackberry" Then
ComboBox2.Items.Clear()
Dim file As New System.IO.StreamReader("E:\blackberry.txt")
For i = 1 To 20
q(i) = file.ReadLine() & vbNewLine
ComboBox3.Items.Add(q(i))
Next
I have checked the obvious problems like putting the wrong text file names and capital letters etc, but can't get this to work whatever I do.
Does anyone know why the third combobox remains blank even when both conditions are met (both combobox1 and 2 have the right thing selected)? Any suggestion would be much appreciated.
Firstly I suspect that this code :-
Dim type As String = ComboBox1.SelectedItem.ToString
Dim make As String = ComboBox2.SelectedItem.ToString
Dim model As String = ComboBox3.SelectedItem.ToString
Dim version As String = TextBox2.Text
Dim memory As String = TextBox3.Text
Dim problem As String = TextBox4.Text
shouldn't be in each if your events. They should really be placed somewhere that executes after all the information has been chosen yes?
OK for a start paste this into a text file called "device type.txt"
Phone,E:\phone.txt
Tablet,E:\tablet.txt
Desktop Computer,E:\pc.txt
Laptop,E:\laptop.txt
Then edit your phones.txt file and the rest of the above files to match that format e.g this phone.txt file
Apple,E:\apple.txt
Samsung,E:\samsung.txt
Htc,E:\htc.txt
Nokia,E\nokia.txt
Blackberry,E:\blackberry.txt
and so on for each item that links to another file. For the last files in the tree - which I presume are the files containing a list of the models for each brand of phone, just leave them as a simple list. No commas or anything after each model.
Use this code to do the populating of each ComboBox
Private Sub PopulateComboBox(ByRef cboBox As ComboBox, ByVal itemSource As String)
RemoveHandler ComboBox1.SelectedIndexChanged, AddressOf ComboBox1_SelectedIndexChanged
RemoveHandler ComboBox2.SelectedIndexChanged, AddressOf ComboBox2_SelectedIndexChanged
RemoveHandler ComboBox3.SelectedIndexChanged, AddressOf ComboBox3_SelectedIndexChanged
Dim devices As New List(Of item)
Dim csvFlag As Boolean = False
cboBox.Items.Clear()
Using MyReader As New Microsoft.VisualBasic.
FileIO.TextFieldParser(itemSource)
If MyReader.ReadLine.Contains(",") Then csvFlag = True
End Using
Using MyReader As New Microsoft.VisualBasic.
FileIO.TextFieldParser(itemSource)
If csvFlag Then
MyReader.TextFieldType = FileIO.FieldType.Delimited
MyReader.SetDelimiters(",")
End If
Dim currentRow As String() = {"", ""}
While Not MyReader.EndOfData
Try
If csvFlag Then
currentRow = MyReader.ReadFields()
Dim tempItem As New item
tempItem.item = currentRow(0)
tempItem.fileName = currentRow(1)
devices.Add(tempItem)
Else
currentRow(0) = MyReader.ReadLine
Dim tempItem As New item
tempItem.item = currentRow(0)
tempItem.fileName = ""
devices.Add(tempItem)
End If
Catch ex As Microsoft.VisualBasic.
FileIO.MalformedLineException
MsgBox("Line " & ex.Message & "is not valid and will be skipped.")
End Try
End While
End Using
If csvFlag Then
cboBox.DataSource = devices
cboBox.DisplayMember = "item"
cboBox.ValueMember = "fileName"
Else
cboBox.DataSource = devices
cboBox.DisplayMember = "item"
cboBox.ValueMember = "item"
End If
AddHandler ComboBox1.SelectedIndexChanged, AddressOf ComboBox1_SelectedIndexChanged
AddHandler ComboBox2.SelectedIndexChanged, AddressOf ComboBox2_SelectedIndexChanged
AddHandler ComboBox3.SelectedIndexChanged, AddressOf ComboBox3_SelectedIndexChanged
End Sub
What it does is firstly check to see if the file being read is a comma-delimited file.
If it is delimited, it will read the file referred to in itemSource and expect a pair of values. The first value is what you see in the box(the DisplayMember), and the second value is what clicking on the box actually returns(the ValueMember)
If the file isn't comma-delimited, it will just read each line and add it to the combobox so that it acts normally (this will be important for the last files in the tree)
Next you need these methods for the ComboBoxes
Private Sub PopulateComboBox1()
PopulateComboBox(ComboBox1, "E:\device type.txt")
End Sub
Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
PopulateComboBox(ComboBox2, ComboBox1.SelectedValue.ToString)
End Sub
Private Sub ComboBox2_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox2.SelectedIndexChanged
PopulateComboBox(ComboBox3, ComboBox2.SelectedValue.ToString)
End Sub
Private Sub ComboBox3_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox3.SelectedIndexChanged
PopulateComboBox(ComboBox3, ComboBox2.SelectedValue.ToString)
End Sub
Call the method to populate Combobox1 possibly in the form's load event.

Listview - select mosti similar item to value

How would one select item in listview (first column) that is most similar to string value from e.g. label or textbox.
Listview is populated with this code :
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
ListView1.Items.Clear()
ListView1.View = System.Windows.Forms.View.Details
ListView1.Columns.Add("COL1", 100, HorizontalAlignment.Left) 'KONTO
ListView1.Columns.Add("COL2", 140, HorizontalAlignment.Left) 'NAZIV
Dim FilePath As String = "W:\GLAVNI\KOR14\"
Dim DBF_File As String = "MATIKGL"
Dim ColName As String = "KONTO"
'Dim naz As String
Using con As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & FilePath & _
" ;Extended Properties=dBASE IV")
con.Open()
Using cmd As New OleDbCommand("SELECT * FROM MATIKGL ORDER BY KONTO, NAZIV", con)
Using reader As OleDbDataReader = cmd.ExecuteReader()
If reader.HasRows Then
While (reader.Read())
Me.ListView1.Items.Add(reader("KONTO"))
'ListView1.Items(i).SubItems.Add(rdr.Item("YourColumnName").ToString)
'BELOW SELECTS ALL ITEMS THAT STARTS WITH 2020-
For i = 0 To ListView1.Items.Count - 1
If ListView1.Items(i).ToString.Contains("2020-") Then
Else
ListView1.Items.Remove(ListView1.Items(i))
End If
Next
End While
Else
End If
End Using
End Using
con.Close()
End Using
End Sub
I have one textbox and a button.
Textual input from textbox should be compared with all items in listview and closest should be selected. One more thing : All items are sorted alphabetically
Button code is :
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
ListView1.MultiSelect = False
ListView1.FullRowSelect = True
Dim checkInt As Integer = FindItem(ListView1, "2020-" & TextBox1.Text)'this one is changed since all items starts with "2020-"& UCASE TEXT
If checkInt <> -1 Then
ListView1.Items(checkInt).Selected = True
ListView1.Focus()
Else
Label1.Text = "Search string not found"
End If
End Sub
UPDATED CODE
Dim checkInt As Integer = FindItem(ListView1, "2020-" & TextBox3.Text)
If checkInt <> -1 Then
TextBox4.Focus()
Else
Label14.Text = "NEMA"
On Error GoTo ext
Dim li As ListViewItem
ListView1.SelectedItems.Clear()
ListView1.HideSelection = False
li = ListView1.FindItemWithText("2020-" & UCase(TextBox3.Text))
If Not (li Is Nothing) Then
Me.ListView1.Focus()
li.Selected = True
li.EnsureVisible()
ElseIf li Is Nothing Then
li = ListView1.FindItemWithText("2020-" & Strings.Left(TextBox3.Text, 1))
Me.ListView1.Focus()
li.Selected = True
li.EnsureVisible()
Else
End If
Exit Sub
ext:
TextBox3.Text = ""
TextBox3.Focus()
Label14.Text = "String not found"
End If
This one works.
I know it's not the best solution but it's working.
Could fixed this without your help, thank you Phillip Trelford
Define a function to score two strings for closeness then use LINQ to find the lowest score, i.,e.
' Example score function
Function Score(a As String, b As String) As Integer
Dim index = 0
While index < a.Length And index < b.Length
Dim diff = Math.Abs(AscW(a(index)) - AscW(b(index)))
If diff <> 0 Then Return diff
index += 1
End While
Return Math.Abs(a.Length - b.Length)
End Function
Function Closest(searchWord As String, words As String()) As String
Dim ordered =
From w In words
Select Word = w, Score = Score(w, searchWord)
Order By Score
Return ordered.First().Word
End Function
Sub Main()
Dim words = {"Alpha", "Apple", "Ask"}
Dim searchWord = "Ann"
Dim word = Closest(searchWord, words)
Console.WriteLine(word)
End Sub
Update
To select the value in a WinForms ListView, you need to do roughly this:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
ListView1.MultiSelect = False
ListView1.FullRowSelect = True
Dim prefix = "2020-"
' Extract items from Listview
Dim items = New List(Of String)()
For Each item In ListView1.Items
items.Add(item)
Next
Dim words = items.ToArray()
Dim searchWord = TextBox1.Text
Dim resultWord = Closest(searchWord, words)
'this one is changed since all items starts with "2020-"& UCASE TEXT
Dim checkInt As Integer = FindItem(ListView1, prefix & resultWord)
If checkInt <> -1 Then
ListView1.Items(checkInt).Selected = True
ListView1.Focus()
Else
Label1.Text = "Search string not found"
End If
End Sub