2017-03-16 16 views
2

我與我的代碼收到以下錯誤:從字符串轉換爲鍵入計算分鐘時雙擊無效和最大值

轉換爲double類型無效

的程序正常運行之前正確的輸出,但我做了一些無效的更改,不得不恢復這些,但它沒有奏效。

該程序可以在文本文件的列中找到minmax值。

如果可能,請提供一種計算minmax值的方法,用空格(不一致的空格)分隔的文本文件中的多個列的值與以下代碼具有相似的方法。

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 


    Dim RECfile As New System.IO.StreamReader(Textfile) 
    Dim textline As String 

    Dim ln = 0 
    Dim Max As Integer 
    Max = 0 
    Dim Min As Integer 
    Min = 999999 

    Do While RECfile.Peek() <> -1 
     textline = RECfile.ReadLine() 

     If textline > Max Then 
      Max = textline 
     End If 

     If textline < Min Then 
      Min = textline 
     End If 

     ln += 1 

     Me.maxval.Text = Max 
     Me.Minval.Text = Min 

    Loop 

    RECfile.Close() 

End If 

樣品數據1:

 
194787.5 194987.5   194787.5 194987.5 
194987.5 195012.5   194987.5 195012.5 
195012.5 2003999   195012.5 2003999 
2003999  195037.5   2003999 195037.5 
195037.5 195062.5   195037.5 195062.5 
195062.5 195087.5   195062.5 195087.5 
195087.5 195112.5   195087.5 195112.5 
195112.5 195137.5   195112.5 495137.5 
195137.5 195162.5   195137.5 195162.5 
195162.5 194812.5   195162.5 19400012.5 
     194837.5   194837.5 
     194862.5   194862.5 
     194887.5   194887.5 
     194912.5   194912.5 
     194937.5   194937.5 
     12111    12111999  

樣品之日起2:

 
194987.5 195012.5   194987.5 195012.5 
195012.5 2003999   195012.5 2003999 
2003999  195037.5   2003999 195037.5 
195037.5 195062.5   195037.5 195062.5 
195062.5 195087.5   195062.5 195087.5 
195087.5 195112.5   195087.5 195112.5 
195112.5 195137.5   195112.5 495137.5 
195137.5 195162.5   195137.5 195162.5 
195162.5 194812.5   195162.5 19400012.5 
     194837.5   194837.5 
     194862.5   194862.5 
     194887.5   194887.5 
     194912.5   194912.5 
     194937.5   194937.5 

編輯:

這些是我收到,我相信是與警告的屏幕截圖與代碼。

截圖1: enter image description here

截圖2:

designer form

+0

你想檢查只有十列的行嗎?行「12111 12111999」似乎具有與其他值無關的值。由於您需要每個*欄的極值*,因此在查找最小值和最大值之前,必須先讀取所有數據。或者你真的是指每個*行*中的最小值和最大值? –

回答

2

根據您的樣本數據,Integer不會削減它。我建議你改爲使用Double而不是194787.5不會解析爲Integer

首先把Option Strict On

隱含範圍限制數據類型轉換爲只能進行擴大轉換,不允許後期綁定,並禁止導致Object類型隱式類型。

接下來,我建議你創建一個新的臨時變量和使用Double.TryParse

一些它的雙精度浮點數等價的字符串表示形式。返回值指示轉換是成功還是失敗。

您的代碼看起來類似於這樣一個建議:

Dim temp As Double = 0 

If Double.TryParse(textline, temp) Then 

    If temp > Max Then 
     Max = temp 
    End If 

    If temp < Min Then 
     Min = temp 
    End If 

End If 

Me.maxval.Text = Max.ToString() 
Me.Minval.Text = Min.ToString() 

注意.ToString()MaxMin。這是因爲它們是Doubles,需要轉換爲String

我想提出的另一個建議是實施Using來幫助處理物體。

相反的:

Dim RECfile As New System.IO.StreamReader(Textfile) 

你必須:

Using RECfile As New System.IO.StreamReader(Textfile) 

    ... 

End Using 

你不會需要調用RECfile.Close()無論是作爲Using塊將處理這個問題。

我也看不到任何使用變量ln所以刪除它。

最後,您聲明文本文件包含多個使用不一致空格分隔的列。我實際上相信它們是製表符分隔的值。話雖這麼說Andrew Morton提出了很好的建議:

萬一在{CCHAR(vbTab)「,「C} ..split沒有值之間的標籤(例如文件手工編輯) 。

我建議我們使用String.Split方法:

Dim textline As String() = RECfile.ReadLine().Split(New Char() {CChar(vbTab), " "c}, StringSplitOptions.RemoveEmptyEntries) 

總體代碼將類似於這樣:

Using RECfile As New System.IO.StreamReader(Textfile) 

    Dim Max As Double = Double.MinValue 
    Dim Min As Double = Double.MaxValue 

    Do While RECfile.Peek() <> -1 
     Dim textline As String() = RECfile.ReadLine().Split(New Char() {CChar(vbTab), " "c}, StringSplitOptions.RemoveEmptyEntries) 

     For Each line In textline 
      Dim temp As Double = 0 

      If Double.TryParse(line.Trim(), temp) Then 

       If temp > Max Then 
        Max = temp 
       End If 

       If temp < Min Then 
        Min = temp 
       End If 

      End If 

      Me.maxval.Text = Max.ToString() 
      Me.Minval.Text = Min.ToString() 

     Next 
    Loop 

End Using 

對我來說,輸出是:

Max = 19400012.5 
Min = 12111 

根據OP的要求進行編輯,以獲取文本文件中每列的最小值和最大值。

我已經盡我所能去嘗試和分析示例數據,並且我可以告訴這些值是製表符分隔的。如果列中有一個缺失值,那麼兩個選項卡將會彼此相鄰。如果在兩個相鄰列中有一個缺失值,那麼四個選項卡將會彼此相鄰。爲了解決這個問題,我用一個選項卡替換了所有出現的兩個選項卡。這使索引保持穩定。

首先我創建了兩個類:

ColumnValue

Public Class ColumnValue 
    Public Key As String 

    Public Sub New(ByVal id As Integer, 
        ByVal value As Double) 

     _id = id 
     _value = value 

    End Sub 

    Private _id As Integer 
    Public ReadOnly Property ID As Integer 
     Get 
      Return _id 
     End Get 
    End Property 

    Private _value As Double 
    Public ReadOnly Property Value As Double 
     Get 
      Return _value 
     End Get 
    End Property 

End Class 

ColumnValues

Imports System.Collections.ObjectModel 
Public Class ColumnValues 
    Inherits KeyedCollection(Of String, ColumnValue) 

    Protected Overrides Function GetKeyForItem(ByVal item As ColumnValue) As String 
     Return item.Key 
    End Function 

    Public Function GetMax(ByVal columnId As Integer) As Double 

     Return (From c In Me 
       Where c.ID = columnId 
       Select c.Value).Max() 

    End Function 

    Public Function GetMin(ByVal columnId As Integer) As Double 

     Return (From c In Me 
       Where c.ID = columnId 
       Select c.Value).Min() 

    End Function 

End Class 

注意,在ColumnValues類我有兩個函數返回MinMax基於columnId通過使用LINQ

這是修改後的代碼我已經到位:

Dim myColumnValues As New ColumnValues 

Using RECfile As New System.IO.StreamReader(Textfile) 

    Do While RECfile.Peek() <> -1 
     Dim textline As String() = RECfile.ReadLine().Replace(CChar(vbTab) & CChar(vbTab), vbTab).Split(New Char() {CChar(vbTab)}) 

     Dim columnId As Integer = 0 

     For Each column In textline 

      columnId += 1 

      Dim temp As Double = 0 

      If Double.TryParse(column.Trim(), temp) Then 
       myColumnValues.Add(New ColumnValue(columnId, temp)) 
      End If 

     Next 
    Loop 

    'Get a distinct list of column Ids to loop through 
    Dim columnIds = (From c In myColumnValues 
        Order By c.ID 
        Select c.ID).Distinct() 

    'Output the Max and Min for each column 
    For Each c In columnIds 

     Debug.WriteLine("Column: " & c.ToString() & " Max: " & myColumnValues.GetMax(c)) 
     Debug.WriteLine("Column: " & c.ToString() & " Min: " & myColumnValues.GetMin(c)) 

    Next 

End Using 

請注意,我已經恢復到分裂的vbTab,而不是兩個標籤和空格。通過在空間上分割也導致索引的許多問題,並且數據不夠好。

示例數據1的輸出是:編輯爲每OP的關於截圖錯誤編輯

Column: 1 Max: 2003999 
Column: 1 Min: 194987.5 

Column: 2 Max: 2003999 
Column: 2 Min: 194812.5 

Column: 3 Max: 2003999 
Column: 3 Min: 194987.5 

Column: 4 Max: 19400012.5 
Column: 4 Min: 194837.5 

Column: 1 Max: 2003999 
Column: 1 Min: 194787.5 

Column: 2 Max: 2003999 
Column: 2 Min: 12111 

Column: 3 Max: 2003999 
Column: 3 Min: 194787.5 

Column: 4 Max: 19400012.5 
Column: 4 Min: 194837.5 

輸出爲樣本數據2是。

我會創建單獨的Class文件ColumnValueColumnValues像這樣:

ColumnValue

enter image description here

ColumnValues

enter image description here

保留這些與Form1代碼分開。