【问题标题】:Read Tab Delimited File Into DataGridView将制表符分隔文件读入 DataGridView
【发布时间】:2015-06-24 14:27:06
【问题描述】:

以下代码我已将制表符分隔文件读入 DataGridView。它工作正常,但有几个问题我不确定如何解决。

Dim query = From line In IO.File.ReadAllLines("C:\Temp\Temp.txt")
Let Data = line.Split(vbTab)
Let field1 = Data(0)
Let field2 = Data(1)
Let field3 = Data(2)
Let field4 = Data(3)

DataGridView1.DataSource = query.ToList
DataGridView1.Columns(0).Visible = False

如何根据标题行中的字段数添加字段(列)?标题行当前包含 110 个字段,我不想以与 Let field1 = Data(0) 类似的方式定义它们

我还需要跳过标题行,只显示之后的行。

有没有比我目前正在做的更好的方法来处理这个问题?

【问题讨论】:

  • OleDB 将读取该类型的文件,创建一个可以绑定到 DGV 的 DataTable

标签: vb.net datagridview csv header-row


【解决方案1】:

有几种工具可以解析这种类型的文件。一个是 OleDB。

我无法弄清楚(已删除)答案是如何工作的,因为HDR=No; 告诉文本驱动程序第一行不包含列名。但有时会在没有 IMEX 的情况下读取前 8 行后忽略它。

但是,FMT=Delimited\""" 看起来像是从 C# 答案复制而来,因为 VB 不使用 \ 来转义字符。看起来它也混淆了列分隔符(在这种情况下是逗号或制表符)和文本分隔符(通常是"

如果文件是制表符分隔的,则正确的值为FMT=TabDelimited。我猜这些字段是用引号分隔的文本(例如"France" "Paris" "2.25"),而 OleDB 是用引号而不是制表符来切分数据以意外得到相同的结果。

正确的 ACE 字符串是:

Dim connstr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source='C:\Temp';Extended Properties='TEXT;HDR=Yes;FMT=TabDelimited';"

仅使用连接字符串会将每个文件导入为字符串。您还可以让 OleDB 将读取的数据转换为任何数据类型,这样您就不必在代码中乱扔大量 Convert.ToXXXX 来将 String 数据转换为任何类型。

这需要使用Schema.INI 来定义文件。这将替换连接字符串中的大部分扩展属性,只留下 Extended Properties='TEXT';"(这意味着使用 TEXT 驱动程序)。在与数据相同的文件夹中创建文件名Schema.INI

[大写.txt]
ColNameHeader=真
字符集=437
格式=制表符分隔
TextDelimiter="
DecimalSymbol=.
货币符号=$
Col1="Country" 文本宽度 254
Col2="Capital City" 文字宽度 254
Col3="人口" 单
Col4="Fake" 整数

一个Schema.INI 可以包含许多文件的布局。每个文件都有自己的部分,标题为文件名(例如[FooBar.CSV][Capitals.txt]etc)

大部分条目应该是不言自明的,但FORMAT 定义了列分隔符(TabDelimitedCSVDelimited 或自定义Delimited(;)); TextDelimiter 是用于包含可能包含空格或其他特殊字符的列数据的字符。 CurrencySymbol 之类的内容允许您允许使用外来符号并且可以省略。

ColN= 列表是您可以重命名列和指定数据类型的地方。输入 100 多列可能会很乏味,但可能主要是复制和粘贴。完成后,您将始终拥有它,并且能够轻松使用类型化数据。

您无需指定列名/大小/类型即可使用 Schema.INI 如果文件包含列名作为第一行 (ColNameHeader=True),则可以使用 Schema只是以清晰易读的方式指定各种参数,而不是将它们压缩到连接字符串中。

OleDB 在与导入文件相同的文件夹中查找 Schema.INI,然后查找带有 SQL 中使用的“表”的确切名称的部分:

' form level DT var
Private capDT As DataTable

' procedure code to load the file:
Dim connstr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source='C:\Temp';Extended Properties='TEXT';"
Dim SQL = "SELECT * FROM Capitals.txt"

capDT = New DataTable

' USING will close and dispose of resources
Using cn As New OleDbConnection(connstr),
            cmd As New OleDbCommand(SQL, cn)

    cn.Open()
    Using da As New OleDbDataAdapter(cmd)
        da.Fill(capDT)
    End Using

End Using   ' close and dispose

DataTable 现在可以使用了。如果我们迭代列,您可以看到它们与架构中指定的类型匹配:

' display data types
For n As Int32 = 0 To capDT.Columns.Count - 1
     Console.WriteLine("name: {0}, datatype: {1}",
                        capDT.Columns(n).ColumnName,
                        capDT.Columns(n).DataType.ToString)
Next

输出:

名称:国家,数据类型:System.String
名称:首都,数据类型:System.String
名称:人口,数据类型:System.Single
名称:假,数据类型:System.Int32

另见:

【讨论】:

  • 那么我必须删除我的答案,有些东西坏了。是的,我找到了一个 c# 部分,它今天似乎整天都工作得很好。哦,好的,谢谢你的帮助,我明天上班看看。
  • 好吧,这让我很烦,我从家里登录上班,果然我有一个正在使用的方案文件,错误地删除了它。但是,你还是觉得我发的不对?
  • 我的方案包括第 1 行 = [Temp.txt],第 2 行 = Format=Delimited( )。我一定是用其他一些不起作用的代码创建的。
  • 这说明了很多!由于您可能不想定义所有 100 列,请尝试使用我在顶部的 connstr。您答案中的那个显然不能单独工作。
  • 好的,所以在您的架构中,您将列定义为特定格式。我也需要这样做吗?不过我有 100 多列。
猜你喜欢
  • 1970-01-01
  • 2013-03-09
  • 1970-01-01
  • 2015-10-22
  • 2012-04-01
  • 2012-04-18
  • 1970-01-01
  • 2013-11-28
  • 2023-03-10
相关资源
最近更新 更多