how to order a text file without using array and query - vb.net

I'm trying to order a text file which contain numbers and rewrite it in other textile without using query of array
i try to do it using a comparing statement but in the end it only write one number in the new text file
to make it clear the program is to find the median number in that file which is something i can't do without reordering the file descending or ascending
This is what i did
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim sw As IO.StreamReader = IO.File.OpenText("Numbers.txt")
Dim sr As IO.StreamWriter = IO.File.CreateText("Numbers2.txt")
Dim num As Double
Dim min As Double = CDbl(sw.ReadLine)
Dim line As String = sw.ReadLine
Do Until sw.EndOfStream
num = CDbl(sw.ReadLine)
If min > num Then
sr.WriteLine(num)
End If
Loop
sr.Close()
End Sub

Well, of curse I have no idea how your text file looks, I can't help without his string format
So I made two functions who will help about the median program
the program is to find the median number in that file
You can test this code just add 1 button in a frame that's all (I wrote some strings for test, you can change it)
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
If Button1.Text = "20; 30; 50; 40; 10; 80; 90; 70" Then 'A pair list of simple numbers
Button1.Text = "20; 30; 50; 40; 80; 90; 70" 'Odd list of simple numbers
Else
If Button1.Text = "20; 30; 50; 40; 80; 90; 70" Then
Button1.Text = "18; 91,123; 47,789; 29; 35; 78.456; 91; 84" 'A test with a mix of some decimal separators mistakes
Else
If Button1.Text = "18; 91,123; 47,789; 29; 35; 78.456; 91; 84" Then
Button1.Text = "25.45; 78; 10.123; 65; 27.485; 78; 19; 41; 26" 'Another odd test
Else
Button1.Text = "20; 30; 50; 40; 10; 80; 90; 70"
End If
End If
End If
Dim StringList As String = Button1.Text
Me.Text = "Medan of " & StringList & " = " & MedianOf(StringList, "; ") 'Using "; " (; + space) separator (can be changed)
End Sub
Private Function MedianOf(ByVal StrLine As String, ByVal Separator As String) As Double
Dim Nb As Double
Dim Str As String = StrLine
'Write all values in the good order with the next function down here e.g.(from "23; 12; 78; ..." to "12; 23; 78; ...")
StrLine = GetOrderOf(StrLine, Separator)
'Counts how many values StrLine contains
Dim ValuesInString = System.Text.RegularExpressions.Regex.Split(StrLine, "\" & Separator).GetUpperBound(0) + 1
'Check ValuesInString count odd's (calculated with different ways)
If ((ValuesInString And 1) = 1) = True Then
Nb = CDbl(System.Text.RegularExpressions.Regex.Split(StrLine, "\" & Separator)(ValuesInString \ 2))
MessageBox.Show("ODD:" & Environment.NewLine & "First String = " & Str & Environment.NewLine & "Ordered string = " & StrLine & Environment.NewLine & "*** Median value = " & Nb & " ***")
Else
Nb = (CDbl(System.Text.RegularExpressions.Regex.Split(StrLine, "\" & Separator)((ValuesInString / 2) - 1)) + CDbl(System.Text.RegularExpressions.Regex.Split(StrLine, "\" & Separator)(ValuesInString / 2))) / 2
MessageBox.Show("PAIR:" & Environment.NewLine & "First String = " & Str & Environment.NewLine & "Ordered string = " & StrLine & Environment.NewLine & "(" & StrLine.Split(Separator)((ValuesInString / 2) - 1) & "+" & StrLine.Split(Separator)(ValuesInString / 2) & ")/2 = " & Nb)
End If
'MessagesBoxes were added only for a best understanding of how it works
'Should be disabled if tests are ok
Return Nb
End Function
Private Function GetOrderOf(ByVal Line As String, ByVal Separator As String) As String
If Separator = "." Or Separator = "," Then MessageBox.Show("Wrong... so Wrong separator")
Line = Line.Replace(".", ",")
Dim Line_InOrder As String = ""
Dim Str As String = ""
Dim Nb As Double = 0
Do While Line.Length > 0
Nb = 0
If Line.Contains(Separator) Then
For Each St As String In System.Text.RegularExpressions.Regex.Split(Line, "\" & Separator)
If CDbl(St) > Nb Then
Nb = CDbl(St)
Str = St
End If
Next
Else
Str = Line
Line &= Separator
End If
If Line.Contains(Str & Separator) Then
Line = Replace(Line, Str & Separator, "", , 1)
Else
Line = Replace(Line, Separator & Str, "", , 1)
End If
If Line_InOrder.Length = 0 Then
Line_InOrder = Str
Else
Line_InOrder = Str & Separator & Line_InOrder
End If
Loop
Return Line_InOrder
End Function

Related

Efficiently append .csv files together (VB.NET)

I have a question regarding a piece of coding I would like to make more efficient in Visual Basic. What I am trying to do is the following:
I have a folder containing 100 .csv files (comma delimited), these files have around 5000 lines and around 200 columns. The order of columns may vary from one file to another, and some column are missing in some files.
My goal is to create one big .csv file that combines all the 100 .csv files, with a selection of column that I specify in advance.
Here is how I proceed:
Create an array to store the name of the columns I want in the final “big .csv”
Loop through all the files in the folder. For each file,
For each line in the file, use the Split function, to create an array containing all the values for a given line.
create a mapping array, that store the position of the column in the file for each column name chosen in the first step (do this only for the first line of each file)
Write in a file (“the big .csv”) the header (do this only once)
Write in the same big file, for each line of each file, the data based on the position of the column.
So that process works well, I get the outcome that I want but it is very slow… (It takes ~40min on my computer for ~200 files which once appended contains 500,000 lines and 200 columns. A colleague has managed to do a similar process, appending all the files, using the data.table package in R, and he is able to perform the same appending with the same .csv tables in 5-10min on the same computer)
I was wondering if there is a better alternative than going through the file “cell by cell”? Could I identify the column I don’t want from the source file and delete them entirely? Is there a function to append files together rather than reading each cell and then write them back?
Edit: Alternatively, is there another programming language that is significantly more efficient (Python? Power-Shell?) to do this kind of files manipulation?
Edit2: More details about why I consider it slow.
Edit3: The piece of code relevant to my question as requested in the comments:
Public Module Public_Variables
'Initializr technical parameters
Public Enable_SQL_Upload As String = "Yes"
Public Enable_CSV_Output As String = "Yes"
Public Enable_Runlog As String = "Yes"
Public MPF_Type As String
'Initialize Path and Folder location
Public Path As String '= "L:\Prophet\1902_Analysis\results\RUN_200" ' "S:\Users\Jonathan\12_Project_Space\Input" '"K:\Prophet\1809\Model_B2_LS_Analysis\results\RUN_31"
'Initialize parameters for Actuarial SQL database connection
Public SQLServer As String '= "MELAIPWBAT01"
Public SQLDataBase As String '= "VALDATA"
Public SQLTableName As String '= "RPT_1902_" & Right(Path, 7) '"aMPF_Retail_1808"
Public HeaderScopeFileName As String
Public ValidFilesFileName As String = "S:\Users\Jonathan\12_Project_Space\Tables\ValidFiles.txt"
Public InputFileName As String = "S:\Users\Jonathan\12_Project_Space\Tables\Input.txt"
Public tsrl As String = Now.Year.ToString() + Now.Month.ToString() + Now.Day.ToString() + "_" + Now.Hour.ToString() + "h" + Now.Minute.ToString() + "m" + Now.Second.ToString() + "s"
Public RunLogFileName As String = "\\Melaipwbat01\c$\Users\AACT064\Desktop\SQL_CSV_BULK_INSERT\RunLog" & tsrl & ".csv"
Public RunLogFile As IO.StreamWriter = My.Computer.FileSystem.OpenTextFileWriter(RunLogFileName, False)
Public HeaderFile1 As String '= "K:\Prophet\1903\MPF\MPF_SNAPSHOT\C_TROC.rpt" ' "K:\Prophet\1903\Model_B2_LS_Analysis\results\RUN_200\C_TROC.rpt" '"K:\Prophet\1809\Model_B2_LS_Analysis\results\RUN_31\C_DIO0.rpt"
Public HeaderFile2 As String '= "K:\Prophet\1901\Model_GRP\results\RUN_16\CORS_0.rpt" '"K:\Prophet\1809\Model_B2_LS_Analysis\results\RUN_31\C_DIO0.rpt"
Public ValidFilesFile As New System.IO.StreamReader(ValidFilesFileName)
'UserForm Design
'Public UserFormHeight_Start As Integer = 800
'Public UserFormWidth_Start As Integer = 800
Public UserFormHeight_ProgressBarExtension As Integer = 0
Public UserFormWidth_ProgressBarExtension As Integer = 0
'Initialize Misc.
Public Input_Array(,) As String
Public TextLine As String
Public TextLineSplit() As String
Public ValidFilesArray(,) As String
Public RecordCount As Integer = 0
Public BodyString As String = ""
Public SqlCommandText1 As String = ""
Public SqlCommandText2 As String = ""
'Initialize IS variables
Public Is_RPT_Name As Integer = 1
Public Is_RPT_Type As Integer = 2
Public Is_RPT_Valid As Integer = 3
Public Is_Name As Integer = 1
Public Is_Type As String = 2
Public Is_Not_found As Integer = -1
Public Is_RetailDCS As Integer = 0
Public Is_GroupDCS As Integer = 1
Public Is_MPF_Type As Integer
Public Is_Input_Header As Integer = 1
Public Is_Input_Path As Integer = 2
Public Is_Input_Server As Integer = 3
Public Is_Input_Database As Integer = 4
Public Is_Input_TableName As Integer = 5
Public Is_Input_HeaderFileRetailDCS As Integer = 6
Public Is_Input_HeaderFileGroupDCS As Integer = 7
'Initialize temp variables
Public temp_Valid As Integer
'Initialize the header of the SQL table that is created from that application
Public HeaderScope(,) As String
Public HeaderMapId(,) As String
Public HeaderStringSQL As String = ""
Public HeaderStringCSV As String = ""
Public MappingFound As Boolean
'Initialization for the files looping
Public temp_file As Integer = 1
Public temp_line As Integer
Public temp_headerfile As String
Public FileSize As Integer
Public TimerCounter As Integer = 0
End Module
Public Class UF_UserForm
Private Sub UF_UserForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'Me.Height = UserFormHeight_Start
'Me.Width = UserFormWidth_Start
TB_Input.Text = InputFileName
CB_SQLUpload.Text = Enable_SQL_Upload
CB_CSVOutput.Text = Enable_CSV_Output
CB_Runlog.Text = Enable_Runlog
GB_Progress.Visible = False
End Sub
Private Sub B_Run_Click_1(sender As Object, e As EventArgs) Handles B_Run.Click
'Disable the button, switch to 'Progress' tab
B_Run.Enabled = False
TabControl1.SelectedIndex = 1
'Start the Timer
Timer1.Interval = 1000
TimerCounter = 0
Timer1.Start()
'Initilialize the parameters with the Text Box values
TB_Server.Enabled = False
TB_Database.Enabled = False
TB_TableName.Enabled = False
TB_Path.Enabled = False
TB_FileType.Enabled = False
CB_SQLUpload.Enabled = False
CB_CSVOutput.Enabled = False
CB_Runlog.Enabled = False
Enable_SQL_Upload = CB_SQLUpload.Text
Enable_CSV_Output = CB_CSVOutput.Text
Enable_Runlog = CB_Runlog.Text
'Extract the inputs from the input.txt file
Dim temp_Input As Integer
Dim InputFirstCol As String
Dim InputSecCol As String
Dim Nb_Of_Runs As Integer
Dim EndOfLoop As Boolean
InputFileName = TB_Input.Text
Dim InputFile As New System.IO.StreamReader(InputFileName)
temp_Input = 0
EndOfLoop = False
Do While InputFile.Peek() <> -1 And EndOfLoop = False
TextLine = InputFile.ReadLine()
TextLineSplit = TextLine.Split(",")
InputFirstCol = TextLineSplit(0)
If InputFirstCol <> "#" And InputFirstCol <> "" And InputFirstCol <> "--End--" Then
InputSecCol = TextLineSplit(1)
Else
InputSecCol = ""
End If
If InputFirstCol = "--End--" Then
EndOfLoop = True
Else
If InputFirstCol = "#" Then
temp_Input = temp_Input + 1
ElseIf InputFirstCol = "HeaderScope" Then
ReDim Preserve Input_Array(7, temp_Input)
Input_Array(Is_Input_Header, temp_Input) = InputSecCol
ElseIf InputFirstCol = "Path" Then
Input_Array(Is_Input_Path, temp_Input) = InputSecCol
ElseIf InputFirstCol = "Server" Then
Input_Array(Is_Input_Server, temp_Input) = InputSecCol
ElseIf InputFirstCol = "Database" Then
Input_Array(Is_Input_Database, temp_Input) = InputSecCol
ElseIf InputFirstCol = "TableName" Then
Input_Array(Is_Input_TableName, temp_Input) = InputSecCol
ElseIf InputFirstCol = "HeaderFileRetailDCS" Then
Input_Array(Is_Input_HeaderFileRetailDCS, temp_Input) = InputSecCol
ElseIf InputFirstCol = "HeaderFileGroupDCS" Then
Input_Array(Is_Input_HeaderFileGroupDCS, temp_Input) = InputSecCol
End If
End If
Loop
Nb_Of_Runs = temp_Input
'Create an array to store the timer per run
Dim Timer_Array(Nb_Of_Runs) As String
'Let's start the loop for each run
For temp_Run = 1 To Nb_Of_Runs
'Initialize date stamp variables and create the date stamp (called ts)
Dim now As DateTime = DateTime.Now
Dim ts As String = now.Year.ToString() + now.Month.ToString() + now.Day.ToString() + "_" + now.Hour.ToString() + "h" + now.Minute.ToString() + "m" + now.Second.ToString() + "s"
Dim temp_full_count As Integer = 0
Dim File_Count As Integer = 0
Dim temp_count As Integer = 0
'Open the.csv file
Dim OutputCSVFileName As String = "\\Melaipwbat01\c$\Users\AACT064\Desktop\SQL_CSV_BULK_INSERT\SQL_Upload" & ts & ".csv" ' "S:\Users\Jonathan\12_Project_Space\Output\RPT_Files" & ts & ".csv"
Dim SQLUploadFileName As String = Replace(OutputCSVFileName, "\\Melaipwbat01\c$", "C:")
Dim SQLQueriesFileName As String = "\\Melaipwbat01\c$\Users\AACT064\Desktop\SQL_CSV_BULK_INSERT\SQL_Queries" & ts & ".csv"
Dim outFile As IO.StreamWriter = My.Computer.FileSystem.OpenTextFileWriter(OutputCSVFileName, False)
Dim SQLQueriesFile As IO.StreamWriter = My.Computer.FileSystem.OpenTextFileWriter(SQLQueriesFileName, False)
'Store the inputs from the Input_Array
SQLServer = Input_Array(Is_Input_Server, temp_Run)
TB_Server.Text = Input_Array(Is_Input_Server, temp_Run)
SQLDataBase = Input_Array(Is_Input_Database, temp_Run)
TB_Database.Text = Input_Array(Is_Input_Database, temp_Run)
SQLTableName = Input_Array(Is_Input_TableName, temp_Run)
TB_TableName.Text = Input_Array(Is_Input_TableName, temp_Run)
Path = Input_Array(Is_Input_Path, temp_Run)
TB_Path.Text = Input_Array(Is_Input_Path, temp_Run)
HeaderScopeFileName = Input_Array(Is_Input_Header, temp_Run)
TB_FileType.Text = Input_Array(Is_Input_Header, temp_Run)
HeaderFile1 = Input_Array(Is_Input_HeaderFileRetailDCS, temp_Run)
TB_HeaderRetailDCS.Text = Input_Array(Is_Input_HeaderFileRetailDCS, temp_Run)
HeaderFile2 = Input_Array(Is_Input_HeaderFileGroupDCS, temp_Run)
TB_HeaderGroupDCS.Text = Input_Array(Is_Input_HeaderFileGroupDCS, temp_Run)
'Open the folder location and store all the files objetcs into files()
Dim files() As String = IO.Directory.GetFiles(Path)
'Open the Header scope .txt file
Dim HeaderScopeFile As New System.IO.StreamReader(HeaderScopeFileName)
'Initialize the variable ValidFilesArray
temp_Valid = 1
Do While ValidFilesFile.Peek() <> -1
TextLine = ValidFilesFile.ReadLine()
TextLineSplit = TextLine.Split(", ")
ReDim Preserve ValidFilesArray(3, temp_Valid)
ValidFilesArray(Is_RPT_Name, temp_Valid) = TextLineSplit(Is_RPT_Name - 1)
ValidFilesArray(Is_RPT_Type, temp_Valid) = TextLineSplit(Is_RPT_Type - 1)
ValidFilesArray(Is_RPT_Valid, temp_Valid) = TextLineSplit(Is_RPT_Valid - 1)
temp_Valid = temp_Valid + 1
Loop
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'' Display the Progress Group Box ''''''''''''''''''''''''''''''''''''''''''''''''
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
L_ProgressPC.Text = "Initialisation"
ProgressBar.Value = 0
GB_Progress.Visible = True
'Me.Height = UserFormHeight_Start + UserFormHeight_ProgressBarExtension
'Me.Width = UserFormWidth_Start + UserFormWidth_ProgressBarExtension
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'' Nb of Files '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' The goal of this piece of code aims at calculating the number of .rpt files
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
TB_Runlog.Text = "Checking number of .rpt files..." & Environment.NewLine & TB_Runlog.Text
For Each file As String In files
If CheckValidRPTFile(file, False) = True Then
File_Count = File_Count + 1
L_NbOfFiles.Text = File_Count
L_NbOfRuns.Text = temp_Run & "/" & Nb_Of_Runs
End If
Application.DoEvents()
Next
TB_Runlog.Text = "... " & " Run number " & temp_Run & Environment.NewLine & TB_Runlog.Text
TB_Runlog.Text = "... " & File_Count & " rpt files founds" & Environment.NewLine & TB_Runlog.Text
TB_Runlog.Text = "---------------------------------------" & Environment.NewLine & TB_Runlog.Text
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' The key is to define the header with the field names and the field types
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Dim HeaderNbOfField As Integer = 0
Do While HeaderScopeFile.Peek() <> -1
HeaderNbOfField = HeaderNbOfField + 1
'We split the libe into an array using the comma delimiter
TextLine = HeaderScopeFile.ReadLine()
TextLineSplit = TextLine.Split(", ")
ReDim Preserve HeaderScope(2, HeaderNbOfField)
HeaderScope(Is_Name, HeaderNbOfField) = TextLineSplit(0)
HeaderScope(Is_Type, HeaderNbOfField) = TextLineSplit(1)
Loop
'That array stores the position of a given field in the file
'It is important to initialise the array to -1
'When further down we assign HeaderMapId, if a value remains "-1" il will mean the field was not assigned thus not found.
'We will then assign a default value for those not found fields
ReDim HeaderMapId(1, HeaderNbOfField)
For temp_headermapini = 0 To HeaderNbOfField
HeaderMapId(Is_RetailDCS, temp_headermapini) = Is_Not_found
HeaderMapId(Is_GroupDCS, temp_headermapini) = Is_Not_found
Next
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'' Header ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' The goal of this piece of code is to populate the variable HeaderMapId
' HeaderMapId stores the position of each field define is HeaderScope variable
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
L_ProgressPC.Text = "Find position of each field in the flat file"
'We use HeaderFile as the base to define the position of each field
'The application will function properly only if every .rpt file in the folder have same header as HeaderFile
For temp_header = 0 To 1
'We loop through 2 different type of MPFs
'Typicaly coming from Retail DCS and Group DCS
If temp_header = Is_RetailDCS Then
temp_headerfile = HeaderFile1
ElseIf temp_header = Is_GroupDCS Then
temp_headerfile = HeaderFile2
Else
temp_headerfile = "" 'Error
End If
Dim objReaderHeader As New System.IO.StreamReader(temp_headerfile)
'We read line by line until the end of the file
Do While objReaderHeader.Peek() <> -1
TextLine = objReaderHeader.ReadLine()
'We only care about the header, which starts with the character "!" in prophet .rpt files
If Strings.Left(TextLine, 1) = "!" Then
Dim temp_scope As Integer
Dim temp_scope_id As Integer
'We split the line in an array delimited by comma
TextLineSplit = TextLine.Split(", ")
'We loop through the array
'Once a field match one of the field define in HeaderScope, we store the position of that field in HeaderMapId
temp_scope_id = 1
For Each s As String In TextLineSplit
For temp_scope = 1 To UBound(HeaderScope, 2)
If HeaderScope(Is_Name, temp_scope) = s Then
HeaderMapId(temp_header, temp_scope) = temp_scope_id
End If
Next
temp_scope_id = temp_scope_id + 1
Next
End If
Loop
Next
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'' Header''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Create the query for SQL table creation
Dim temp_field As Integer
For temp_field = 1 To HeaderNbOfField
If temp_field = 1 Then
HeaderStringSQL = "(Prophet_Name varchar(255),"
HeaderStringCSV = "Prophet_Name,"
End If
'We replace the bracket by underscore to avoid crashes when creating the SQL table
HeaderStringSQL = HeaderStringSQL & Replace(Replace(HeaderScope(Is_Name, temp_field), "(", "_"), ")", "_") & " " & HeaderScope(Is_Type, temp_field)
HeaderStringCSV = HeaderStringCSV & Replace(Replace(HeaderScope(Is_Name, temp_field), "(", "_"), ")", "_")
If temp_field <> HeaderNbOfField Then
HeaderStringSQL = HeaderStringSQL & ","
HeaderStringCSV = HeaderStringCSV & ","
Else
HeaderStringSQL = HeaderStringSQL & ")"
HeaderStringCSV = HeaderStringCSV & ","
End If
Next
If Enable_CSV_Output = "Yes" Then
'Remove braquets and single quotes
outFile.WriteLine(Replace(Replace(Replace(HeaderStringCSV, ")", ""), "(", ""), "'", ""))
End If
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'' Body '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' We loop through all the files and pick the information we need based on HeaderMapId
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'We loop through each file in the folder location
For Each file As String In files
Dim objReader As New System.IO.StreamReader(file)
Dim fileInfo As New IO.FileInfo(file)
'We only loop through the valid .rpt files
If CheckValidRPTFile(file, True) = True Then
'Count the number of files we go through
temp_count = temp_count + 1
'Count the number of lines in the file (called FileSize)
'Dim objReaderLineCOunt As New System.IO.StreamReader(file)
'FileSize = 0
'Do While objReaderLineCOunt.Peek() <> -1
'TextLine = objReaderLineCOunt.ReadLine()
'FileSize = FileSize + 1
'Loop
FileSize = 1000000
'temp_line = 1
''We loop through line by line for a given file
'Do While objReader.Peek() <> -1
Dim TextLines() As String = System.IO.File.ReadAllLines(file)
For Each TextLine2 In TextLines
'Update the Progress Bar
temp_full_count = temp_full_count + 1
If temp_full_count Mod 200 = 0 Then
ProgressBar.Value = Int(100 * temp_count / File_Count)
L_ProgressPC.Text = "Processing file " & fileInfo.Name & " " & temp_count & "/" & File_Count & " - line " & temp_line & "/" & FileSize
L_RecordsProcessed.Text = temp_full_count
Application.DoEvents()
End If
'We split the libe into an array using the comma delimiter
'TextLine = objReader.ReadLine()
TextLineSplit = TextLine2.Split(", ")
'Skip line that are not actual prophet records (skip header and first few lines)
If Strings.Left(TextLine2, 1) = "*" Then
'We loop through the number of field we wish to extract for the file
For temp_field = 1 To HeaderNbOfField
If temp_field = 1 Then
BodyString = "('" & Strings.Left(fileInfo.Name, Len(fileInfo.Name) - 4) & "',"
End If
If MPF_Type = "RetailDCS" Then
Is_MPF_Type = Is_RetailDCS
ElseIf MPF_Type = "GroupDCS" Then
Is_MPF_Type = Is_GroupDCS
Else
MsgBox("Is_MPF_Type value is nor recognized")
End
End If
'The array HeaderMapId tells us where to pick the information from the file
'This assumes that each file in the folder have same header as the 'HeaderFile'
If HeaderMapId(Is_MPF_Type, temp_field) = Is_Not_found Then
BodyString = BodyString & "98766789"
Else
BodyString = BodyString & TextLineSplit(HeaderMapId(Is_MPF_Type, temp_field) - 1)
End If
If temp_field <> HeaderNbOfField Then
BodyString = BodyString & ","
Else
BodyString = BodyString & ")"
End If
Next
'We replace double quotes with single quotes
BodyString = Replace(BodyString, """", "'")
'This Line is to add records to the .csv file
If Enable_CSV_Output = "Yes" Then
'Remove braquets and single quotes
outFile.WriteLine(Replace(Replace(Replace(BodyString, ")", ""), "(", ""), "'", ""))
End If
End If
temp_line = temp_line + 1
Next
TB_Runlog.Text = "Completed: " & fileInfo.Name & Environment.NewLine & TB_Runlog.Text
temp_file = temp_file + 1
End If
Next
outFile.Close()
ProgressBar.Value = Int(100 * temp_count / File_Count)
L_RecordsProcessed.Text = temp_full_count
Application.DoEvents()
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'' Upload to SQL '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' The goal of this code is to create the SQL table
' And push the .csv created into the SQL table using BULK INSERT function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
L_ProgressPC.Text = "Creating SQL Table"
Application.DoEvents()
If Enable_SQL_Upload = "Yes" Then
'First query is to create the table
SqlCommandText1 = "CREATE TABLE [" & SQLDataBase & "].[analysis]." & SQLTableName & "_" & ts & " " & HeaderStringSQL
'Second query is to populate the data
SqlCommandText2 = "BULK INSERT [" & SQLDataBase & "].[analysis]." & SQLTableName & "_" & ts & " " & " FROM '" & SQLUploadFileName & "' WITH ( FIELDTERMINATOR = ',', ROWTERMINATOR = '\n' , FIRSTROW=2)"
SQLQueriesFile.WriteLine(SqlCommandText1)
SQLQueriesFile.WriteLine(SqlCommandText2)
SQLQueriesFile.Close()
Using connection As New SqlConnection("Data Source=" & SQLServer & ";Integrated Security=True;Connection Timeout=2000;Initial Catalog=" & SQLDataBase & ";")
connection.Open()
Dim command As New SqlCommand(SqlCommandText1, connection)
command.ExecuteNonQuery()
Dim command2 = New SqlCommand(SqlCommandText2, connection)
command2.CommandTimeout = 2000
command2.ExecuteNonQuery()
connection.Close()
End Using
End If
Timer_Array(temp_Run) = L_Timer.Text
Next 'temp_Run
RunLogFile.Close()
Timer1.Stop()
L_ProgressPC.Text = "Job completed"
One way to speed up your program is to mininize the number of access to disk. Right now, you are reading each file twice, line-by-line. Each file most likely fits in memory. So, what you can do, is read all lines of a file in memory, and then process its lines. This will be much faster.
Something like:
'We only loop through the valid .rpt files
If CheckValidRPTFile(file, True) = True Then
''Count the number of files we go through
'temp_count = temp_count + 1
''Count the number of lines in the file (called FileSize)
'Dim objReaderLineCOunt As New System.IO.StreamReader(file)
'FileSize = 0
'Do While objReaderLineCOunt.Peek() <> -1
' TextLine = objReaderLineCOunt.ReadLine()
' FileSize = FileSize + 1
'Loop
'temp_line = 1
''We loop through line by line for a given file
'Do While objReader.Peek() <> -1
Dim TextLines() As String = System.IO.File.ReadAllLines(file)
For Each TextLine In TextLines
'We split into an array using the comma delimiter
'TextLine = objReader.ReadLine()
TextLineSplit = TextLine.Split(", ")
I looked at your updated code. You have a few additional performance issues in your code.
Reading and writing to network shared folder files is not very efficient especially when there is a lot of back and forth access to the file because everything goes through the network rather than direct local drive access.
Probably the most inefficient part of your program is iterating through your 200 fields for each line of the files. Let's say we have 5000 lines per file on average, then this means 200 x 5000 x 284 = 284 millions iterations!
The efficient method for accessing network shared files is to read an entire file in memory using System.IO.ReadAllLines() or System.IO.File.ReadAllText(), and then process its contents. Similarly, writing to a network shared file should consist of building the file contents in memory (if possible) using StringBuilder or a List(Of String), and then write the entire file to the network share with System.IO.File.WriteAllText() of System.IO.File.WriteAllLines. This should be the preferred way of accessing network shared files for best performance.
For the second performance issue, the loop through fields can be simplified as follows.
Dim BodyStringBuilder As New StringBuilder("")
BodyStringBuilder.Append("('" & Strings.Left(fileInfo.Name, Len(fileInfo.Name) - 4) & "',")
If MPF_Type = "RetailDCS" Then
Is_MPF_Type = Is_RetailDCS
ElseIf MPF_Type = "GroupDCS" Then
Is_MPF_Type = Is_GroupDCS
Else
MsgBox("Is_MPF_Type value is nor recognized")
End
End If
'Skip line that are not actual prophet records (skip header and first few lines)
If Strings.Left(TextLine2, 1) = "*" Then
'We loop through the number of field we wish to extract for the file
For temp_field = 1 To HeaderNbOfField
'The array HeaderMapId tells us where to pick the information from the file
'This assumes that each file in the folder have same header as the 'HeaderFile'
If HeaderMapId(Is_MPF_Type, temp_field) = Is_Not_found Then
BodyStringBuilder.Append("98766789,")
Else
BodyStringBuilder.Append(TextLineSplit(HeaderMapId(Is_MPF_Type, temp_field) - 1) & ",")
End If
Next
' Replace last "," by ")".
BodyStringBuilder.Remove(BodyStringBuilder.Length - 1, 1).Append(")")
'We replace double quotes with single quotes
BodyString = Replace(BodyString.ToString, """", "'")

Value Of Type Form1.Data cannot be converted to Form1.Data() when passing parameters

At the start of the program I define a new Public Structure 'Data':
Public Structure Data
Dim car, grid, points As String
Dim driver, team, fastestlap, racetime As String
End Structure
I then have the user input data and it is added to array displayData(5) of data type 'Data'.
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim displayData(5) As Data
Dim accepted As Boolean = False
Dim temp As String
Dim tempNum As Integer
Dim output As String = ""
Dim arraysize As Integer = 0
For x = 0 To 5
displayData(x).driver = InputBox("Please enter the name of driver number " & x + 1)
temp = InputBox("Please enter the car number of driver number " & x + 1)
While accepted = False
If IsNumeric(temp) Then
accepted = True
displayData(x).car = temp
Else
accepted = False
temp = InputBox("Error: integer not entered. Please enter the car number of driver number " & x + 1)
End If
End While
accepted = False
displayData(x).team = InputBox("Please enter the team name of driver number " & x + 1)
temp = InputBox("Please enter the grid number of driver number " & x + 1)
tempNum = Convert.ToInt32(temp)
While accepted = False
If IsNumeric(tempNum) Then
accepted = True
displayData(x).grid = temp
Else
accepted = False
temp = InputBox("Error: integer not entered. Please enter the grid number of driver number " & x + 1)
tempNum = Convert.ToInt32(temp)
End If
End While
accepted = False
displayData(x).fastestlap = InputBox("Please enter the fastest lap of driver number " & x + 1)
displayData(x).racetime = InputBox("Please enter the race time of driver number " & x + 1)
temp = InputBox("Please enter the points of driver number " & x + 1)
While accepted = False
If IsNumeric(temp) Then
accepted = True
displayData(x).points = temp
Else
accepted = False
temp = InputBox("Error: integer not entered. Please enter the points of driver number " & x + 1)
End If
End While
accepted = False
output = output & displayData(x).driver & "," & displayData(x).car & "," & displayData(x).team & "," & displayData(x).grid & "," & displayData(x).fastestlap & "," & displayData(x).racetime & "," & displayData(x).points & vbCrLf
Next
Dim filename As String = "U:\Subjects\Computing\AH Computing\Project Files\Leaderboard.csv"
My.Computer.FileSystem.WriteAllText(filename, output, True)
bubbleSort(arraysize, displayData(6))
End Sub
Above is the main bulk of my code. I am getting an error from typing in displayData(6) into bubblesort, which is defined here:
Public Sub bubbleSort(ByVal arraysize As Integer, ByVal displayData() As Data)
Dim counter As Integer
Dim outerloop As Integer
For outerloop = (arraysize - 2) To 0 Step -1
For counter = 0 To outerloop
If displayData(counter).racetime > displayData(counter + 1).racetime Then
swap(displayData(counter).racetime, displayData(counter + 1).racetime)
swap(displayData(counter).car, displayData(counter + 1).car)
swap(displayData(counter).driver, displayData(counter + 1).driver)
swap(displayData(counter).points, displayData(counter + 1).points)
swap(displayData(counter).team, displayData(counter + 1).team)
swap(displayData(counter).fastestlap, displayData(counter + 1).fastestlap)
swap(displayData(counter).grid, displayData(counter + 1).grid)
End If
Next
Next
End Sub
And apparently I need more normal text in order to save this. The bubble sort uses a swap algorithm that I defined in another part of the program, but it is incredibly simple and is 100% not the cause of the error so it seems unproductive to include it.

System.IndexOutOfRangeException VB GradeBook

So I get this error when trying to run my code "System.IndexOutOfRangeException: 'Index was outside the bounds of the array.'" I am not exactly sure what the issue is. The user should be able to enter 3 assignment grades and then see the averages
I marked the line where I get the error with 'THIS IS THE ERROR'
Public Class GradeBook
Dim grade(9, 2) As Integer 'Store 10 student grades on 3 tests'
Dim studentCount As Integer = 0 'Number of students entered'
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
GradeListBox.Items.Add(vbTab & vbTab & "Test 1" & vbTab & "Test 2" & vbTab & "Test 3" & vbTab & "Average")
End Sub
Private Sub SubmitButton_Click(sender As Object, e As EventArgs) Handles SubmitButton.Click
grade(studentCount, 0) = Convert.ToInt32(Assignment1TextBox.Text)
grade(studentCount, 1) = Convert.ToInt32(Assignment2TextBox.Text)
grade(studentCount, 2) = Convert.ToInt32(Assignment3TextBox.Text)
Dim output As String = "Student " & studentCount & vbTab
For column = 0 To grade.GetUpperBound(1)
If LetterRadioButton.Checked = True Then
output &= vbTab & LetterGrade(grade(studentCount, column))
Else
output &= vbTab & grade(studentCount, column)
End If
Next
output &= vbTab & CalculateStudentAverage(studentCount)
GradeListBox.Items.Add(output)
studentCount += 1
AverageLabel.Text = CalculateClassAverage()
displayBarChart()
End Sub
Function LetterGrade(ByVal grade As Double) As String
Dim output As String = ""
Select Case grade
Case Is >= 90
output = "A"
Case Is >= 80
output = "B"
Case Is >= 70
output = "C"
Case Is >= 60
output = "D"
Case Is >= 50
output = "E"
End Select
Return output
End Function
Function CalculateStudentAverage(ByVal row As Integer) As String
Dim gradeTotal As Integer = 0
For column = 0 To grade.GetUpperBound(1)
gradeTotal += grade(row, column) 'THIS IS THE ERROR'
Next
Dim studentAverage As String = String.Empty
If LetterRadioButton.Checked = True Then
studentAverage = LetterGrade(gradeTotal / (grade.GetUpperBound(1) + 1))
Else
studentAverage = String.Format("{0:F}", (gradeTotal / grade.GetUpperBound(1) + 1))
End If
Return studentAverage
End Function
Function CalculateClassAverage() As String
Dim classTotal As Integer = 0
For row = 0 To studentCount - 1
For column = 0 To grade.GetUpperBound(1)
classTotal += grade(row, column)
Next
Next
Dim classAverage As String = String.Empty
If LetterRadioButton.Checked = True Then
classAverage = LetterGrade(classTotal / (studentCount * (grade.GetUpperBound(1) + 1)))
Else
classAverage = String.Format("{0:F}", (classTotal / (studentCount * (grade.GetUpperBound(1) + 1))))
End If
Return classAverage
End Function
Sub displayBarChart()
GradeListBox.Items.Clear()
GradeListBox.Items.Add(vbTab & vbTab & "Test 1" & vbTab & "Test 2" & vbTab & "Test 3" & vbTab & "Average")
For row = 0 To studentCount - 1
Dim output As String = "Student " & row & vbTab
For column = 0 To grade.GetUpperBound(1)
If LetterRadioButton.Checked = True Then
output &= vbTab & LetterGrade(grade(row, column))
Else
output &= vbTab & (grade(row, column))
End If
Next
output &= vbTab & CalculateStudentAverage(studentCount)
GradeListBox.Items.Add(output)
studentCount += 1
AverageLabel.Text = CalculateClassAverage()
displayBarChart()
Assignment1TextBox.Clear()
Assignment2TextBox.Clear()
Assignment3TextBox.Clear()
If studentCount = grade.GetUpperBound(0) + 1 Then
InputGradeGroupBox.Enabled = False
End If
Next
End Sub
End Class
To be honest, I suspect you're going about it in a way not suited to OOP. Using arrays for multiple peices of data is prone to error and harder to maintain later.
Lets have a think about how you want to represent your data. You have a bunch of students. In a more complete example each student would have a name, personal details such as address, a list of the courses they're taking and for each course, a list of assignments and scores for each assignment which can also be represented as a grade.
So in essence you have a class called Student and the various bits of information are properties of that student.
Finally you have a list of these students
In your code, you simply have a student number and three assignment scores.
Your basic student class should have the properties of Number, Test1Score, Test2Score and Test3Score. You would also want to be able to get the grade from each score, the average of all the scores and the average of all the grades.
The code below defines the Student class with that information in mind
Friend Class Student
Public Property Number As Integer
Public Property Test1Score As Integer
Public Property Test2Score As Integer
Public Property Test3Score As Integer
Public Function Test1Grade() As String
Return LetterGrade(Test1Score)
End Function
Public Function Test2Grade() As String
Return LetterGrade(Test2Score)
End Function
Public Function Test3Grade() As String
Return LetterGrade(Test3Score)
End Function
Friend Shared Function LetterGrade(ByVal grade As Double) As String
Dim output As String = ""
Select Case grade
Case Is >= 90
output = "A"
Case Is >= 80
output = "B"
Case Is >= 70
output = "C"
Case Is >= 60
output = "D"
Case Is >= 50
output = "E"
Case Else
output = "F"
End Select
Return output
End Function
Friend Function AverageScore() As Double
Return (Test1Score + Test2Score + Test3Score) / 3
End Function
Friend Function AverageGrade() As String
Dim avgscore As Double = AverageScore()
Return LetterGrade(avgscore)
End Function
End Class
The function LetterGrade is Shared so that it can be used in your main form to calculate the average grade for the entire class.
OK Next think about how you want your program to work. You'll need a list of students, so at the beginning of your form class , you'll need this..
Public Class Form1
Private Students As New List(Of Student)
This way, instead of trying to keep track of your variable studentCount you can just use the .Count property of the List e.g Students.Count. You wont need to any adding to it as the Students list keeps track of it automatically.
Next, you'll want the function that calculates the average score/grade of the class..
Function CalculateClassAverage() As String
Dim classTotal As Integer = 0
For Each tmpStudent As Student In Students
With tmpStudent
classTotal += .Test1Score + .Test2Score + .Test3Score
End With
Next
Dim classAverage As String = String.Empty
If LetterRadioButton.Checked = True Then
classAverage = Student.LetterGrade((classTotal / Students.Count) / 3)
Else
classAverage = String.Format("{0:F}", (classTotal / (Students.Count)) / 3)
End If
Return classAverage
End Function
As you can see, there are a number of differences here because of the way your data is stored, but you should be able to follow it. One difference is the With statement, this allows you to save on typing. inside the With.. End With block, instead of typing tmpstudent.Test1Score etc, you can just type .Test1Score
The other thing of note is this line ..
classAverage = Student.LetterGrade( ... etc
You may think that there has been no declaration of a variable called Student. There IS a class, but not a variable. What this is actually doing is calling the LetterGrade function that is shared in the Student class definition.. Have a look at shared functions.
Next is the code to display the information in the ListBox. I haven't changed the name even though it is misleading btw.
Sub displayBarChart()
GradeListBox.Items.Clear()
GradeListBox.Items.Add(vbTab & vbTab & "Test 1" & vbTab & "Test 2" & vbTab & "Test 3" & vbTab & "Average")
For Each tmpstudent As Student In Students
Dim output As String = "Student " & tmpstudent.Number & vbTab
With tmpstudent
If LetterRadioButton.Checked = True Then
output &= .Test1Grade & vbTab & .Test2Grade & vbTab & .Test3Grade & vbTab & .AverageGrade
Else
output &= .Test1Score & vbTab & .Test2Score & vbTab & .Test3Score & vbTab & .AverageScore
End If
End With
GradeListBox.Items.Add(output)
AverageLabel.Text = CalculateClassAverage()
Next
If Students.Count = 10 Then
InputGradeGroupBox.Enabled = False
End If
End Sub
More use of the With..End With statements again, but the rest should be straighforward to follow.
A little extra bit of code.. When you click on the LetterRadioButton, the data in the listBox and ClassAveragelabel are refreshed with the appropriate letters/grades
Private Sub LetterRadioButton_CheckedChanged(sender As Object, e As EventArgs) Handles LetterRadioButton.CheckedChanged
AverageLabel.Text = CalculateClassAverage()
displayBarChart()
End Sub
Finally, to bring it all together, you have the code for the button click..
Private Sub SubmitButton_Click(sender As Object, e As EventArgs) Handles SubmitButton.Click
Dim tmpStudent As New Student With {.Number = Students.Count + 1,
.Test1Score = Convert.ToDouble(Assignment1TextBox.Text),
.Test2Score = Convert.ToDouble(Assignment2TextBox.Text),
.Test3Score = Convert.ToDouble(Assignment3TextBox.Text)}
Dim output As String = "Student " & tmpStudent.Number & vbTab
With tmpStudent
If LetterRadioButton.Checked = True Then
output &= vbTab & .Test1Grade & vbTab & .Test2Grade & vbTab & .Test3Grade
Else
output &= vbTab & .Test1Score & vbTab & .Test2Score & vbTab & .Test3Score
End If
End With
Students.Add(tmpStudent)
If LetterRadioButton.Checked Then
output &= vbTab & tmpStudent.AverageGrade
Else
output &= vbTab & tmpStudent.AverageScore
End If
GradeListBox.Items.Add(output)
AverageLabel.Text = CalculateClassAverage()
displayBarChart()
Assignment1TextBox.Clear()
Assignment2TextBox.Clear()
Assignment3TextBox.Clear()
End Sub
Hopefully in addition to my comment to your question, this provides a slightly better insight of OOP.

How to update a Progressbar / Label created per code in a for each loop?

First my code :
Sub festplatte()
Dim allDrives() As DriveInfo = DriveInfo.GetDrives()
Dim d As DriveInfo
Dim I As Integer
For Each d In allDrives
If d.IsReady = True Then
Try
' Intelize controls
Dim progressbar As ProgressBar = New ProgressBar
Dim pbgroup As GroupBox = New GroupBox
Dim info As Label = New Label
Dim type As Label = New Label
Dim format As Label = New Label
Dim Space As Double = d.TotalFreeSpace / d.TotalSize
' Add to tab
Me.Tab_M.Controls.Add(progressbar)
Me.Tab_M.Controls.Add(pbgroup)
Me.Tab_M.Controls.Add(info)
Me.Tab_M.Controls.Add(type)
Me.Tab_M.Controls.Add(format)
' Add to group
pbgroup.Controls.Add(progressbar)
pbgroup.Controls.Add(info)
pbgroup.Controls.Add(type)
pbgroup.Controls.Add(format)
pbgroup.Text = d.Name & " | Name : " & CheckName(d.VolumeLabel.ToString())
pbgroup.Size = New System.Drawing.Size(600, 65)
pbgroup.Location = New System.Drawing.Point(8, I * 70 + 40)
' format
format.AutoSize = True
format.Name = "format" & I
format.Location = New System.Drawing.Point(435, 36)
format.Text = "Format : " & d.DriveFormat
' Typ
type.AutoSize = True
type.Name = "type" & I
type.Location = New System.Drawing.Point(435, 16)
type.Text = "Art : " & GetDriverFormat(d)
' info
info.Name = "info" & I
info.Location = New System.Drawing.Point(6, 16)
info.AutoSize = True
' Info Text :: 1000 MB Grenze
If d.TotalFreeSpace > Math.Pow(1024, 3) Then
info.Text = "Benutzter Speicher beträgt : " & Math.Round((d.TotalSize - d.TotalFreeSpace) / btogb, 2) & " GB von " & Math.Round((d.TotalSize) / btogb, 2) & " GB (" & Math.Round(100 - Space * 100, 2) & " % )"
Else
info.Text = "Benutzter Speicher beträgt : " & Math.Round((d.TotalSize - d.TotalFreeSpace) / btomb, 2) & " MB von " & Math.Round((d.TotalSize) / btomb, 2) & " MB (" & Math.Round(100 - Space * 100, 2) & " % )"
End If
'Progressbar
progressbar.Size = New System.Drawing.Size(425, 23)
progressbar.Location = New System.Drawing.Point(6, 32)
progressbar.Name = "Memory" & I
progressbar.Value = 100 - Space * 100
Catch ex As Exception
MsgBox(ex.ToString())
End Try
I += 1
End If
Next
End Sub
The code does generate a groupbox with each a progressbar in it and 3 labels, where i would like to edit something.
How can I edit the text of for example a label ? And how could I add / remove generated elements from the form ? I tried with refresh but it doesnt work
The Form
This was something quick I tried:
Dim LabelList As New List(Of Integer)
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim LBL As New Label
LBL.Location = New Point(6, 23)
LBL.AutoSize = True
Me.Controls.Add(LBL)
LabelList.Add(Me.Controls.Count - 1)
End Sub
Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
Me.Controls(LabelList(0)).Text = "HELLO WORLD!"
End Sub
This will add a label to the form and then add it's control index to LabelList. LabelList(0) will get the index for the first added label.

extracting text from comma separated values in visual basic

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.