2012-07-05 82 views
1

我有一個讀取CSV文件並構建數據表的函數。我不會聲稱這是我自己的真心話,事實並非如此。我不記得我在哪裏,但它是來自幾個不同來源的組合。從CSV文件構建DataTable? ASP.net VB

我的功能正常工作,直到我需要處理一些具有「,」逗號的CSV值。任何人都可以幫我解決這個問題來解決這個問題嗎?

非常感謝..

檔案範例

FirstName, LastName, Comment, "address, just city", 
    John, Smith, "you are very good, but ugly", London, 
    Britney, Spear, "I am a singer, and beautiful", New York, 

我的功能

Public Function BuildDataTable() As DataTable 

    Dim myTable As DataTable = New DataTable("MyTable") 
    Dim i As Integer 
    Dim myRow As DataRow 
    Dim fieldValues As String() 
    Dim myReader As IO.StreamReader 
    Dim csv2xml As New csv2xml 

    Try 
     'Open file and read first line to determine how many fields there are. 
     myReader = File.OpenText(_fileFullPath) 
     fieldValues = myReader.ReadLine().Split(_seperator) 
     'Create data columns accordingly 
     If _hasheader = False Then 
      For i = 0 To fieldValues.Length() - 1 
       myTable.Columns.Add(New DataColumn("Column(" & i & ")")) 
      Next 
     Else 
      'if the file has header, take the first row as header for datatable 
      For i = 0 To fieldValues.Length() - 1 
       myTable.Columns.Add(New DataColumn(fieldValues(i).Replace(" ", ""))) 
      Next 
     End If 

     'Adding the first line of data to data table 
     myRow = myTable.NewRow 

     'if the csv file has not got a column header. defined by radio button list on first page by user 
     'if csv file has header, then not need to read the first line 
     If _hasheader = False Then 
      For i = 0 To fieldValues.Length() - 1 
       myRow.Item(i) = fieldValues(i).ToString 
      Next 
      myTable.Rows.Add(myRow) 
     End If 

     'Now reading the rest of the data to data table 
     While myReader.Peek() <> -1 
      fieldValues = myReader.ReadLine().Split(_seperator) 
      myRow = myTable.NewRow 
      For i = 0 To fieldValues.Length() - 1 
       myRow.Item(i) = fieldValues(i).Trim.ToString 
      Next 
      'check if there are empty rows in csv, ignore empty rows 

      If Not csv2xml.AreAllColumnsEmpty(myRow) = True Then 
       myTable.Rows.Add(myRow) 
      End If 

     End While 
    Catch ex As Exception 
     'MsgBox("Error building datatable: " & ex.Message) 
     Dim oError As ErrorLog = New ErrorLog 
     oError.LogError(_strWebsiteName, _ 
      loginID, _ 
      ex.Source.ToString, _ 
      ex.Message.ToString, _ 
      , _ 
      ex.StackTrace.ToString) 
     oError = Nothing 
     Return New DataTable("Empty") 
     'Server.Transfer(CustomErrorPage) 
    Finally 
     csv2xml = Nothing 
     myRow = Nothing 
    End Try 
    myReader.Close() 
    Return myTable 

    End Function 
+4

看看這個問題/答案http://stackoverflow.com/questions/1050112/how-to-read-a-csv-file-into-a-net-datatable ?rq = 1 – Steve 2012-07-05 11:05:56

+0

您似乎意外地忽略瞭解析文件中的行和字段的代碼部分。在我看來,這是與你的問題最相關的那部分代碼。 – 2012-07-05 12:46:36

回答

2

你的問題是,你似乎被簡單地通過分割每行字符串解析列逗號作爲分隔符。該方法不適用於所有CSV文件,因爲如果它是一個包含逗號的字符串,如您所示,整個字段值將被引號包圍。所以你需要首先用引號分割,然後用逗號分割剩下的部分,然後從字段的值中刪除引號,這是一個相當複雜的算法。你可以寫這樣的事情自己,或使用正則表達式來做到這一點,但在這一點上,我只想使用ADO加載CSV文件認爲你會更好:

Public Function LoadCsvFile(filePath As String, hasHeader As Boolean) As DataTable 
    Dim folderPath As String = Path.GetDirectoryName(filePath) 
    Dim fileName As String = Path.GetFileName(filePath) 
    Dim hdr As String = Nothing 
    If hasHeader Then 
     hdr = "Yes" 
    Else 
     hdr = "No" 
    End If 
    Dim connectionString As String = String.Format("Driver={Microsoft Text Driver (*.txt; *.csv)};Dbq={0};Extended Properties=""Text;HDR={1};FMT=Delimited""", folderPath, hdr) 
    Dim connection As New OdbcConnection(connectionString) 
    Dim adapter As New OdbcDataAdapter("SELECT * FROM [" + fileName + "]", connection) 
    Dim table As New DataTable() 
    adapter.Fill(table) 
    Return table 
End Function 
6

只需使用VB TextFieldParser類,並將HasFieldsEnclosedInQuotes屬性設置爲True:

+0

Ooo。好一個。我不知道那一個。 +1 – 2012-07-05 20:55:45