Split when a character is found ( txt not delimited) using VB.net - vb.net

I am trying to populate a datagrid from a .txt file. I managed to do it with the split function Split(sr.ReadLine, " ") when I have all the rows identical with only one space, but the problem I have is that the txt file is not delimited and the "spaces" varies some time. This is a sample of my data:
Col1 Col2 Col3
1 Mary Yes
1234 John Yes
999 Leo No
So my question is how to delimit or split the line based when it finds the next character and ignore the empty spaces. This is the code I have.
OpenFileDialog1.Filter = "Text File|*.txt"
OpenFileDialog1.Title = "Open File..."
OpenFileDialog1.FileName = "test"
If OpenFileDialog1.ShowDialog() = DialogResult.OK Then
Dim sr As System.IO.StreamReader = New System.IO.StreamReader(OpenFileDialog1.FileName)
Dim srlineitems() As String
srlineitems = Split(sr.ReadLine, " ")
Dim DT As New DataTable
DT.Columns.Add("Col1")
DT.Columns.Add("Col2")
DT.Columns.Add("Col3")
DT.Columns.Add("Col4")
DataGridView1.DataSource = DT
Dim Lines() As String = System.IO.File.ReadAllLines(OpenFileDialog1.FileName)
For Each Line As String In Lines
Dim ItemsOf() As String = Split(Line, " ")
Dim NRow As String() = {ItemsOf(0), ItemsOf(1), ItemsOf(2), ItemsOf(3)}
DT.Rows.Add(NRow)
Next Line
End If
Any help is appreciated

Try the .Net String.Split method instead, it has a RemoveEmptyEntries option.
ItemsOf = Line.Split(New String() {" "},
StringSplitOptions.RemoveEmptyEntries)

Related

Split multi line in VB

I have a problem in split multi line in that it only splits the first line. I want to split all the lines.
Dim a As String
Dim b As String
Dim split = TextBox1.Text.Split(":")
If (split.Count = 2) Then
a = split(0).ToString
b = split(1).ToString
End If
TextBox2.Text = a
TextBox3.Text = b
You have to iterate all the lines in the textbox
For Each Ln As String In TextBox1.Lines
If Not String.IsNullOrEmpty(Ln) Then
Dim Lines() As String = Ln.Split(":"c)
If Lines.Length = 2 Then
TextBox2.Text &= Lines(0) & Environment.NewLine
TextBox3.Text &= Lines(1) & Environment.NewLine
End If
End If
Next
Edit- Updated to include condition checking to prevent index exceptions.
Edi2- It should be mentioned that drawing your strings into these textbox controls can take some time, it's not my place to judge your requirement, but you could optimize the routine by using collection based objects or stringbuilder.
IE:
Dim StrBldrA As New Text.StringBuilder
Dim StrBldrb As New Text.StringBuilder
For Each Ln As String In TextBox1.Lines
If Not String.IsNullOrEmpty(Ln) Then
Dim Lines() As String = Ln.Split(":"c)
If Lines.Length = 2 Then
StrBldrA.Append(Lines(0) & Environment.NewLine)
StrBldrb.Append(Lines(1) & Environment.NewLine)
End If
End If
Next
TextBox2.Text = StrBldrA.ToString
TextBox3.Text = StrBldrb.ToString

vb.net how do i add long text into csv

hello this is my firs thread ,
i'm trying to convert description of this page (https://www.tokopedia.com/indoislamicstore/cream-zaitun-arofah)
with regex and replace <br/> tag with new line and convert it to csv .
the datagridview it's alright but the csv got screwed
this is my code :
Dim dskrip As New System.Text.RegularExpressions.Regex("<p itemprop=""description"" class=""mt-20"">(.*?)\<\/p>\<\/div>")
Dim dskripm As MatchCollection = dskrip.Matches(rssourcecode0)
For Each itemdskrm As Match In dskripm
getdeskripsinew = itemdskrm.Groups(1).Value
Next
Dim deskripsinew As String = Replace(getdeskripsinew, ",", ";")
Dim deskripsitotal As String = Replace(deskripsinew, "<br/>", Environment.NewLine)
' ListView1.s = Environment.NewLine & deskripsinew
txtDeskripsi.Text = deskripsitotal
datascrapes.ColumnCount = 5
datascrapes.Columns(0).Name = "Title"
datascrapes.Columns(1).Name = "Price"
datascrapes.Columns(2).Name = "Deskripsi"
datascrapes.Columns(3).Name = "Gambar"
datascrapes.Columns(4).Name = "Total Produk"
Dim row As String() = New String() {getname, totalprice, deskripsitotal, directoryme + getfilename, "10"}
datascrapes.Rows.Add(row)
Dim filePath As String = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) & "\" & "Tokopedia_Upload.csv"
Dim delimeter As String = ","
Dim sb As New StringBuilder
For i As Integer = 0 To datascrapes.Rows.Count - 1
Dim array As String() = New String(datascrapes.Columns.Count - 1) {}
If i.Equals(0) Then
For j As Integer = 0 To datascrapes.Columns.Count - 1
array(j) = datascrapes.Columns(j).HeaderText
Next
sb.AppendLine(String.Join(delimeter, array))
End If
For j As Integer = 0 To datascrapes.Columns.Count - 1
If Not datascrapes.Rows(i).IsNewRow Then
array(j) = datascrapes(j, i).Value.ToString
End If
Next
If Not datascrapes.Rows(i).IsNewRow Then
sb.AppendLine(String.Join(delimeter, array))
End If
Next
File.WriteAllText(filePath, sb.ToString)
this is the csv file
I'm not sure where your problem is looking at the CSV file, but there are certain cases where you'll want to quote the values for a CSV. There's no official spec but RFC 4180 is often used as an unofficial standard. I would recommend using a library like CSV Helper

find the first number in the last line of text file and put ino integer variable visual basic

I am making a program that creates a text file that formats like so:
[1, * John, Doe, Family, 0002354561]
[2, * Jason, Doe, Obstetric, 0002358411]
[3, * Mikael, Doe, Pediatric, 0002352361]
[4, * Jamiel, Doe, Orthopedic, 0002354547]
What I need is a way to read the file and get the first number of the last line. and then put that into an integer.
I know i can read the first line like this:
Dim fileReader As System.IO.StreamReader
fileReader =
My.Computer.FileSystem.OpenTextFileReader(("..\..\..\Patients.txt"))
Dim stringReader As String
stringReader = fileReader.ReadLine()
MsgBox("The first line of the file is " & stringReader)
But how do i read the last line and get the second char into an integer variable?
Here is an example of how you could accomplish the task, this puts all the numbers into an arraylist. Not that by converting it to an long(or integer) it will remove any leading zeros
Public Function GetDigits() As System.Collections.ArrayList
Dim numList As System.Collections.ArrayList
numList = New System.Collections.ArrayList()
Dim fileReader As System.IO.StreamReader
fileReader = My.Computer.FileSystem.OpenTextFileReader(("C:\Patients.txt"))
Dim stringReader As String
While Not fileReader.EndOfStream
stringReader = fileReader.ReadLine()
If Trim(stringReader) = "" Then Continue While
Dim strParts
strParts = Split(stringReader, Chr(44))
Try
numList.Add(Integer.Parse(Trim(Replace(strParts(UBound(strParts)), "]", ""))))
Catch
MsgBox("Could not parse string: " & stringReader)
End Try
End While
fileReader.Close()
GetDigits = numList
End Function
I'm using something like this
Dim lastLine As String = File.ReadLines(myFileName) _
.Where(Function(f As String) (Not String.IsNullOrEmpty(f))).Last.ToString
Dim startpos As Integer = lastLine.IndexOf(",", 3)
lastline = Substring(lastline, startpos).Trim
Dim firstchar as String = Substring(lastline,0,1)
Dim result As Integer
If Integer.TryParse(firstchar, result) Then Return result _
Else Return -1

Combine multiple txt files alternately (vb.net)

Let me explain it on an excel sheet. I have few txt files in directory (f.txt, d.txt, s.txt, a.txt and q.txt). Each file has few lines of text. And I want to combine those files but in specific way - it is shown on screenshot.
and output should be:
I've already made a code but it doesn't work - I don't know why.
Dim fileEntries As String() = Directory.GetFiles("D:\dir\", "*.txt")
' Process the list of .txt files found in the directory. '
Dim i As Integer = 0
Dim filesCount As Integer = Directory.GetFiles("D:\dir\", "*.txt").Count
Do Until i = filesCount
'do it for every file in folder'
i = i + 1
Dim reader As New System.IO.StreamReader(fileEntries(i))
Dim files() As String = reader.ReadToEnd.Split({Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries)
Dim lineCount = File.ReadAllLines(fileEntries(i)).Length
Dim w As Integer = 0
Dim dt As DataTable
dt.Columns.Add(i)
'add column "0" for file 1, "1" for file 2 etc.'
Do Until w = lineCount
dt.Rows.Add(files(w))
'write each line in file 1 to column 0, etc.'
w = w + 1
Loop
Loop
Can somebody help me?
Read/write
If your goal is as shown in the last image, write back to a file named output.txt, then this can be done in a single line of code.
My.Computer.FileSystem.WriteAllText("D:\dir\output.txt", String.Join(Environment.NewLine, (From path As String In Directory.GetFiles("D:\dir", "*.txt") Where IO.Path.GetFileNameWithoutExtension(path) <> "output" Select My.Computer.FileSystem.ReadAllText(path, Encoding.UTF8))), False, Encoding.UTF8)
You can of course make this a bit more readable if you don't like one-liners.
My.Computer.FileSystem.WriteAllText(
"D:\dir\output.txt",
String.Join(
Environment.NewLine,
(
From
path As String
In
Directory.GetFiles("D:\dir", "*.txt")
Where
IO.Path.GetFileNameWithoutExtension(path) <> "output"
Select
My.Computer.FileSystem.ReadAllText(path, Encoding.UTF8)
)
),
False,
Encoding.UTF8
)
Iterate
If you need to iterate each line and/or each file, store the result in a local variable.
Dim files As IEnumerable(Of String()) = (
From
path As String
In
Directory.GetFiles("D:\dir", "*.txt")
Select
My.Computer.FileSystem.ReadAllText(path, Encoding.UTF8).Split({Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries)
)
For Each file As String() In files
For Each line As String In file
Next
Next
DataSet
If you need to create a DataSet from the result, then take advantage of anonymous types. This way you can store both the name of the file and its lines.
Dim files = (
From
path As String
In
Directory.GetFiles("D:\dir", "*.txt")
Select
New With {
Key .Name = IO.Path.GetFileNameWithoutExtension(path),
.Lines = My.Computer.FileSystem.ReadAllText(path, Encoding.UTF8).Split({Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries)
}
)
Dim data As New DataSet()
With data
.BeginInit()
For Each item In files
With data.Tables.Add(item.Name)
.BeginInit()
.Columns.Add("Column1", GetType(String))
.EndInit()
.BeginLoadData()
For Each line As String In item.Lines
.Rows.Add(line)
Next
.EndLoadData()
End With
Next
.EndInit()
End With
There are few problems in your code:
Your datatable was not initialized
value of w is exceed than the size of files array
Note: I use DataSet to add each DataTable, However you can remove it if it's not required.
Try following code:
Dim fileEntries As String() = Directory.GetFiles("C:\dir\", "*.txt")
' Process the list of .txt files found in the directory. '
Dim filesCount As Integer = Directory.GetFiles("C:\dir\", "*.txt").Count()
Dim ds As New DataSet()
For i As Integer = 0 To filesCount - 1
'do it for every file in folder'
i = i + 1
Dim reader As New System.IO.StreamReader(fileEntries(i))
Dim files As String() = reader.ReadToEnd().Split(New String() {Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries)
Dim lineCount = File.ReadAllLines(fileEntries(i)).Length
Dim w As Integer = 0
Dim dt As New DataTable()
dt.Columns.Add(i.ToString())
'add column "0" for file 1, "1" for file 2 etc.'
While w <> lineCount
If files.Length = w AndAlso w <> 0 Then
Continue While
End If
dt.Rows.Add(files(w))
'write each line in file 1 to column 0, etc.'
w = w + 1
End While
ds.Tables.Add(dt)
Next

How to select a value from a comma delimited string?

I have a string that contains comma delimited text. The comma delimited text comes from an excel .csv file so there are hundreds of rows of data that are seven columns wide. An example of a row from this file is:
2012-10-01,759.05,765,756.21,761.78,3168000,761.78
I want to search through the hundreds of rows by the date in the first column. Once I find the correct row I want to extract the number in the first position of the comma delimited string so in this case I want to extract the number 759.05 and assign it to variable "Open".
My code so far is:
strURL = "http://ichart.yahoo.com/table.csv?s=" & tickerValue
strBuffer = RequestWebData(strURL)
Dim Year As String = 2012
Dim Quarter As String = Q4
If Quarter = "Q4" Then
Dim Open As Integer =
End If
Once I can narrow it down to the right row I think something like row.Split(",")(1).Trim) might work.
I've done quite a bit of research but I can't solve this on my own. Any suggestions!?!
ADDITIONAL INFORMATION:
Private Function RequestWebData(ByVal pstrURL As String) As String
Dim objWReq As WebRequest
Dim objWResp As WebResponse
Dim strBuffer As String
'Contact the website
objWReq = HttpWebRequest.Create(pstrURL)
objWResp = objWReq.GetResponse()
'Read the answer from the Web site and store it into a stream
Dim objSR As StreamReader
objSR = New StreamReader(objWResp.GetResponseStream)
strBuffer = objSR.ReadToEnd
objSR.Close()
objWResp.Close()
Return strBuffer
End Function
MORE ADDITIONAL INFORMATION:
A more complete picture of my code
Dim tickerArray() As String = {"GOOG", "V", "AAPL", "BBBY", "AMZN"}
For Each tickerValue In Form1.tickerArray
Dim strURL As String
Dim strBuffer As String
'Creates the request URL for Yahoo
strURL = "http://ichart.yahoo.com/table.csv?s=" & tickerValue
strBuffer = RequestWebData(strURL)
'Create Array
Dim lines As Array = strBuffer.Split(New String() {Environment.NewLine}, StringSplitOptions.None)
'Add Rows to DataTable
dr = dt.NewRow()
dr("Ticker") = tickerValue
For Each columnQuarter As DataColumn In dt.Columns
Dim s As String = columnQuarter.ColumnName
If s.Contains("-") Then
Dim words As String() = s.Split("-")
Dim Year As String = words(0)
Dim Quarter As String = words(1)
Dim MyValue As String
Dim Open As Integer
If Quarter = "Q1" Then MyValue = Year & "-01-01"
If Quarter = "Q2" Then MyValue = Year & "-04-01"
If Quarter = "Q3" Then MyValue = Year & "-07-01"
If Quarter = "Q4" Then MyValue = Year & "-10-01"
For Each line In lines
Debug.WriteLine(line)
If line.Split(",")(0).Trim = MyValue Then Open = line.Split(",")(1).Trim
dr(columnQuarter) = Open
Next
End If
Next
dt.Rows.Add(dr)
Next
Right now in the For Each line in lines loop, Debug.WriteLine(line) outputs 2,131 lines:
From
Date,Open,High,Low,Close,Volume,Adj Close
2013-02-05,761.13,771.11,759.47,765.74,1870700,765.74
2013-02-04,767.69,770.47,758.27,759.02,3040500,759.02
2013-02-01,758.20,776.60,758.10,775.60,3746100,775.60
All the way to...
2004-08-19,100.00,104.06,95.96,100.34,22351900,100.34
But, what I expect is for Debug.WriteLine(line) to output one line at a time in the For Each line in lines loop. So I would expect the first output to be Date,Open,High,Low,Close,Volume,Adj Close and the next output to be 2013-02-05,761.13,771.11,759.47,765.74,1870700,765.74. I expect this to happen 2,131 times until the last output is 2004-08-19,100.00,104.06,95.96,100.34,22351900,100.34
You could loop through the lines and call String.Split to parse the columns in each line, for instance:
Dim lines() As String = strBuffer.Split(New String() {Environment.NewLine}, StringSplitOptions.None)
For Each line As String In lines
Dim columns() As String = line.Split(","c)
Dim Year As String = columns(0)
Dim Quarter As String = columns(1)
Next
However, sometimes CSV isn't that simple. For instance, a cell in a spreadsheet could contain a comma character, in which case it would be represented in CSV like this:
example cell 1,"example, with comma",example cell 3
To make sure you're properly handling all possibilities, I'd recommend using the TextFieldParser class. For instance:
Using parser As New TextFieldParser(New StringReader(strBuffer))
parser.TextFieldType = FieldType.Delimited
parser.SetDelimiters(",")
While Not parser.EndOfData
Try
Dim columns As String() = parser.ReadFields()
Dim Year As String = columns(0)
Dim Quarter As String = columns(1)
Catch ex As MalformedLineException
' Handle the invalid formatting error
End Try
End While
End Using
I would break it up into a List(of string()) - Each row being a new entry in the list.
Then loop through the list and look at Value(0).
If Value(0) = MyValue, then Open = Value(1)
You can use String.Split and this linq query:
Dim Year As Int32 = 2012
Dim Month As Int32 = 10
Dim searchMonth = New Date(Year, Month, 1)
Dim lines = strBuffer.Split({Environment.NewLine}, StringSplitOptions.None)
Dim dt As Date
Dim open As Double
Dim opens = From line In lines
Let tokens = line.Split({","c}, StringSplitOptions.RemoveEmptyEntries)
Where Date.TryParse(tokens(0), dt) AndAlso dt.Date = searchMonth AndAlso Double.TryParse(tokens(1), open)
If opens.Any() Then
open = Double.Parse(opens.First().tokens(1))
End If