将文本文件写入Datagridview的特定行

时间:2016-01-10 21:16:00

标签: vb.net winforms datagridview text-files

我有一个Datagridview(dgvMaster)和一个逗号分隔的文本文件,我将其用作数据库(每行以ID号开头,这些都是唯一的)。按钮(btnLoadSeries)加载文本框(txtseriestoload)中显示的文件。 文本文件如下所示:

1,joe,smith
2,john,doe
30,charlie,brown

我想要的是能够将“1,joe,smith”的行写入第1行,将“30,charlie,brown”写入第30行,依此类推。我尝试了一些不同的想法,但我是一个自学VB用户。这是我当前的代码,它用文件中的行数填充dgvmaster并显示行号,然后在此之后添加数据。我试图简单地添加5000行,即使我的文件永远不会包含大于5000的id仍然没有运气。这是我第一次发帖,所以请善待!

   Private Sub btnLoadSeries_Click(sender As Object, e As EventArgs) Handles btnLoadSeries.Click
    dgvMaster.Rows.Clear()
    Dim TextLine As String = ""
    Dim SplitLine() As String
    Dim fname As String = txtSeriestoLoad.Text

    'Count the lines of the file.  May change to a fixed number.
    Dim lineCount = System.IO.File.ReadAllLines(fname).Length

    'Set the number of rows
    dgvMaster.RowCount = lineCount + 1

    'Show row number
    Dim rownumber As Integer
    For rownumber = 0 To lineCount
        dgvMaster.Rows(rownumber).HeaderCell.Value = (rownumber).ToString
    Next rownumber

    'write file to dgvmaster
    If System.IO.File.Exists(fname) = True Then
        Dim objReader As New System.IO.StreamReader(fname)
        Do While objReader.Peek() <> -1
            TextLine = objReader.ReadLine()
            SplitLine = Split(TextLine, ",")
            Me.dgvMaster.Rows.Add(SplitLine)
        Loop
    Else
        MsgBox("File Does Not Exist")
    End If



End Sub

2 个答案:

答案 0 :(得分:0)

您可以使用Environment.NewLine加载文件内容并拆分内容以获取行。然后使用逗号分割每一行以获取列,然后将它们添加到网格中。

例如:

Dim content = System.IO.File.ReadAllText("File Path")
Dim rows = content.Split(Environment.NewLine).Select(Function(Row)
                                         Dim Cells = Row.Split(",")
                                         Return New Person With
                                         {
                                             .Id = Integer.Parse(Cells(0)),
                                             .FirstName = Cells(1),
                                             .LastName = Cells(2)
                                         }
                                     End Function).OrderBy(Function(x) x.Id).ToList()
Me.DataGridView1.DataSource = rows

或者如果您需要添加/编辑/删除行:

Me.DataGridView1.DataSource = New BindingList(Of Person)(rows)

这是Person类:

Public Class Person
    Public Property Id As Integer
    Public Property FirstName As String
    Public Property LastName As String
End Class

答案 1 :(得分:0)

以下读取可执行路径中的文本文件(随意更改)到DataTable中,该DataTable用作BindingSource的DataSource(请参阅注释),然后将BindingSource设置为DataGridView的DataSource,其中没有定义列。加载数据后,我使用BindingSource根据字段ID查找并定位到DataGridView中的一行。 Button1将当前数据写回同一文件。 Button2显示了如何获取DataGridView.Button3中当前行的名字字段,这里我们更改了DataTable中的字段值。 Button4我们根据搜索定位到一个字段,然后找到它的位置。

我故意将控件命名为generic,随意重命名。

如果您需要易于添加的列名。

当然我们可以使用其他容器来处理数据,例如列表(Of T)但在这种情况下似乎以下工作对于手头的任务就好了。

如果ID丢失的可能性,则需要一些断言,但如果不是首先使用Integer.TryParse那么听起来应该存在。

代码

Public Class Form1
    ' provides easy method to find, position, view, add, edit, remove
    Private bs As New BindingSource
    Private fileName As String = IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TextFile1.txt")
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        ' make sure file exists
        If IO.File.Exists(fileName) Then
            Dim dt As New DataTable
            dt.Columns.Add(New DataColumn With {.ColumnName = "ID", .DataType = GetType(Integer)})
            dt.Columns.Add(New DataColumn With {.ColumnName = "FirstName", .DataType = GetType(String)})
            dt.Columns.Add(New DataColumn With {.ColumnName = "LastName", .DataType = GetType(String)})

            ' cycle through data and add rows to data table
            Using Reader As New Microsoft.VisualBasic.FileIO.TextFieldParser(fileName)

                Reader.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited
                Reader.Delimiters = New String() {","}

                Dim Row As String()

                While Not Reader.EndOfData
                    Try
                        Row = Reader.ReadFields()
                        dt.Rows.Add(New Object() {CInt(Row(0)), Row(1), Row(2)})
                    Catch ex As Microsoft.VisualBasic.FileIO.MalformedLineException
                        MsgBox("Line " & ex.Message & " is invalid.  Skipping")
                    End Try
                End While
            End Using

            bs.DataSource = dt
            DataGridView1.DataSource = bs

            ' let's see if id 3 exists and if so move to it
            Dim pos As Integer = bs.Find("ID", 3)
            If pos > -1 Then
                bs.Position = pos
            End If

        End If

    End Sub
    ''' <summary>
    ''' Write current data to file
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        If bs.DataSource IsNot Nothing Then
            Dim dt As DataTable = CType(bs.DataSource, DataTable)
            Dim sb As New System.Text.StringBuilder
            For Each row As DataRow In dt.Rows
                sb.AppendLine(String.Join(",", row.ItemArray))
            Next
            IO.File.WriteAllText(fileName, sb.ToString)
        End If
    End Sub
    ''' <summary>
    ''' example how to get back a field value
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        If bs.DataSource IsNot Nothing Then
            If bs.Current IsNot Nothing Then
                MessageBox.Show(CType(bs.Current, DataRowView).Row.Field(Of String)("FirstName"))
            End If
        End If
    End Sub
    ''' <summary>
    ''' Change a field value
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
        If bs.DataSource IsNot Nothing Then
            If bs.Current IsNot Nothing Then
                If Not String.IsNullOrWhiteSpace(TextBox1.Text) Then
                    CType(bs.Current, DataRowView).Row.SetField(Of String)("LastName", TextBox1.Text)
                End If
            End If
        End If
    End Sub
    ''' <summary>
    ''' Find and position based on a field value
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
        If bs.DataSource IsNot Nothing Then
            If Not String.IsNullOrWhiteSpace(TextBox2.Text) Then
                Dim pos As Integer = bs.Find("FirstName", TextBox2.Text)
                If pos > -1 Then
                    bs.Position = pos
                Else
                    MessageBox.Show(TextBox2.Text & " not found")
                End If
            End If
        End If
    End Sub
End Class

示例文本文件

1,Karen,Payne
2,Kevin,Gallagher
3,Mary,Williams
4,Lisa,Miller
5,Betty,Moore
6,Laura,Jackson
7,Jon,Wright

最后,如果你想从DataGridView导出这里是一种语言扩展方法(扩展方法进入代码模块)

IO.File.WriteAllLines(fileName, DataGridView1.DelimitedRows(","))

...

<System.Diagnostics.DebuggerStepThrough()> _
<Runtime.CompilerServices.Extension()> _
Public Function ExportRows(ByVal sender As DataGridView, ByVal Delimiter As String) As String()
    Return (From row In sender.Rows Where Not DirectCast(row, DataGridViewRow).IsNewRow Let RowItem = String.Join(Delimiter, Array.ConvertAll(DirectCast(row, DataGridViewRow).Cells.Cast(Of DataGridViewCell).ToArray, Function(c As DataGridViewCell) If(c.Value Is Nothing, "", c.Value.ToString))) Select RowItem).ToArray
End Function

新样本 此版本在读取所有行之前首先创建数据行。

文本文件

1,Karen,Payne
2,Kevin,Gallagher
3,Mary,Williams
4,Lisa,Miller
78,Bill,Jenkins
10,Jim,Clime
5,Betty,Moore
6,Laura,Jackson
7,Jon,Wright

修订代码

Public Class Form1
    ' provides easy method to find, position, view, add, edit, remove
    Private bs As New BindingSource
    Private fileName As String = IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TextFile1.txt")
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        If IO.File.Exists(fileName) Then
            Dim Identifier As Integer = 0
            Dim dt As New DataTable

            ' row with identifier but we are hiding it, feel free to show
            dt.Columns.Add(New DataColumn With {
                           .ColumnName = "ID",
                           .DataType = GetType(Integer),
                           .AutoIncrement = True,
                           .AutoIncrementSeed = 1,
                           .ColumnMapping = MappingType.Hidden
                       }
            )

            ' optional, show # in front of ID - feel free to discard
            dt.Columns.Add(New DataColumn With
                           {
                               .ColumnName = "Identifier",
                               .DataType = GetType(String),
                               .Expression = "'#' + ID"
                            }
            )

            dt.Columns.Add(New DataColumn With
                           {
                               .ColumnName = "FirstName",
                               .DataType = GetType(String)
                           }
            )
            dt.Columns.Add(New DataColumn With
                           {
                               .ColumnName = "LastName",
                               .DataType = GetType(String)
                           }
            )

            Dim HighIdentifier As Integer = 0
            Dim IdentifierList As New List(Of Integer)

            ' get highest identifier
            Using Reader As New Microsoft.VisualBasic.FileIO.TextFieldParser(fileName)
                Reader.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited
                Reader.Delimiters = New String() {","}

                Dim Row As String()
                While Not Reader.EndOfData
                    Row = Reader.ReadFields()
                    If Integer.TryParse(Row(0), Identifier) Then
                        IdentifierList.Add(Identifier)
                    End If
                End While
            End Using

            HighIdentifier = IdentifierList.Max

            ' add rows equal to highest identifier
            For x As Integer = 0 To HighIdentifier - 1
                dt.Rows.Add(New Object() {Nothing, "", ""})
            Next

            bs.DataSource = dt

            ' cycle through data and add rows to data table
            Using Reader As New Microsoft.VisualBasic.FileIO.TextFieldParser(fileName)

                Reader.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited
                Reader.Delimiters = New String() {","}

                Dim Row As String()
                Dim Index As Integer = 0

                While Not Reader.EndOfData
                    Try

                        Row = Reader.ReadFields()

                        ' find/update row if first field is truly an integer
                        ' we could go another route rather than BindingSource.Find
                        ' so feel free to change it e.g. DataTable.Find, DataTable.Select
                        If Integer.TryParse(Row(0), Identifier) Then
                            Index = bs.Find("ID", Identifier)
                            If Index > -1 Then
                                bs.Position = Index
                                CType(bs.Current, DataRowView).Row.SetField(Of String)("FirstName", Row(1))
                                CType(bs.Current, DataRowView).Row.SetField(Of String)("LastName", Row(2))
                            End If
                        End If
                    Catch ex As Microsoft.VisualBasic.FileIO.MalformedLineException
                        MessageBox.Show("Line " & ex.Message & " is invalid.  Skipping")
                    End Try
                End While
            End Using


            DataGridView1.DataSource = bs
            bs.Position = 0

        End If

    End Sub

    ''' <summary>
    ''' Write current data to file
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        If bs.DataSource IsNot Nothing Then
            Dim dt As DataTable = CType(bs.DataSource, DataTable)
            Dim sb As New System.Text.StringBuilder
            For Each row As DataRow In dt.Rows
                sb.AppendLine(String.Join(",", row.ItemArray))
            Next
            IO.File.WriteAllText(fileName, sb.ToString)
        End If

        ' IO.File.WriteAllLines(fileName, DataGridView1.DelimitedRows(","))
    End Sub
    ''' <summary>
    ''' example how to get back a field value
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        If bs.DataSource IsNot Nothing Then
            If bs.Current IsNot Nothing Then
                MessageBox.Show(CType(bs.Current, DataRowView).Row.Field(Of String)("FirstName"))
            End If
        End If
    End Sub
    ''' <summary>
    ''' Change a field value
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
        If bs.DataSource IsNot Nothing Then
            If bs.Current IsNot Nothing Then
                If Not String.IsNullOrWhiteSpace(TextBox1.Text) Then
                    CType(bs.Current, DataRowView).Row.SetField(Of String)("LastName", TextBox1.Text)
                End If
            End If
        End If
    End Sub
    ''' <summary>
    ''' Find and position based on a field value
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
        If bs.DataSource IsNot Nothing Then
            If Not String.IsNullOrWhiteSpace(TextBox2.Text) Then
                Dim pos As Integer = bs.Find("FirstName", TextBox2.Text)
                If pos > -1 Then
                    bs.Position = pos
                Else
                    MessageBox.Show(TextBox2.Text & " not found")
                End If
            End If
        End If
    End Sub
End Class