2015-09-09 2 views
0

Я хочу, чтобы просмотреть мою таблицу посещений с использованием datagridview (vb.net)стиль Flatten Таблица Pivot для DataGridView

Это мой стол

Name | Date  | Status 
-------+-------------+-------- 
John | 08/08/2015 | P 
Mark | 08/08/2015 | A 
James | 08/08/2015 | L 
John | 08/09/2015 | A 
Mark | 08/09/2015 | A 
James | 08/09/2015 | A 

образец И это то, что я хочу, чтобы мой datagridview в выглядят так:

NAME | 08/08/2015 | 08/09/2015 
------+------------+------------ 
John |  P  |  A 
Mark |  A  |  A 
James |  L  |  A 
+0

Измените свой вопрос, чтобы включить код, с которым вы пытались выполнить эту работу. – Blackwood

ответ

0

В зависимости от того, что вы делаете, в некоторых случаях вы можете создать запрос или подготовленный оператор, чтобы сделать это за вас. Обычно они суммируют фиксированный набор известных столбцов. В этом случае мы не знаем, сколько столбцов даты будет или что они есть. Таким образом, мы можем сделать это в коде.

Я использовал Access вместо mySQL, но концепция такая же. Я также сделал это более сложным, регистрируя посещаемость по классу, которые не встречаются каждый день. Исходное данные:

enter image description here

я не буду использовать имя класса в результатах, это делает дисплей слишком широко.

Dim sql = <sql> 
      ((Use your own SQL obviously)) 
      </sql>.Value 

Dim dtTemp As New DataTable 

' get the data 
Using dbcon As OleDbConnection = GetACEConnection(), 
    cmd As New OleDbCommand(sql, dbcon) 

    dbcon.Open() 
    Using da As New OleDbDataAdapter(cmd) 
     da.Fill(dtTemp) 
    End Using 

End Using 

' unique list of "date" columns in the result set 
' ORDERBY Date is in the SQL 
Dim colNames = dtTemp.AsEnumerable(). 
       Select(Function(s) DateTime.Parse(s.Item("Date").ToString). 
         ToString("MM/dd/yyyy")). 
       Distinct.ToList() 

' unique list of students 
Dim Students = dtTemp.AsEnumerable().Select(Function(q) q.Item("Name")). 
       Distinct.ToList() 

' the final table to use with the DGV 
Dim dt As New DataTable 
Dim colName As String 

' add the name and class code designation columns 
dt.Columns.Add(New DataColumn(dtTemp.Columns(0).ColumnName, GetType(String))) 
dt.Columns.Add(New DataColumn(dtTemp.Columns(1).ColumnName, GetType(String))) 

' add a "MM/dd/yyyy" text column for each possible class day 
For n As Int32 = 0 To colNames.ToArray.Count - 1 
    colName = DateTime.Parse(colNames(n).ToString).ToString("MM/dd/yyyy") 
    dt.Columns.Add(New DataColumn(colName, GetType(String))) 
Next 

Dim newRow As DataRow 

' loop thru all students 
For Each s In Students 
    ' the student-class dataset 
    Dim drs As DataRow() = dtTemp.Select(String.Format("Name = '{0}'", s.ToString)). 
          OrderBy(Function(o) o.Item("ClassCode")).ToArray 

    ' create list of classes for this student 
    Dim classes = drs.AsEnumerable. 
      Select(Function(q) q.Item(1).ToString).Distinct.ToArray 

    For Each classcode As String In classes 
     ' filter the drs results to the current class 
     Dim datestat As DataRow() = drs.AsEnumerable. 
       Where(Function(q) q.Item(1).ToString = classcode).ToArray 

     ' create new row, copy the data from drs.Rows to dt.columns 
     newRow = dt.NewRow 
     newRow.Item(0) = s 
     newRow.Item(1) = classcode 
     ' NOTE since not all students will have a class everyday, some 
     ' "status" cells will be dbNull! 
     For Each statRow In datestat 
      Dim cname As String = DateTime.Parse(statRow.Item("Date"). 
                ToString()).ToString("MM/dd/yyyy") 
      newRow.Item(cname) = statRow.Item("Status") 
     Next 
     dt.Rows.Add(newRow) 
    Next 

Next 

dgv.AutoGenerateColumns = True 
dgv.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.ColumnHeader) 
dgv.DataSource = dt 

Оно не совсем так сложно, как это может выглядеть.

  1. Получить мастер набора данных для работы на
  2. Получить список уникальных имен студентов
  3. Имена столбцов для использования приходит из запроса Linq для извлечения уникальных дат класса в таблице данных
  4. Создать новый DataTable.
    • После StudentName и ClassCode петли добавляет один столбец для каждой даты, что соответствует любому класса. Имя столбца/текст заголовка поступает из только что созданного списка/массива ColNames.

С DataTable назначения создан, вы можете начать копирование данных на него. Опять же, вместо объектов вы использовали бы объект MySQL..., но они работают одинаково.

  1. Loop через все студент в списке студентов
  2. Для каждого извлечь список всех классов, которые они посещали из основных данных набора
  3. Loop через эти классы
  4. Извлечение строки для текущего класса из набора данных Student-Class
  5. Создайте новый DataRow с использованием итерационных часов Student и Class для первых двух столбцов.
  6. Преобразование каждого значения DateTime в текущий набор данных Student-Class в тот же формат, который используется для создания столбцов результатов (cname).
    • использовать его, чтобы скопировать их статус: newRow.Item(cname) = statRow.Item("Status") в новой строке
    • Так как классы не делаете встречаться каждый день, некоторые клетки будут пустыми (DbNull)
  7. Добавить новую строку в финал DataTable

Это было бы проще без отчетности по классам и просто сообщить о статусе на весь день. Результат:

enter image description here

наиболее запутанная часть с использованием датой данных в одном DataTable в качестве имени столбца в другом и зачистках времени части.

Это всего лишь первый проход, поэтому его можно скорее уточнить. Некоторая обработка может быть выполнена в SQL; метод DateTime.Parse для преобразования данных DateTime в строку в том же формате (удалить Time и т. д.) может быть его собственной процедурой. Я бы также использовал формат двухзначного года, чтобы заголовки немного были более узкими.

+0

СПАСИБО СМОТРЕТЬ! Я люблю тебя. Я люблю тебя. Я люблю тебя! Я застрял в этой части уже несколько недель! Спасибо огромное! вы очень помогли !!!! Я люблю тебя. Спасибо! –

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