You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB.NET中如何将文本文件数据解析到DataGridView(代码优化需求)

VB.NET 解析固定格式文本到DataGridView的优化方案

问题描述

在VB.NET中解析记事本数据到DataGridView时,使用空格作为分隔符会导致空字段被忽略,引发字段错位。需要优化代码以正确识别固定格式的字段,即使字段为空也能保留对应位置。

原始代码

OpenFileDialog1.ShowDialog()

Try
    Dim Delimiter As Char = " "
    Dim Datagrid As New DataTable
    Dim dr As DataRow
    
    Datagrid.Columns.Add("SER NO")
    Datagrid.Columns.Add("MANGU TANAKA")
    Datagrid.Columns.Add("ILHANA")
    Datagrid.Columns.Add("TAOYA")            
    Datagrid.Columns.Add("SUN NM")
    Datagrid.Columns.Add("T/N")
    Datagrid.Columns.Add("IDD NUMBER")
    Datagrid.Columns.Add("TOTAL IDD")
    Datagrid.Columns.Add("TIX")
    Datagrid.Columns.Add("PAY")
    Datagrid.Columns.Add("DISC")
    Datagrid.Columns.Add("FO")
    Datagrid.Columns.Add("CUS NAME")
    Datagrid.Columns.Add("ID")
    Datagrid.Columns.Add("REFN")
    Datagrid.Columns.Add("TRNX")           

    dr = Datagrid.NewRow()
    Dim Data_Read As New System.IO.StreamReader(OpenFileDialog1.FileName)
    While Data_Read.Peek() <> -1
        Datagrid.Rows.Add(Data_Read.ReadLine().Split(Delimiter))
    End While
    DataGridView1.DataSource = Datagrid
    Call Datagrid_Row_Count()
Catch ex As Exception
    MsgBox(ex.Message, MsgBoxStyle.Critical, "Import")
End Try

示例数据

SER NO - 12345678              MANGU TANAKA 20OCT                  PERANILA DEF
  ILHANA - ABCYY1234             PILIANMON:
  TAOYA  - ABC                                                        20 OCT 2022
  -------------------------------------------------------------------------------
  SUN NM T/N IDD NUMBER TOTAL IDD    TIX    PAY   DISC FO CUS NAME ID REFN   TRNX
  -------------------------------------------------------------------------------
  432149 000 5123456766    59.300 23.300  0.000  0.000*CR ABC/EFGH AA P8CBCK CONF
  432150 111 6123456767    43.450 18.450  0.000  0.000    ABCDEFGH QQ P9B26B BALK
  432151 222 7123456768    53.000 42.000  0.000  0.000 CR ABCDE/GH BB P9TSDX CONF
  432152 000 8123456769    88.750 25.750  0.000  0.000    ABC/EFGH AA P9YGTH BALK
  432153 333 9123456770    88.100 52.100  0.000  0.000*CR ABCDEFGH XX P9IQ27 CONF
  432154 555 1123456771   313.800 92.800  0.000  0.000 CR ABC/EFGH AA PCPZPH CONF
  From: Please do not respond <abc@noreply.net.com>
  Sent: Thursday, October 20, 2022 9:05 AM
  To:   REPLYME@SAMPLES.COM
  Subject:  Your persnl information

  SER NO - 87654321              MANGU TANAKA 20OCT-21OCT            PERANILA XYZ
  ILHANA - XYZWE5678             PILIANMON:
  TAOYA  - 1234AB                                                     20 OCT 2022
  -------------------------------------------------------------------------------
  SUN NM T/N IDD NUMBER TOTAL IDD    TIX    PAY   DISC FO CUS NAME ID REFN   TRNX
 -------------------------------------------------------------------------------
  123412*111 9875601128    81.150 23.150  0.000  0.000 CR ABCDEFGH AA M7NBVG CONF
  123413*111 9875601129    81.150 23.150  0.000  0.000 CR ABCD/FGH 11 M7NBVG CONF
  123414*222 9875601130    65.150 21.150  0.000  0.000 CR ABCDEFGH AA M7NBVG CONF
  123415*555 9875601131   168.200 20.200  0.000  0.000 CR AB/DEFGH 22 M7ZBCJ CONF
  123416*666 9875601132   168.200 20.200  0.000  0.000*CR ABCDEFGH AA M7ZBCJ BALK
  123417*777 9875601133    63.400 46.400  0.000  0.000 CR ABC/EFGH BB MQTEP7 CONF
  123418*012 9875601134    62.200 17.200  0.000  0.000    ABCDEFGH 11 MAUVAF CONF
  123419*023 9875601135    61.750 35.750  0.000  0.000 CR ABC/EFGH AA MQOEDC CONF
  123420*055 9875601136   285.600 100.6T  0.000  0.000    ABCDEFGH 55 ABPCOX BALK
  123421*009 9875601137    43.600 27.600  0.000  0.000*CR ABCDE/GH 00 MKQWEV CONF
  From: Please do not respond <abc@noreply.net.com>
  Sent: Thursday, October 20, 2022 9:05 AM
  To:   REPLYME@SAMPLES.COM
  Subject:  Your persnl information

  SER NO - 23456789              MANGU TANAKA 19OCT                  PERANILA DEF
  ILHANA - WERQQ7895             PILIANMON:
  TAOYA  - 1111ZZ                                                     20 OCT 2022
  -------------------------------------------------------------------------------
  SUN NM T/N IDD NUMBER TOTAL IDD    TIX    PAY   DISC FO CUS NAME ID REFN   TRNX
  -------------------------------------------------------------------------------
  987505*123 9870290897    51.650 26.650  0.000  0.000 CR ABCDEFG/ QQ M6XYZL CONF
  987506*321 9870290898    51.650 26.650  0.000  0.000*   ABCDEF/H AA M6XYZL BALK
  987507*567 9870290899   156.400 102.4T  0.000  0.000 CR ABC/EFGH ZZ JDAWEF NOTC
  From: Please do not respond <abc@noreply.net.com>
  Sent: Thursday, October 20, 2022 9:05 AM
  To:   REPLYME@SAMPLES.COM
  Subject:  Your persnl information

  SER NO - 98765432              MANGU TANAKA 19OCT-20OCT            PERANILA EFG
  ILHANA - ZXCQA0123             PILIANMON:
  TAOYA  - ABCD11                                                     20 OCT 2022
  -------------------------------------------------------------------------------
  SUN NM T/N IDD NUMBER TOTAL IDD    TIX    PAY   DISC FO CUS NAME ID REFN   TRNX
  -------------------------------------------------------------------------------
  987593 890 9870290968    60.100 35.100  0.000  0.000    AB/DEFGH 12 OOQW7H CONF
  987594*098 9870290897    51.650 26.650  0.000  0.000*CR ABCD/FGH 55 MQZVZL BALK

期望结果

DataGridView中每条数据的字段与表头一一对应,空字段保留空白单元格,不会导致后续字段错位。例如部分行的FO字段为空时,CUS NAME等后续字段仍能显示在正确列中。

优化后的代码

OpenFileDialog1.ShowDialog()

Try
    Dim Datagrid As New DataTable
    ' 初始化列结构
    Datagrid.Columns.Add("SER NO")
    Datagrid.Columns.Add("MANGU TANAKA")
    Datagrid.Columns.Add("ILHANA")
    Datagrid.Columns.Add("TAOYA")            
    Datagrid.Columns.Add("SUN NM")
    Datagrid.Columns.Add("T/N")
    Datagrid.Columns.Add("IDD NUMBER")
    Datagrid.Columns.Add("TOTAL IDD")
    Datagrid.Columns.Add("TIX")
    Datagrid.Columns.Add("PAY")
    Datagrid.Columns.Add("DISC")
    Datagrid.Columns.Add("FO")
    Datagrid.Columns.Add("CUS NAME")
    Datagrid.Columns.Add("ID")
    Datagrid.Columns.Add("REFN")
    Datagrid.Columns.Add("TRNX")           

    Dim currentSERNO As String = ""
    Dim currentMANGU As String = ""
    Dim currentILHANA As String = ""
    Dim currentTAOYA As String = ""
    Dim isDataSection As Boolean = False

    Using Data_Read As New System.IO.StreamReader(OpenFileDialog1.FileName)
        While Not Data_Read.EndOfStream
            Dim line As String = Data_Read.ReadLine()
            If String.IsNullOrWhiteSpace(line) Then Continue While

            ' 提取头部固定信息
            If line.TrimStart().StartsWith("SER NO -") Then
                currentSERNO = line.Substring(8, 10).Trim()
                currentMANGU = If(line.Length >= 55, line.Substring(25, 30).Trim(), "")
            ElseIf line.TrimStart().StartsWith("ILHANA -") Then
                currentILHANA = line.Substring(9, 15).Trim()
            ElseIf line.TrimStart().StartsWith("TAOYA  -") Then
                currentTAOYA = line.Substring(9, 15).Trim()
            End If

            ' 识别数据区域起始标记
            If line.StartsWith("-------------------------------------------------------------------------------") Then
                Data_Read.ReadLine() ' 跳过表头行
                isDataSection = True
                Continue While
            End If

            ' 跳过邮件无关内容
            If line.TrimStart().StartsWith("From:") OrElse line.TrimStart().StartsWith("Sent:") OrElse 
               line.TrimStart().StartsWith("To:") OrElse line.TrimStart().StartsWith("Subject:") Then
                isDataSection = False
                Continue While
            End If

            ' 解析数据行
            If isDataSection Then
                Dim row As DataRow = Datagrid.NewRow()
                ' 填充头部公共信息
                row("SER NO") = currentSERNO
                row("MANGU TANAKA") = currentMANGU
                row("ILHANA") = currentILHANA
                row("TAOYA") = currentTAOYA

                ' 按固定宽度提取字段(可根据实际数据调整位置和长度)
                row("SUN NM") = If(line.Length >= 8, line.Substring(0, 8).Trim(), "")
                row("T/N") = If(line.Length >= 12, line.Substring(8, 4).Trim(), "")
                row("IDD NUMBER") = If(line.Length >= 23, line.Substring(12, 11).Trim(), "")
                row("TOTAL IDD") = If(line.Length >= 32, line.Substring(23, 9).Trim(), "")
                row("TIX") = If(line.Length >= 40, line.Substring(32, 8).Trim(), "")
                row("PAY") = If(line.Length >= 48, line.Substring(40, 8).Trim(), "")
                row("DISC") = If(line.Length >= 57, line.Substring(48, 9).Trim(), "")
                row("FO") = If(line.Length >= 61, line.Substring(57, 4).Trim(), "")
                row("CUS NAME") = If(line.Length >= 72, line.Substring(61, 11).Trim(), "")
                row("ID") = If(line.Length >= 75, line.Substring(72, 3).Trim(), "")
                row("REFN") = If(line.Length >= 83, line.Substring(75, 8).Trim(), "")
                row("TRNX") = If(line.Length >= 88, line.Substring(83, 5).Trim(), "")

                Datagrid.Rows.Add(row)
            End If
        End While
    End Using

    DataGridView1.DataSource = Datagrid
    Call Datagrid_Row_Count()
Catch ex As Exception
    MsgBox(ex.Message, MsgBoxStyle.Critical, "Import")
End Try

代码说明

  1. 头部信息复用:提取每个数据块的SER NO、MANGU TANAKA等公共信息,自动填充到该块下的所有数据行。
  2. 数据区域识别:通过分割线标记判断进入数据区域,跳过表头和邮件无关内容。
  3. 固定宽度解析:使用Substring按预设位置提取字段,彻底避免空格拆分导致的字段错位问题,空字段自动保留空白。
  4. 边界防护:添加行长度判断,防止因行内容过短引发索引越界错误。

内容的提问来源于stack exchange,提问作者Joel Leoj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 19:50:45