2016-01-10 2 views
2

У меня есть Datagridview (dgvMaster) и текстовый файл с разделителями-запятыми, который я использую в качестве базы данных (каждая строка начинается с идентификационного номера, и они уникальны). Кнопка (btnLoadSeries) загружает файл, указанный в текстовом поле (txtseriestoload). Текст файла выглядит следующим образом:Запись текстового файла в определенные строки Datagridview

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

Что я хотел бы, чтобы иметь возможность написать строку с «1, Джо, кузнеца» грести # 1, и «30, чарли, коричневый» грести 30 , и так далее. Я пробовал несколько разных идей, но я сам являюсь пользователем VB. Вот мой текущий код, и он заполняет dgvmaster количеством строк из файла и показывает номер строки, но затем добавляет данные после этого. Я попытался просто добавить 5000 строк, хотя мой файл никогда не будет содержать идентификатор размером больше 5000, пока не удастся. Это первый пост для меня, поэтому, пожалуйста, будьте добрыми!

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 
+0

В реальной базе данных, которую CSV не вы Арент должны заботиться, где хранятся данные ... вы обычно даже не знаю. Добавьте данные по мере необходимости, затем сортируйте DGV по этому столбцу, и он поместит их в порядок – Plutonix

+0

Что относительно строки 3,4,5, ..., 29? Все числа существуют в файлах? Что относительно пробелов в файле, пробелы появляются только после id? А как насчет запятых? Все строки имеют две запятые, и имя и фамилия присутствуют? –

+0

Reza. Текстовый файл всегда будет содержать одинаковое количество столбцов и разделяется запятой, поэтому в случае строки, которая не содержит имени, файл будет показывать «4,, smith». Мне все равно, показаны ли строки, которые не содержат данных (3-29 в моем примере выше). Plutonix, я надеюсь добавить данные с помощью строки выбора, и именно поэтому я надеюсь, что идентификационный номер соответствует номеру строки. –

ответ

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 
+0

Я добавил класс person и создал новую кнопку в моей форме и вставил два примера кода (измененный путь к файлу и datagridview для соответствия моим), но во время выполнения я получил ошибку: необработанное исключение типа «System.FormatException» произошел в mscorlib.dll –

+0

Вот мои тестовые данные: '1, x, y 2 ,, 3, a, b', который работает правильно. Вероятно, у вас есть некорректный идентификатор или дополнительное место. Проследите за программой и используйте точку останова, чтобы найти проблему. Код работает правильно. Если вы не знакомы с linq, вы можете просто использовать цикл for. Если вы узнаете основную идею, то остальное легко :) –

+0

Спасибо Reza, мой текстовый файл не разделен пробелами, а линиями. –

0

Следующая читает в текстовом файле в исполняемом пути (не стесняйтесь изменять его) в DataTable, который используется как DataSour ce BindingSource (см. комментарии), тогда BindingSource настроен как DataSource DataGridView, где не определены столбцы. После загрузки данных я использую BindingSource для поиска и размещения строки в DataGridView на основе идентификатора поля. Button1 записывает текущие данные обратно в тот же файл. Button2 показывает, как получить первое имя для текущей строки в DataGridView.Button3, здесь мы изменим значение поля из DataTable. Button4 мы позиционируем поле, основанное на поиске, а затем позицию на него, если он найден.

Я всецело контролировал под общим именем, не стесняйтесь переименовывать их.

Если вам нужны имена столбцов, которые также легко добавить.

Конечно, мы могли бы использовать другие контейнеры для данных, например. List (Of T), но в этом случае, кажется, следующие работы для этой задачи очень хорошо.

Если есть вероятность, что идентификатор отсутствует, потребуется некоторое утверждение, но звучит так, должно быть, если не использовать 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 
+0

Карен, мой код показывает, что bs не объявлен. –

+0

Parker, он находится в верхней части кода. Также у меня есть проект VS2013 здесь https://onedrive.live.com/redir?resid=A3D5A9A9A28080D1!884&authkey=!AN4Zly9yVzOuPLg&ithint=file%2czip без двоичных файлов, поэтому перед его попыткой нужно построить сборку. –

+0

Thansk Karen для проекта, но позвольте мне уточнить. Я хочу записать строку в текстовом файле в соответствующую строку в DataGridView. Это позволит id # 101 находиться в строке 101 документа datagridview. Я хочу сделать это, чтобы позволить мне позже ссылаться на него, просто ищет строку 101 в datagridview. Это также связано с тем, что у меня нет проблем с тем, что строки в DataGridView пусты. –

Смежные вопросы