Mysql
 sql >> база данни >  >> RDS >> Mysql

Изравняване на стил на въртяща се таблица за Datagridview

В зависимост от това, което правите, в някои случаи можете да създадете заявка или подготвен изявление, за да направите това вместо вас. Те обикновено са за обобщаване на фиксиран набор от известни колони. В този случай не знаем колко колони за дата ще има или какви са те. Така че можем да го направим в код.

Използвах Access вместо mySQL, но концепцията е същата. Освен това го направих по-сложно, като регистрирах присъствието по класове, които не се срещат всеки ден. Началните данни:

Няма да използвам името на класа в резултатите, това прави дисплея твърде широк.

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 можете да започнете да копирате данни в нея. Отново вместо OleDB... обекти, които бихте използвали MySQL... обект, но работят по същия начин.

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

Би било по-лесно без отчитането по клас и просто докладвайте състоянието за целия ден. Резултатът:

Най-объркващата част е използването на данните за дата в една таблица с данни като колона име в друг и премахване на времевата част.

Това е само първо преминаване, така че вероятно може да бъде прецизирано. Част от обработката може да бъде извършена в SQL; DateTime.Parse метод за преобразуване на DateTime данни към низ в същия формат (премахване на Time и т.н.) може да бъде собствена процедура. Също така бих използвал 2-символен годишен формат, за да направя заглавките малко по-тесни.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Обобщени таблици PHP/MySQL

  2. Предаване на PHP променливи в MySQL

  3. Мониторинг на Percona сървър за MySQL - ключови метрики

  4. Как да деинсталирате MySQL от Mac OS X?

  5. Как да използвам mysql_escape_string() в Yii рамка?