Click here to Skip to main content
14,361,059 members
Rate this:
Please Sign up or sign in to vote.
See more:
Dear All,

I am trying to read different columns from a text file as per my need and calculating min and max for those columns. There are minimum 4 columns in a text file. Sometimes I read column 1 and column 3, sometimes I have to read column 2 and column 5 and so on. what I need is to give 2 column numbers in 2 textboxes and read those columns and return the min max values. The text file is separated by spaces which are not consistent. But there could be columns separated with both tabs and spaces. As I am not an expert in VB .net so I would prefer to have something simple and understandable. So far what I tried is copied below ... Thanks in advance !!

EXAMPLE of a text file
1821 20132 194775.0 2664662.5
1821 20372 195375.0 2664662.5
1821 20432 195525.0 2664662.5
1905 24692 206175.0 2665712.5
1905 24932 206775.0 2665712.5
1905 24992 206925.0 2665712.5
S1993 23012 201975.0 2666812.5
S1993 23072 202125.0 2666812.5
1905 25052 207075.0 2665712.5
1905 25112 207225.0 2665712.5
1905 25412 207975.0 2665712.5
1905 25472 208125.0 2665712.5
1907 20132 194775.0 2665737.5
S1907 20312 195225.0 2665737.5
S1907 20372 195375.0 2665737.5

What I have tried:

Dim Textfile As String
        Dim openDlg As New OpenFileDialog

        If openDlg.ShowDialog() = DialogResult.OK Then
            openDlg.Filter = "txt files (*.txt)| *.txt|All files (*.*)|*.*"
            openDlg.FilterIndex = 2
            openDlg.RestoreDirectory = True
            Textfile = openDlg.FileName
 Using RECfile As New System.IO.StreamReader(Textfile)

Dim maxE As Double = 0
            Dim minE As Double = 99999999
            Dim maxN As Double = 0
            Dim minN As Double = 99999999
            Do While RECfile.Peek() <> -1
 Dim textline As String() = RECfile.ReadLine().TrimStart("S"c).Replace(vbTab & vbTab, vbTab).Split(New Char() {CChar(vbTab)}) // 'comment:  removing the letter "S" which appears in the beginning of the line sometimes and changing all the double tab to single tab and even the spaces to tab to read the columns consistently.

                If CDbl(textline(CInt(Val(Me.eastval.Text)))) > maxE Then
                    maxE = CDbl(textline(CInt(Val(Me.eastval.Text))))
                    Me.MaxvalE.Text = maxE.ToString()

                End If

                If CDbl(textline(CInt(Val(Me.eastval.Text)))) < minE Then
                    minE = CDbl(textline(CInt(Val(Me.eastval.Text))))
                    Me.MinvalE.Text = minE.ToString()

                End If



                If CDbl(textline(CInt(Val(Me.northval.Text)))) > maxN Then
                    maxN = CDbl(textline(CInt(Val(Me.northval.Text))))
                    Me.MaxvalN.Text = maxN.ToString()

                End If
                If CDbl(textline(CInt(Val(Me.northval.Text)))) < minN Then
                    minN = CDbl(textline(CInt(Val(Me.northval.Text))))
                    Me.MinvalN.Text = minN.ToString()

                End If
loop 
End Using
Posted
Updated 20-Mar-17 2:01am
Comments
Richard MacCutchan 20-Mar-17 5:27am
   
Do not convert the numbers to double types. All the values are integers so you should process them as such.
VB_Learner 20-Mar-17 8:09am
   
Thanks Richard, I have understood your point and following your suggestion.!!

1 solution

Rate this:
Please Sign up or sign in to vote.

Solution 1

First some observations...
- You need to set up the Dialog box before you display it not afterwards
- As Richard said in his comment - use the correct type for your values
- It looks as if you were a Classic VB or VBA programmer before venturing into VB.NET ... there is no need to process the file line by line nor to use Peek (see below).
- There is a neater way to use the Split function (see below)
- Use the explicit Try and/or TryParse methods rather than CDbl or CInt - they are more robust (see below)
- There is no need to update the textbox text values within the loop - just do that once you have worked out the min and max values

Here is my first attempt at the problem:
Dim textfile As String
Dim openDlg As New OpenFileDialog

openDlg.Filter = "txt files (*.txt)| *.txt|All files (*.*)|*.*"
openDlg.FilterIndex = 1
openDlg.RestoreDirectory = True

If openDlg.ShowDialog() = DialogResult.OK Then
    textfile = openDlg.FileName

    Dim fileLines() As String = File.ReadAllLines(textfile)

    Dim col1 As List(Of Long) = New List(Of Long)()
    Dim col2 As List(Of Long) = New List(Of Long)()
    Dim col3 As List(Of Double) = New List(Of Double)()
    Dim col4 As List(Of Double) = New List(Of Double)()

    For Each fileLine As String In fileLines

        If fileLine.StartsWith("S") Then fileLine = fileLine.Substring(1)

        Dim items() As String = fileLine.Split(New Char() {CChar(vbTab), " "}, StringSplitOptions.RemoveEmptyEntries)

        Dim lngRet As Long
        Dim douRes As Double
        If Integer.TryParse(items(0), lngRet) Then col1.Add(lngRet)
        If Integer.TryParse(items(1), lngRet) Then col2.Add(lngRet)
        If Double.TryParse(items(2), douRes) Then col3.Add(douRes)
        If Double.TryParse(items(3), douRes) Then col4.Add(douRes)
    Next

    'We now have 4 lists of numbers which we can Sort!
    col1.Sort()
    col2.Sort()
    col3.Sort()
    col4.Sort()

    'The max and min values are in the last and first item respectively
    'Remember that the list uses zero-based indexing!
    MaxvalE.Text = col1.Item(col1.Count - 1).ToString()
    MinvalE.Text = col1.Item(0).ToString()
    MaxvalN.Text = col2.Item(col2.Count - 1).ToString()
    MinvalN.Text = col2.Item(0).ToString()

End If
I say "first attempt" because I would probably carry on to see if I could create a DataTable from the file, or at least introduce a class for the rows in the table so I could encapsulate all of the behaviours (int or double, starts with S or not etc). But this is a working starting point for you.
   
Comments
VB_Learner 20-Mar-17 8:23am
   
Thanks a lot CHill60 .. it is indeed a very simple and fine solution at this stage. Actually it is just a beginning of the whole problem :P which I might explain later after using this solution and try for the next step!! ..

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100