Extract whole row/line using Lumenworks CSV Parser - vb.net

How do I read the whole row while using LumenWorks CVS parser? So far am only able to read entry by entry but not the whole row. i.e. if a row is a,b,c,d,e,f, am able to pluck out each individual alphabet. However, I want to be able to read the whole row
Currently I have:
my_csv = New CsvReader(New StreamReader(file_path), False, ",", resetPoint)
field_count = my_csv.FieldCount
While my_csv.ReadNextRecord()
'process the data here
'This code will process each individual alphabet in one row
The above reads each individual alphabet. What I want is to have something like
row = my_csv.row
Is this option available or something similar?
'EDITED'
When you have basic VB programming skills like me, this is what you come up with to solve the problem
Dim my_string As String = ""
For x As Integer = 0 To my_csv.FieldCount - 1
my_string += my_csv(x).ToString.Trim + ","
Next
my_string = Mid(my_string, 1, Len(my_string) - 1)
Return my_string
By all means use the code in the marked answer. Its super elegant!

I haven't found anything available, but this should work:
VB:
Dim rowFields = Enumerable.Range(0, my_csv.FieldCount).
Select(Function(field) my_csv(CInt(my_csv.CurrentRecordIndex), field))
Dim line As String = String.Join(my_csv.Delimiter.ToString(), rowFields)
C#:
var rowFields = Enumerable.Range(0, my_csv.FieldCount)
.Select(field => my_csv[(int)my_csv.CurrentRecordIndex, field]);
string line = string.Join(my_csv.Delimiter.ToString(), rowFields);

I found a method using the CopyCurrentRecordTo(array) method, which seems to be marginally faster (a few seconds) the wider (more columns) a file is:
C#:
string[] currentRow = new string[csv.FieldCount];
while (csv.ReadNextRecord())
{
csv.CopyCurrentRecordTo(currentRow);
var line = string.Join(csv.Delimiter.ToString(), currentRow);
}
VB (this is from Telerik converter, beware):
Dim currentRow As String() = New String(csv.FieldCount - 1) {}
While csv.ReadNextRecord()
csv.CopyCurrentRecordTo(currentRow)
Dim line = String.Join(csv.Delimiter.ToString(), currentRow)
End While

Related

Saving contents of multiple text boxes and possibly combo boxes

I'm working on a basic application that lets you track experience earned across up to 3 skills. The names of the skills are in a combo box (not sure if the best) and the beginning and ending values are in text boxes.
I want to add a save button that saves the ending values and selected skills, when pressing the load button it would populate the combo boxes with saved skills and input the old ending values into the new beginning ones.
I've been working on this all day, searching for a long time I've come up with similar solutions but nothing seems to work right. I'm still a bit of a beginner so some of the solutions I don't understand. Also, this has to work for VBNet.
The closest solution I've come across is:
File.WriteAllText("C:\Data.txt", String.Join("|", new String({TextBox1.Text, TextBox2.Text, TextBox3.Text}))
I'd like the file to stay with the project in the main directory though. Would this work for combo boxes as well, and how to load the values back in?
I'm still a newbie to VB, hope this question makes sense.
If I get your idea right, please find some functions below if they can help:
One can read (or write) text:
This one can populate the needed string to 3 textboxes txtSkill1, txtSkill2, txtSkill3
Sub ReadTextFile()
Dim lineCount As Integer = 0
Dim rndInstance As New Random
Dim idx As Integer = 0
Dim selectedLine As String = ""
Dim txt As String = "Skills.txt"
If Not File.Exists(txt) Then
File.Create(txt).Dispose()
Dim objWriter As New System.IO.StreamWriter(txt, True)
' 2 sample text lines:
objWriter.WriteLine("Negotiating - Interpersonal - Working independently")
objWriter.WriteLine("Goal oriented - Leadership - Teamwork")
objWriter.Close()
End If
lineCount = File.ReadAllLines(txt).Length
idx = rndInstance.Next(1, lineCount + 1) ' the index can be random if you want, or run from (1 to lineCount)
selectedLine = ReadLineWithNumberFrom(txt, idx)
Dim pattern As String = "-" ' split on hyphens
Dim subStrings() As String = Regex.Split(selectedLine, pattern)
txtSkill1.Text = subStrings(0)
txtSkill2.Text = subStrings(1)
txtSkill3.Text = subStrings(2)
End Sub
One can read a string from a specific line number:
Function ReadLineWithNumberFrom(filePath As String, ByVal lineNumber As Integer) As String
Using file As New StreamReader(filePath)
' Skip all preceding lines:
For i As Integer = 1 To lineNumber - 1
If file.ReadLine() Is Nothing Then
Throw New ArgumentOutOfRangeException("lineNumber")
End If
Next
' Attempt to read the line you're interested in:
Dim line As String = file.ReadLine()
If line Is Nothing Then
Throw New ArgumentOutOfRangeException("lineNumber")
End If
' Succeeded!
Return line
End Using
End Function
Now with the functions allow you to write to any text file, to read from any text file, from any line number, with specific separator (here is the hyphen -- char), you can Save and Load any string you need.

VB Loading a list of variables from a text document

I'm currently trying to load a list of variables that are formatted like this:
5,
6,
3,
3,
etc, and I'm trying to output them to variables like this:
Strength = variablesList(1)
Agility = variablesList(2)
But so far, I've not been able to find a solution that seems to work for what I'm trying to do.
I'm currently working with:
Dim destination As String = Environment.GetFolderPath("C:\Roll20Output\Class" + outputClass + "2.txt")
Dim FileReader1 As New StreamReader(destination)
Dim Contents1 As String
Dim index As Integer = 0
While FileReader1.Peek <> -1
Contents1 = FileReader1.ReadLine
Dim array As New ArrayList
array.AddRange(Contents1.Split(","))
variablesList.Add(array)
End While
Strength = variablesList(1)
Agility = variablesList(2)
But so far I can't seem to get anything to output.
Would anyone be able to help?
Thanks
You are using a lot of outdated stuff in your code (reading a file with StreamReader, ArrayList instead of List<T>, etc.). I would suggest the following (untested):
' Returns an array with one string per line
Dim lines = File.ReadAllLines("C:\...\SomeFile.txt")
' Remove trailing `,` - LINQ magic
lines = (From s In lines Select s.TrimEnd(","c)).ToArray()
Dim strength = CInt(lines(0))
Dim agility = CInt(lines(1))
...
If you get rid of the useless trailing commas, you can skip the second step. If you use only commas instead of new lines, the first step becomes:
Dim lines = File.ReadAllText("C:\...\SomeFile.txt").Split(","c)

How do I read a tab delimited file to find the line which has a known value?

I have a tab delimited file which has data like this...
022j<TAB>10.375
023j<TAB>12.365
024j<TAB>15.230
NOTE: this will not let me post as it is... each 02xj is a different line in the text file. It
EG: 023j is input into a textbox.
Need to find the value associated with the input; 12.365 in this case.
There are a few different files (some are encoded 012j, 012#, 012$ etc. which will correspond to different data.)
My head is exploding trying to find a way to take what I have in the textbox then read through and find the data I need.
I know this is easy, please nudge me in the right direction.
Here's your nudge. You should be able to use something like this:
Dim searchValue As Decimal = 023j 'or someTextBox.Text whatever
Dim searchField As Int32 = 0
Dim returnField As Int32 = 1
Dim returnValue As String = ""
Dim returnLineNumber as Int32 = 0
Using fileReader As New FileIO.TextFieldParser(YourFileNameWithPathAsString)
fileReader.TextFieldType = FileIO.FieldType.Delimited
fileReader.SetDelimiters(vbTab)
While Not fileReader.EndOfData
Dim currentLine As String() = fileReader.ReadFields()
If currentLine(searchField) = searchValue Then
returnValue = currentLine(returnField)
returnLineNumber = fileReader.LineNumber
Exit While
End If
End While
End Using
Return returnValue 'or Return returnLineNumber if that is what you need
You should be able to make it a function and if no result is returned then check your next file.
I figured this out... so this is what I ended up doing.
First set up the streamreader
'set reader to read the file
Dim reader As New System.IO.StreamReader(filetoread)
Then loop through the file line by line, use contains to find the string to match. Do whatever trimming/extracting and you're there.
Do While reader.Peek() >= 0
line = reader.ReadLine
If line.Contains(TB_Input.Text) Then
s = Replace(line, TB_Input.Text, "")
s = Replace(s, vbTab, "")
TB_Length.Text = s
End If
Loop
I was leaking brain juice on this. Until someone basically said "just do it"... thanks I needed that.
I know there are things like variables I don't explain... I figured anyone looking will know, if that's a bad assumption let me know.
Thanks again

My List(OF Strings) are being saved as system.string (Empty)

I'm trying to delete a selected row, then save the rest into a file. However, when I save it, it totally empties the file.
Console.Write("Please eneter the first name of the student you wish to search for: ")
searchfname = Console.ReadLine
searchfname = StrConv(searchfname, VbStrConv.ProperCase)
Console.Write("Please enter the second name of the student you wish to search for: ")
searchsname = Console.ReadLine
searchsname = StrConv(searchsname, VbStrConv.ProperCase)
Dim foundItem() As String = Nothing
Dim foundline As String = Nothing
Dim fnsearch As String = String.Join(searchfname, searchsname)
Dim lines As New List(Of String)(File.ReadAllLines("F:\Computing\Spelling Bee\stdnt&staffdtls.csv"))
For Each line As String In lines
If searchfname = item(3) And searchsname = item(4) Then
Console.WriteLine(line)
Console.WriteLine()
Console.WriteLine("Are you sure you wish to delete this record? (y/n)")
End If
Dim answer As String
answer = Console.ReadLine
If answer = "y" Or answer = "Y" Then
Console.Clear()
lines.Remove(line)
Using sw As New StreamWriter("F:\Computing\Spelling Bee\stdnt&staffdtls.csv")
sw.WriteLine(lines.ToString)
End Using
ElseIf answer = "n" Or answer = "N" Then
staffmenu()
End If
Next
Look at this line in your code:
sw.WriteLine(lines.ToString)
Extract the lines.ToString expression from that statement. The result of that expression is "System.String". You are telling your stream writer to write the text "System.String" to the file.
To fix it, you need something more like this:
Using sw As New StreamWriter("F:\Computing\Spelling Bee\stdnt&staffdtls.csv")
For Each line As String In lines
sw.WriteLine(line)
Next line
End Using
The method List(Of T).ToString does not produce a value that includes the elements of the collection. Instead it will just return the type name.
The API you are looking for is File.WriteAllLines. Using this instead of StreamWriter and the Using block
File.WriteAllLines("F:\Computing\Spelling Bee\stdnt&staffdtls.csv", lines)
I can see that this issue can be resolved from the given answers and comment, but I would like to add an alternative to use Join function in writing to a file. Try like this may be of help:
Using sw As New StreamWriter(.....)
sw.WriteLine(Join(lines.ToArray(), Environment.NewLine))
End Using
Since using VB.Net, this is a vb.net specific solution can not be used in C#. For C#, use string.join instead.
Hope it helps too!

Lowercase the first word

Does anybody know how to lowercase the first word for each line in a textbox?
Not the first letter, the first word.
I tried like this but it doesn't work:
For Each iz As String In txtCode.Text.Substring(0, txtCode.Text.IndexOf(" "))
iz = LCase(iz)
Next
When you call Substring, it is making a copy of that portion of the string and returning it as a new string object. So, even if you were successfully changing the value of that returned sub-string, it still would not change the original string in the Text property.
However, strings in .NET are immutable reference-types, so when you set iz = ... all you are doing is re-assigning the iz variable to point to yet another new string object. When you set iz, you aren't even touching the value of that copied sub-string to which it previously pointed.
In order to change the value of the text box, you must actually assign a new string value to its Text property, like this:
txtCode.Text = "the new value"
Since that is the case, I would recommend building a new string, using a StringBuilder object, and then, once the modified string is complete, then set the text box's Text property to that new string, for instance:
Dim builder As New StringBuilder()
For Each line As String In txtCode.Text.Split({Environment.NewLine}, StringSplitOptions.None)
' Fix case and append line to builder
Next
txtCode.Text = builder.ToString()
The solutions here are interesting but they are ignoring a fundamental tool of .NET: regular expressions. The solution can be written in one expression:
Dim result = Regex.Replace(txtCode.Text, "^\w+",
Function (match) match.Value.ToLower(), RegexOptions.Multiline)
(This requires the import System.Text.RegularExpressions.)
This solution is likely more efficient than all the other solutions here (It’s definitely more efficient than most), and it’s less code, thus less chance of a bug and easier to understand and to maintain.
The problem with your code is that you are running the loop only on each character of the first word in the whole TextBox text.
This code is looping over each line and takes the first word:
For Each line As String In txtCode.Text.Split(Environment.NewLine)
line = line.Trim().ToLower()
If line.IndexOf(" ") > 0 Then
line = line.Substring(0, line.IndexOf(" ")).Trim()
End If
// do something with 'line' here
Next
Loop through each of the lines of the textbox, splitting all of the words in the line, making sure to .ToLower() the first word:
Dim strResults As String = String.Empty
For Each strLine As String In IO.File.ReadAllText("C:\Test\StackFlow.txt").Split(ControlChars.NewLine)
Dim lstWords As List(Of String) = strLine.Split(" ").ToList()
If Not lstWords Is Nothing Then
strResults += lstWords(0).ToLower()
If lstWords.Count > 1 Then
For intCursor As Integer = 1 To (lstWords.Count - 1)
strResults += " " & lstWords(intCursor)
Next
End If
End If
Next
I used your ideas guys and i made it up to it like this:
For Each line As String In txtCode.Text.Split(Environment.NewLine)
Dim abc() As String = line.Split(" ")
txtCode.Text = txtCode.Text.Replace(abc(0), LCase(abc(0)))
Next
It works like this. Thank you all.