Why does my CSV Writer skips some lines? vb.net - vb.net

I dont know why my CSV writer skips some lines. I tried to export today a gridview and saw it by coincindence. The grid has 250 rows. It writes 1-60 and then goes on at 140-250. 61-139 are missing in the excel table?
to the code: First I create a list whith all columns, because the writer method shall be able to also write only specific columns, but this is another button.
Then the grid and the list is given to the csv Writer.
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
Dim list As List(Of Integer) = New List(Of Integer)
For Each column As DataGridViewColumn In datagridview2.Columns
list.Add(column.Index)
Next
Module3.csvwriter(list, datagridview2)
MsgBox("exportieren beendet")
End Sub
The csv-Writer creates a csv-body-String for every datarow.
For each row, append every columnvalue to body if the columnindex is in the list.
The best is, that I have seen how the method build row 61, but then it is missing in the csv :/
Public Sub csvwriter(list As List(Of Integer), grid As DataGridView)
Dim body As String = ""
Dim myWriter As New StreamWriter(Importverzeichnis.savecsv, True, System.Text.Encoding.Default)
Dim i As Integer
For i = 0 To grid.Rows.Count - 1
For ix = 0 To grid.Columns.Count - 1
If list.Contains(ix) Then
If grid.Rows(i).Cells(ix).Value IsNot Nothing Then
body = body + grid.Rows(i).Cells(ix).Value.ToString + ";"
Else
body = body + ";"
End If
End If
Next
myWriter.WriteLine(body)
body = ""
Next
myWriter.Close()
End Sub
Has anyone an idea? Do I overlook something?

I found an answer.
1. The csv file is complete. every row is in there.
The problem was or is, that in my datarows is a sign " which escapes the delimiter ; sign.
To solve the problem I save the file now as .txt file,
because then the user gets asked everytime when he opens the file, which one is the delimiter, which is the escaping sign.. this way the user is forced to put in the right settings, while a .csv file uses standard configurations..

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 Parse a text file, match column 1 to a variable, pass column 2 to another variable

I've written a script that will take a table out of a program, and export it to the local drive in a comma delimited text file. What I need is a script to read the text file. The user will input a string in a text box from Public Class Form 1, then the string gets passed to another Sub in Public Class SpaceMenuClass. The handoff looks ok, but I can't figure out how to parse the text file (match column 1 with the string, and store column 2 from that line to pass back to the SpacemenuClass). I know this may seem ambiguous, but hopefully makes some sense. Thanks to anyone in advance.
From Form1 Class
Private Sub BtnPlano_Click_(sender As Object, e As EventArgs) Handles BtnPlano.Click
If TxtBoxPlano.Text <> "" Then
SpaceCommands.SearchPlano(TxtBoxPlano.Text)
Else MessageBox.Show("Please Enter a Valid Planogram Name!")
End If
TxtBoxPlano.Clear()
End Sub
From SpaceMenuClass:
Public Sub SearchPlano(PlanoName As String)
For Each Plano As Space.Planogram In SpacePlanning.ForPlanograms()
SpacePlanning.SetActivePlanogram(Plano.Number - 1)
'Go open the Searchplano table on the shared drive
SpacePlanning.OpenTableChartView(AnalysisFileName:="\\SERVER1\JDA\Tables\SearchPlano.pst")
'Export the table to a Tab Delimited Text file
SpacePlanning.ExportTableData(ExportFileName:="C:\Temp\JDA\SearchPlano.txt", ExportMethod:=ExportMethod.CommaSeparated, UseCurrency:=False, UseQuotedStrings:=False, UseThousandsSeparator:=False)
'Close the Table
SpacePlanning.CloseTableChartView(AnalysisFileName:="\\SERVER1\JDA\Tables\SearchPlano.pst")
' Open the text file and parse it
Dim str As System.IO.StreamReader = New System.IO.StreamReader(New System.IO.FileStream("C:\Temp\JDA\SearchPlano.txt", System.IO.FileMode.Open))
Dim strline, arr(), Name, Nbr As String
Try
NextLine:
strline = str.ReadLine
arr = strline.Split(",")
Name = arr(0)
Nbr = arr(1)
If Name = PlanoName Then
SpacePlanning.SetActivePlanogram(Plano.Number = Nbr)
GoTo Finish
Else
GoTo NextLine
End If
Catch
End Try
Next
Finish:
My.Computer.FileSystem.DeleteFile("C:\Temp\JDA\SearchPlano.Txt")
End Sub
You open the file for reading, then try to delete it before closing it. This would raise an exception. To avoid this, wrap the StreamReader in a Using block. The End Using automatically disposes of the object (closes the file for you).
Public Sub SearchPlano(planoName As String)
For Each plano As Space.Planogram In SpacePlanning.ForPlanograms()
SpacePlanning.SetActivePlanogram(plano.Number - 1)
'Go open the Searchplano table on the shared drive
SpacePlanning.OpenTableChartView(AnalysisFileName:="\\SERVER1\JDA\Tables\SearchPlano.pst")
'Export the table to a Tab Delimited Text file
SpacePlanning.ExportTableData(
ExportFileName:="C:\Temp\JDA\SearchPlano.txt", ExportMethod:=ExportMethod.CommaSeparated,
UseCurrency:=False, UseQuotedStrings:=False, UseThousandsSeparator:=False)
'Close the Table
SpacePlanning.CloseTableChartView(AnalysisFileName:="\\SERVER1\JDA\Tables\SearchPlano.pst")
' Open the text file and parse it
Using str = New System.IO.StreamReader("C:\Temp\JDA\SearchPlano.txt")
Dim arr(), name, nbr As String
Do
If str.EndOfStream Then
' didn't find item!!!
End If
arr = str.ReadLine.Split(",")
name = arr(0)
nbr = arr(1)
Loop Until name = planoName
SpacePlanning.SetActivePlanogram(plano.Number = nbr)
End Using
Next
My.Computer.FileSystem.DeleteFile("C:\Temp\JDA\SearchPlano.Txt")
End Sub
I also cleaned up your loop and added a check for EndOfStream, in case you couldn't find a match (this would have thrown an exception too).
Also, changed the StreamReader to just open the file. You had a nested FileStream object in there, which would have required another Using block, and is unnecessary.

Vernam cipher key file sincronization

I am working in VB 2010 on a one-time pad software.
The problem is the following. I have a txt file with many continous characters like this "KHKJHDKJDHAKHDAKHDAKHAKDHADHAKJDHASJDHA", i need to read a variable number of this characters and after replace it with a same number of dots (Ex. read four chars "KHKJ" replaced them with four dots "....HDKJDETCETC"). After this i will have to memorize the position of the last dot, in the txt key file, for a next read of the remaining keys. How to do it?
Thanks to info.de for the quick reply and my apologize for not having deepened my request. Let me explain better, my project is a Vernam chat and i need to have one single keys txt file that must remain synchronized in some way between broadcaster and receiver. When I send the message the key used must be deleted and who receives after decripting delete it too.
The goal is synchronizing the two key files!
I thought something like this:
'READ PART
Using stream = File.OpenRead("c:\key.txt")
stream.Seek(v, SeekOrigin.Begin)
Dim b = New Byte(a - 1) {} '
stream.Read(b, 0, a)
Dim str = Encoding.ASCII.GetString(b)
txtPad.Text = str ' portions of code read in txt for encodinh/decoding
End Using
v = startup position for read in file key.txt
a= lenght of text in key.txt to be taken = lenght of text to encode
WRITE PART
Using stream = File.OpenWrite("c:\key.txt")
stream.Seek(v, SeekOrigin.Begin)
Dim b = New Byte(a - 1) {}
stream.Write(b, 0, 1)
End Using
But how can I overwrite (no delete) with dots taken characters using this code?
And above all what will be the next coordinates to repeat a subsequent encoding/decoding operation? (V changes constantly)
Thank's in advance.
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'//--- -----------------------------------------------
'//--- KHKJHDKJDHAKHDAKHDAKHAKDHADHAKJDHASJDHA-line1#
'//--- KHKJHDKJDHAKHDAKHDAKHAKDHADHAKJDHASJDHA-line2#
Dim lines() As String = System.IO.File.ReadAllLines(Application.StartupPath & "\TextFile1.txt")
Dim iReplaceLength As Integer
Dim sReplaceSubString As String
For Each line As String In lines
MessageBox.Show(line)
sReplaceSubString = "KHKJ"
iReplaceLength = sReplaceSubString.Length
MessageBox.Show(line.Replace(sReplaceSubString.ToCharArray, New String("."c, iReplaceLength)))
MessageBox.Show(line.Substring(iReplaceLength, line.Length - iReplaceLength))
Next
End Sub
End Class

loop - reading text after a certain string up until a certain string

start=AKS-RHzlSXSftLGYdBNk.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1&
For every instance of the word 'start' I need to be able to get the text after the first full stop, right up until the & symbol. E.g. 'eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1'.
There will be more than one instance of this. They will need to be appended to a listbox.
What is the simplest/quickest way to do this? (Using possibly streamreader - text file)
The simplest and quickest way will be to read each line, and check if it .StartsWith("start="). If so, then get the .IndexOf(".") and the .IndexOf("&", <whereever the first indexOf was>). Get the .SubString which encompasses those two values. I'm sure you can write the code yourself from that ;)
I tested this function with a button click, output text each line on a textbox. I am sure you can adapt this to your code.
Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
txtResults.Text = ""
Dim ParseString As String
ParseString = "start=123341.23124&kjdshfkjsdaksdstart=1231.2321312&kadhskjashdkjastart=1231.23126789898&skjdfhkjsd"
Dim Delimiters() As String = New String() {"start="}
Dim Words() As String
Words = ParseString.Split(Delimiters, CompareMethod.Text)
For Each Part In Words
Dim Middle As String
Middle = Part.Split(".").Skip(1).Take(1).FirstOrDefault()
Dim Good As String
Good = Middle.Split("&").FirstOrDefault()
txtResults.Text += Good + vbNewLine
Next
End Sub
Output was
23124
2321312
23126789898
Added 31104 lines to a string and ran, took about 11 seconds to run on my laptop. Might be too slow for your app?

How To Read From Text File & Store Data So To Modify At A Later Time

What I am trying to do may be better for use with SQL Server but I have seen many applications in the past that simply work on text files and I am wanting to try to imitate the same behaviour that those applications follow.
I have a list of URL's in a text file. This is simple enough to open and read line by line, but how can I store additional data from the file and query the data?
E.g.
Text File:
http://link1.com/ - 0
http://link2.com/ - 0
http://link3.com/ - 1
http://link4.com/ - 0
http://link5.com/ - 1
Then I will read the data with:
Private Sub ButtonX2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonX2.Click
OpenFileDialog1.Filter = "*txt Text Files|*.txt"
If OpenFileDialog1.ShowDialog() = DialogResult.OK Then
Dim AllText As String = My.Computer.FileSystem.ReadAllText(OpenFileDialog1.FileName)
Dim Lines() = Split(AllText, vbCrLf)
Dim list = New List(Of Test)
Dim URLsLoaded As Integer = 0
For i = 0 To UBound(Lines)
If Lines(i) = "" Then Continue For
Dim URLInfo As String() = Split(Lines(i), " - ")
If URLInfo.Count < 6 Then Continue For
list.Add(New Test(URLInfo(0), URLInfo(1)))
URLsLoaded += 1
Next
DataGridViewX1.DataSource = list
LabelX5.Text = URLsLoaded.ToString()
End If
End Sub
So as you can see, above I am prompting the user to open a text file, afterwards it is displayed back to the user in a datagridview.
Now here is my issue, I want to be able to query the data, E.g. Select * From URLs WHERE active='1' (Too used to PHP + MySQL!)
Where the 1 is the corresponding 1 or 0 after the URL in the text file.
In the above example the data is being stored in a simple class as per below:
Public Class Test
Public Sub New(ByVal URL As String, ByVal Active As Integer)
_URL = URL
_Active = Active
End Sub
Private _URL As String
Public Property URL() As String
Get
Return _URL
End Get
Set(ByVal value As String)
_URL = value
End Set
End Property
Private _Active As String
Public Property Active As String
Get
Return _Active
End Get
Set(ByVal value As String)
_Active = value
End Set
End Property
End Class
Am I going completely the wrong way about storing the data after importing from a text file?
I am new to VB.NET and still learning the basics but I find it much easier to learn by playing around before hitting the massive books!
Working example:
Dim myurls As New List(Of Test)
myurls.Add(New Test("http://link1.com/", 1))
myurls.Add(New Test("http://link2.com/", 0))
myurls.Add(New Test("http://link3.com/", 0))
Dim result = From t In myurls Where t.Active = 1
For Each testitem As Test In result
MsgBox(testitem.URL)
Next
By the way, LINQ is magic. You can shorten your loading/parse code to 3 rows of code:
Dim Lines() = IO.File.ReadAllLines("myfile.txt")
Dim myurls As List(Of Test) = (From t In lines Select New Test(Split(t, " - ")(0), Split(t, " - ")(1))).ToList
DataGridViewX1.DataSource = myurls
The first line reads all lines in the file to an array of strings.
The second line splits each line in the array, and creates a test-item and then converts all those result items to an list ( of Test).
Of course this could be misused to sillyness by making it to a one-row:er:
DataGridViewX1.DataSource = (From t In IO.File.ReadAllLines("myfile.txt") Select New Test(Split(t, " - ")(0), Split(t, " - ")(1))).ToList
Wich would render your load function to contain only following 4 rows:
If OpenFileDialog1.ShowDialog() = DialogResult.OK Then
DataGridViewX1.DataSource = (From t In IO.File.ReadAllLines("myfile.txt") Select New Test(Split(t, " - ")(0), Split(t, " - ")(1))).ToList
LabelX5.Text = ctype(datagridviewx1.datasource,List(Of Test)).Count
End If
You can query your class using LINQ, as long as it is in an appropriate collection type, like List(of Test) . I am not familiar completely with the VB syntax for LINQ but it would be something like below.
list.Where(Function(x) x.Active == "1").Select(Function(x) x.Url)
However, this isnt actually storing anything into a database, which i think your question might be asking?
I think you are reinventing the wheel, which is not generally a good thing. If you want SQL like functionality just store the data in a SQL DB and query it.
There are a lot of reasons you should just use an existing DB:
Your code will be less tested and thus more likely to have bugs.
Your code will be less optimized and probably perform worse. (You were planning on implementing a query optimizer and indexing engine for performance, right?)
Your code won't have as many features (locking, constraints, triggers, backup/recovery, a query language, etc.)
There are lots of free RDBMS options out there so it might even be cheaper to use an existing system than spending your time writing an inferior one.
That said, if this is just an academic exercise, go for it. However, I wouldn't do this for a real-world system.