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
代码说明
- 头部信息复用:提取每个数据块的
SER NO、MANGU TANAKA等公共信息,自动填充到该块下的所有数据行。 - 数据区域识别:通过分割线标记判断进入数据区域,跳过表头和邮件无关内容。
- 固定宽度解析:使用
Substring按预设位置提取字段,彻底避免空格拆分导致的字段错位问题,空字段自动保留空白。 - 边界防护:添加行长度判断,防止因行内容过短引发索引越界错误。
内容的提问来源于stack exchange,提问作者Joel Leoj
相关产品推荐
相关产品推荐

