Bergantung pada apa yang Anda lakukan, dalam beberapa kasus Anda bisa membuat kueri atau pernyataan yang disiapkan untuk melakukan ini untuk Anda. Ini biasanya untuk meringkas satu set tetap kolom yang diketahui. Dalam hal ini kita tidak tahu berapa banyak kolom tanggal yang akan ada atau apa itu. Jadi, kita bisa melakukannya dalam kode.
Saya menggunakan Access alih-alih mySQL, tetapi konsepnya sama. Saya juga membuatnya lebih rumit dengan mencatat kehadiran berdasarkan kelas yang tidak bertemu setiap hari. Data awal:
Saya tidak akan menggunakan nama kelas dalam hasil, itu membuat tampilan terlalu lebar.
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
Ini tidak serumit kelihatannya.
- Dapatkan kumpulan data master untuk bekerja
- Dapatkan daftar nama siswa yang unik
- Nama kolom yang akan digunakan berasal dari kueri linq untuk mengekstrak tanggal kelas unik dalam tabel data
- Buat
DataTable
baru untuk hasilnya.- Setelah
StudentName
danClassCode
loop menambahkan satu kolom untuk setiap tanggal yang apa saja kelas bertemu. Nama kolom/teks header berasal dariColNames
daftar/array baru saja dibuat.
- Setelah
Dengan DataTable tujuan dibuat, Anda dapat mulai menyalin data ke sana. Sekali lagi, alih-alih OleDB...
objek yang akan Anda gunakan MySQL...
objek, tetapi fungsinya sama.
- Mengulang semua siswa dalam daftar siswa
- Untuk masing-masing, ekstrak daftar semua kelas yang mereka hadiri dari kumpulan data master
- Mengulang kelas-kelas tersebut
- Ekstrak baris untuk kelas saat ini dari kumpulan data Kelas-Siswa
- Buat
DataRow
baru menggunakan vars iterasi Siswa dan Kelas untuk 2 kolom pertama. - Konversi setiap nilai DateTime dalam kumpulan data Kelas-Siswa saat ini ke format yang sama yang digunakan untuk membuat kolom hasil (
cname
).- gunakan untuk menyalin status mereka:
newRow.Item(cname) = statRow.Item("Status")
ke baris baru - Karena kelas tidak bertemu setiap hari, beberapa sel akan kosong (
DbNull
)
- gunakan untuk menyalin status mereka:
- Tambahkan baris baru ke tabel data akhir
Akan lebih mudah tanpa pelaporan Berdasarkan Kelas, dan cukup laporkan statusnya sepanjang hari. Hasilnya:
Bagian yang paling membingungkan adalah menggunakan Tanggal data dalam satu datatable sebagai kolom nama di tempat lain dan menghapus bagian waktu.
Itu hanya umpan pertama, jadi kemungkinan bisa disempurnakan. Beberapa pemrosesan mungkin dapat dilakukan dalam SQL; DateTime.Parse
metode untuk mengonversi DateTime
data ke string dalam format yang sama (menghapus Waktu dll) bisa menjadi prosedurnya sendiri. Saya juga akan menggunakan format tahun 2 karakter untuk membuat header sedikit lebih sempit.