extracting text from comma separated values in visual basic - vb.net
I have such kind of data in a text file:
12343,M,Helen Beyer,92149999,21,F,10,F,F,T,T,T,F,F
54326,F,Donna Noble,92148888,19,M,99,T,F,T,F,T,F,T
99999,M,Ed Harrison,92147777,28,F,5,F,F,F,F,F,F,T
88886,F,Amy Pond,92146666,31,M,2,T,F,T,T,T,T,T
37378,F,Martha Jones,92144444,30,M,5,T,F,F,F,T,T,T
22444,M,Tom Scully,92145555,42,F,6,T,T,T,T,T,T,T
81184,F,Sarah Jane Smith,92143333,22,F,5,F,F,F,T,T,T,F
97539,M,Angus Harley,92142222,22,M,9,F,T,F,T,T,T,T
24686,F,Rose Tyler,92142222,22,M,5,F,F,F,T,T,T,F
11113,F,Jo Grant,92142222,22,M,5,F,F,F,T,T,T,F
I want to extract the Initial of the first name and complete surname. So the output should look like:
H. Beyer, M
D. Noble, F
E. Harrison, M
The problem is that I should not use String Split function. Instead I have to do it using any other way of string handling.
This is my code:
Public Sub btn_IniSurGen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_IniSurGen.Click
Dim vFileName As String = "C:\temp\members.txt"
Dim vText As String = String.Empty
If Not File.Exists(vFileName) Then
lbl_Output.Text = "The file " & vFileName & " does not exist"
Else
Dim rvSR As New IO.StreamReader(vFileName)
Do While rvSR.Peek <> -1
vText = rvSR.ReadLine() & vbNewLine
lbl_Output.Text += vText.Substring(8, 1)
Loop
rvSR.Close()
End If
End Sub
You can use the TextFieldParserClass. It will parse the file and return the results directly to you as a string array.
Using MyReader As New Microsoft.VisualBasic.FileIO.
TextFieldParser("c:\logs\bigfile")
MyReader.TextFieldType =
Microsoft.VisualBasic.FileIO.FieldType.Delimited
MyReader.Delimiters = New String() {","}
Dim currentRow As String()
'Loop through all of the fields in the file.
'If any lines are corrupt, report an error and continue parsing.
While Not MyReader.EndOfData
Try
currentRow = MyReader.ReadFields()
' Include code here to handle the row.
Catch ex As Microsoft.VisualBasic.FileIO.MalformedLineException
MsgBox("Line " & ex.Message &
" is invalid. Skipping")
End Try
End While
End Using
For your wanted result, you may changed
lbl_Output.Text += vText.Substring(8, 1)
to
'declare this first
Dim sInit as String
Dim sName as String
sInit = vText.Substring(6, 1)
sName = ""
For x as Integer = 8 to vText.Length - 1
if vText.Substring(x) = "," Then Exit For
sName &= vText.Substring(x)
Next
lbl_Output.Text += sName & ", " & sInit
But better you have more than one lbl_Output ...
Something like this should work:
Dim lines As New List(Of String)
For Each s As String In File.ReadAllLines("textfile3.txt")
Dim temp As String = ""
s = s.Substring(s.IndexOf(","c) + 1)
temp = ", " + s.First
s = s.Substring(s.IndexOf(","c) + 1)
temp = s.First + ". " + s.Substring(s.IndexOf(" "c), s.IndexOf(","c) - s.IndexOf(" "c)) + temp
lines.Add(temp)
Next
The list Lines will contain the strings you need.
Related
“Input string was not in a correct format” while parsing the content of a file
I need help, I don't know why the array for the quantity in my input file strArr(1) having an error that says that the input string was not in a correct format. Dim objReader As IO.StreamReader Dim objWriter As New IO.StreamWriter("C:\Users\user\Desktop\StationeryFolder\output.txt") Dim strLine As String Dim strName As String Dim intQuantity As Integer Dim intTotal As Integer Dim strArr() As String If IO.File.Exists("C:\Users\user\Desktop\StationeryFolder\input.txt") = True Then objReader = IO.File.OpenText("C:\Users\user\Desktop\StationeryFolder\input.txt") Else MsgBox("File is not exist") Close() End If Do While objReader.Peek <> -1 strLine = objReader.ReadLine() strArr = strLine.Split(" ") strName = strArr(0) intQuantity = Convert.ToInt32(strArr(1)) //this is where the error occurs intTotal = intTotal + intQuantity lstDisplay.Items.Add(strName & " " & intQuantity.ToString()) objWriter.WriteLine(strName & " " & intQuantity.ToString()) Loop lstDisplay.Items.Add("Total Quantity of Stationeries are: " & intTotal.ToString()) objWriter.WriteLine("Total Quantity of Stationeries are: " & intTotal.ToString()) objReader.Close() objWriter.Close() Inside the input file: Markers 15 Pens 25
I used the .net File class instead of streams. ReadAllLine returns an array of the lines in the file. I used a StringBuilder which is mutable (changeable) unlike a String. Saves the code from creating and throwing away several strings. I have used interpolated strings indicated by the $ before the quotes. This allows inserting variables directly into the string surrounded by braces. Private Sub OPCode() Dim inputPath = "C:\Users\user\Desktop\StationeryFolder\input.txt" If Not IO.File.Exists(inputPath) Then MsgBox("File does not exist") Close() End If Dim lines = File.ReadAllLines(inputPath) Dim total As Integer Dim sb As New StringBuilder For i = 0 To lines.Length - 2 Step 2 lstDisplay.Items.Add($"{lines(i)} {lines(i + 1)}") sb.AppendLine($"{lines(i)} {lines(i + 1)}") total += CInt(lines(i + 1)) Next lstDisplay.Items.Add($"Total Quantity of Stationeries are: {total}") sb.AppendLine($"Total Quantity of Stationeries are: {total}") File.WriteAllText("C:\Users\user\Desktop\StationeryFolder\output.txt", sb.ToString) End Sub
Variable '' is used before it has been assigned a value.
I'm trying to make a program that downloads a bunch of domains and adds them windows hosts file but I'm having a bit of trouble. I keep getting an error when I try storing them in a list. I don't get why it doesn't work. Sub Main() Console.Title = "NoTrack blocklist to Windows Hosts File Converter" Console.WriteLine("Downloading . . . ") Dim FileDelete As String = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) & "/Downloads" & "/notracktemp.txt" If System.IO.File.Exists(FileDelete) = True Then System.IO.File.Delete(FileDelete) End If download() Threading.Thread.Sleep(1000) Dim s As New IO.StreamReader(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) & "/Downloads" & "/notracktemp.txt", True) Dim tempRead As String ' = s.ReadLine Dim tempSplit As String() ' = tempRead.Split(New Char() {" "}) Dim i As Integer = 0 Dim tempStore As String() s.ReadLine() s.ReadLine() Do Until s.EndOfStream = True tempRead = s.ReadLine tempSplit = tempRead.Split(New Char() {" "}) Console.WriteLine(tempSplit(0)) tempStore(i) = tempSplit(0)'The part that gives me the error i = i + 1 Loop Console.ReadKey() End Sub Sub download() Dim localDir As String = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) '"Enter file URL" Dim url As String = "https://quidsup.net/notrack/blocklist.php?download" '"Enter directory" Dim dirr As String = localDir & "/Downloads" & "/notracktemp.txt" My.Computer.Network.DownloadFile(url, dirr) 'System.IO.File.Delete(localDir & "/notracktemp.txt") End Sub
tempStore() has to have a size count number of lines in file with loop, then declare it as tempStore(i) where i is the amount of lines. Here is a function that counts the lines. Function countlines() Dim count As Integer Dim s As New IO.StreamReader(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) & "/Downloads" & "/notracktemp.txt", True) s.ReadLine() s.ReadLine() count = 0 Do Until s.EndOfStream = True s.ReadLine() count = count + 1 Loop Console.WriteLine(count) Return count Console.ReadKey() End Function Then what you do is: Dim count As Integer count = countlines() Dim tempStore(count) As String
For-loop doesn't complete all iterations
I have problem with this - I try to send broadcast SMS using AT Commands in my system. After that the SMS content will be stored in my database. My store content SMS function works well. I can store all my SMS content that I send, but the send function just sends message to my first data on my datagridview. Please help me to deal with this - I posted my code below Private Sub ButtonKirim_Click(sender As Object, e As EventArgs) Handles ButtonKirim.Click Dim noPel As String Dim isiPesan As String = "" Dim tgl As Date = Now.Date Dim strReplace(2) As String Dim strIsi(2) As String Dim tagBulan As String = "<bulan>" Dim tagtagihan As String = "<tagihan>" Dim tagLokasi As String = "<lokasi>" Dim pesanKirim As String = "" My.Settings.SettingPesan = RichTextBoxPesan.Text My.Settings.Save() 'Label4.Text = isiPesan For pelanggan As Integer = 0 To DataGridViewKirimPesan.RowCount - 1 'mengirim pesan/send message noPel = DataGridViewKirimPesan.Rows(pelanggan).Cells(3).Value() strReplace(0) = tagBulan strReplace(1) = tagtagihan strReplace(2) = tagLokasi strIsi(0) = DataGridViewKirimPesan.Rows(pelanggan).Cells(4).Value strIsi(1) = DataGridViewKirimPesan.Rows(pelanggan).Cells(5).Value strIsi(2) = DataGridViewKirimPesan.Rows(pelanggan).Cells(6).Value isiPesan = RichTextBoxPesan.Text For i As Integer = LBound(strReplace) To UBound(strReplace) isiPesan = isiPesan.Replace(strReplace(i), strIsi(i)) Next SendMessage(noPel, isiPesan) ''menyimpan pesan keluar ke sms_terkirim/this query store my content SMS to table Dim sqlSmsKeluar As String = "INSERT INTO sms_terkirim (`tgl_sms`,`id_pelanggan`, `isi_sms`) VALUES ( NOW()," & DataGridViewKirimPesan.Rows(pelanggan).Cells(0).Value & " , '" & isiPesan & "');" cudMethod(sqlSmsKeluar) MsgBox(sqlSmsKeluar) 'ProgressBarKirimPesan.Increment(1) Next 'MsgBox("Pesan Sukses Terkirim") ' Catch ex As Exception ' MsgBox("Pesan Gagal Terkirim" + ex.Message) 'End Try ' End If End Sub and this code is AT Command to send message Public Sub SendMessage(ByVal NomorPelanggan As String, ByVal IsiPesan As String) If SerialModem.IsOpen() Then With SerialModem .Write("AT" & vbCrLf) Threading.Thread.Sleep(100) .Write("AT+CMGF=1" & vbCrLf) Threading.Thread.Sleep(100) .Write("AT+CMGS=" & Chr(34) & NomorPelanggan & Chr(34) & vbCrLf) Threading.Thread.Sleep(100) .Write(IsiPesan & vbCrLf & Chr(26)) Threading.Thread.Sleep(100) End With Else MsgBox("Modem Belum Tersambung") End If End Sub
Visual Basic - system.nullReferenceException
So I'm still a bit of a newbie when it comes to programming, hence why I'm using visual basic. I'm getting this exception raised repeatedly, but the variables that vb is saying have unassigned values have been given values in my code. Can anyone point out where I'm going wrong with this? EDIT: just a few more details: the file exists, I can read from it using just the ReadLine method, but I need to split the fields so I can compare the scores and get the highest 2 scores Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load Dim srdFile As System.IO.StreamReader Dim strLine As String Dim strField(1) As String Dim strName() As String Dim strScore() As String Dim i = 0 srdFile = New System.IO.StreamReader("HighScores.dat") rtbOut.AppendText("HighScores:" & vbNewLine & vbNewLine) Do Until srdFile.Peek() = -1 strLine = srdFile.ReadLine() strField = strLine.Split(",") strName(i) = strField(0) strScore(i) = strField(1) rtbOut.AppendText(strName(i) & ", " & strScore(i) & vbNewLine) i = i + 1 Loop End Sub
Following two arrays are never initialized: strName and strScore I don't know the logic, but one way would be to use a List(Of String) instead which does not need to get the correct size in the first place and can be resized. I would also use the Using-statement to dispose the stream properly: Using srdFile As New System.IO.StreamReader("HighScores.dat") Dim strLine As String Dim strField(1) As String Dim strName As New List(Of String) Dim strScore As New List(Of String) Dim i = 0 rtbOut.AppendText("HighScores:" & vbNewLine & vbNewLine) Do Until srdFile.Peek() = -1 strLine = srdFile.ReadLine() strField = strLine.Split(","c) strName.Add(strField(0)) strScore.Add(strField(1)) rtbOut.AppendText(strName(i) & ", " & strScore(i) & vbNewLine) i += 1 Loop End Using Side-note: i recommend to set Option Strict to On by default. By the way, here is a completely different approach doing the same but with LINQ: Dim lines = From line In IO.File.ReadLines("HighScores.dat") Where Not String.IsNullOrWhiteSpace(line) Let fields = line.Split(","c) Let name = fields.First() Let score = fields.Last() Select String.Format("{0}, {1}", name, score) rtbOut.Text = String.Join(Environment.NewLine, lines) I find this more readable.
Before you use an array, you need to assign a fixed array size in the computer memory locations. You can do this by initialising an array with the number of array elements. In your code, you have not allocated any memory to strName() and strScore() before using them, hence the code will throw an exception. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Dim srdFile As System.IO.StreamReader Dim strLine As String Dim strField(1) As String Dim strName(10) As String ''fixed size array (Using List(Of T) is a better option) Dim strScore(10) As String ''fixed size array (Using List(Of T) is a better option) Dim i = 0 srdFile = New System.IO.StreamReader("HighScores.dat") rtbOut.AppendText("HighScores:" & vbNewLine & vbNewLine) Do Until srdFile.Peek() = -1 strLine = srdFile.ReadLine() strField = strLine.Split(",") strName(i) = strField(0) strScore(i) = strField(1) rtbOut.AppendText(strName(i) & ", " & strScore(i) & vbNewLine) i = i + 1 Loop End Sub You can also create a dynamic array. Please follow Resizing an array at runtime in VB.NET on Stackoverflow about dynamic array.
vb.net xls to csv with quotes?
I have a xls file, or a csv without quotes, and using vb.net need to turn it into a csv with quotes around every cell. If I open the xls/csv without quotes in MS Access, set every column to text and then export it, its in the format I need. Is there an easier way? If not, how do I do replicate this in vb.net? Thanks.
If you use the .Net OLE DB provider, you can specify the .csv formatting details in a schema.ini file in the folder your data files live in. For the 'unquoted' .csv the specs should look like [noquotes.csv] <-- file name ColNameHeader=True <-- or False CharacterSet=1252 <-- your encoding Format=Delimited(,) <-- TextDelimiter= <-- important: no " in source file Col1=VendorID Integer <-- your columns, of course Col2=AccountNumber Char Width 15 for the 'quoted' .csv, just change the name and delete the TextDelimiter= line (put quotes around text fields is the default). Then connect to the Text Database and execute the statement SELECT * INTO [quotes.csv] FROM [noquotes.csv] (as this creates quotes.csv, you may want to delete the file before each experimental run) Added to deal with "Empty fields must be quoted" This is a VBScript demo, but as the important things are the parameters for .GetString(), you'll can port it to VB easily: Dim sDir : sDir = resolvePath( "§LibDir§testdata\txt" ) Dim sSrc : sSrc = "noquotes.csv" Dim sSQL : sSQL = "SELECT * FROM [" & sSrc & "]" Dim oTxtDb : Set oTxtDb = New cADBC.openDb( Array( "jettxt", sDir ) ) WScript.Echo goFS.OpenTextFile( goFS.BuildPath( sDir, sSrc ) ).ReadAll() Dim sAll : sAll = oTxtDb.GetSelectFRO( sSQL ).GetString( _ adClipString, , """,""", """" & vbCrlf & """", "" _ ) WScript.Echo """" & Left( sAll, Len( sAll ) - 1 ) and output: VendorID;AccountNumber;SomethingElse 1;ABC 123 QQQ;1,2 2;IJK 654 ZZZ;2,3 3;;3,4 "1","ABC 123 QQQ","1,2" "2","IJK 654 ZZZ","2,3" "3","","3,4" (german locale, therefore field separator ; and decimal symbol ,) Same output from this VB.Net code: Imports ADODB ... Sub useGetString() Console.WriteLine("useGetString") Const adClipString As Integer = 2 Dim cn As New ADODB.Connection Dim rs As ADODB.Recordset Dim sAll As String cn.ConnectionString = _ "Provider=Microsoft.Jet.OLEDB.4.0;" _ & "Data Source=M:\lib\kurs0705\testdata\txt\;" _ & "Extended Properties=""text;""" cn.Open() rs = cn.Execute("SELECT * FROM [noquotes.csv]") sAll = rs.GetString( adClipString, , """,""", """" & vbCrLf & """", "" ) cn.Close() sAll = """" & Left( sAll, Len( sAll ) - 1 ) Console.WriteLine( sAll ) End Sub
Check out the method at this link. What you can do to make sure quotes go around is append quotes to the beginning and end of each column data in the loop that is putting the column data in the file. for example make the loop like this: For InnerCount = 0 To ColumnCount - 1 Str &= """" & DS.Tables(0).Rows(OuterCount).Item(InnerCount) & """," Next
Public Class clsTest Public Sub Test Dim s as string = "C:\!Data\Test1.csv" Dim Contents As String = System.IO.File.ReadAllText(s) Dim aryLines As String() = Contents.Split(New String() { Environment.Newline }, StringSplitOptions.None) Dim aryParts() As String Dim aryHeader() As String Dim dt As System.Data.DataTable For i As Integer = 0 To aryLines.Length - 1 aryParts = SplitCSVLine(aryLines(i)) If dt Is Nothing And aryHeader Is Nothing Then aryHeader = CType(aryParts.Clone, String()) ElseIf dt Is Nothing And aryHeader IsNot Nothing Then dt = DTFromStringArray(aryParts, 1000, "", aryHeader) Else DTAddStringArray(dt, aryParts) End If Next dt.dump End Sub Public Shared Function SplitCSVLine(strCSVQuotedLine As String) As String() Dim aryLines As String() = strCSVQuotedLine.Split(New String() {Environment.NewLine}, StringSplitOptions.None) Dim aryParts As String() = Nothing For i As Integer = 0 To aryLines.Length - 1 Dim regx As New Text.RegularExpressions.Regex(",(?=(?:[^\""]*\""[^\""]*\"")*(?![^\""]*\""))") aryParts = regx.Split(aryLines(i)) For p As Integer = 0 To aryParts.Length - 1 aryParts(p) = aryParts(p).Trim(" "c, """"c) Next Next Return aryParts End Function Public Shared Function DTFromStringArray(ByVal aryValues() As String, Optional ByVal intDefaultColumnWidth As Integer = 255, Optional ByVal strTableName As String = "tblArray", Optional ByVal aryColumnNames() As String = Nothing) As DataTable If String.IsNullOrWhiteSpace(strTableName) Then strTableName = "tblArray" Dim dt As DataTable = New DataTable(strTableName) Dim colNew(aryValues.GetUpperBound(0)) As DataColumn If aryColumnNames Is Nothing Then ReDim aryColumnNames(aryValues.Length) Else If aryColumnNames.GetUpperBound(0) < aryValues.GetUpperBound(0) Then ReDim Preserve aryColumnNames(aryValues.Length) End If End If For x As Integer = aryColumnNames.GetLowerBound(0) To aryColumnNames.GetUpperBound(0) If String.IsNullOrWhiteSpace(aryColumnNames(x)) Then aryColumnNames(x) = "Field" & x.ToString Else aryColumnNames(x) = aryColumnNames(x) End If Next For i As Integer = 0 To aryValues.GetUpperBound(0) colNew(i) = New DataColumn With colNew(i) .ColumnName = aryColumnNames(i) '"Value " & i .DataType = GetType(String) .AllowDBNull = False .DefaultValue = "" .MaxLength = intDefaultColumnWidth .Unique = False End With Next dt.Columns.AddRange(colNew) Dim pRow As DataRow = dt.NewRow For i As Integer = aryValues.GetLowerBound(0) To aryValues.GetUpperBound(0) pRow.Item(i) = aryValues(i) Next dt.Rows.Add(pRow) Return dt End Function Public Shared Sub DTAddStringArray(ByRef dt As DataTable, ByVal aryRowValues() As String) Dim pRow As DataRow pRow = dt.NewRow For i As Integer = aryRowValues.GetLowerBound(0) To aryRowValues.GetUpperBound(0) pRow.Item(i) = aryRowValues(i) Next dt.Rows.Add(pRow) End Sub End Class