Maciej Los
Это очень просто, подумайте об этом!
Есть, по крайней мере, два способа добиться этого.
1. non-Linq решение:
1.1. Все, что вам нужно сделать, это отсортировать данные в таблице DataTable (dt
) по ID#
поле а потом мимо Log date/time
поле.
1.2 создайте новый объект DataTable (скажем, dtFinal
) с помощью dt.Clone()
способ и удаление Log date/time
поле.
1.3 петля через коллекцию строк dt
объект.
1.3.1 затем внутри петли:
- до того момента ID#
это то же самое, что и предыдущее
- проверьте, если Log date/time{No}
уже существует в DataTable (если нет - добавьте его)
- дата копирования с Log date/time
область применения dt
объект в Log date/time{No}
область применения dtFinal
объект
2. Решение Linq (читайте комментарии в приведенном ниже блоке кода):
Dim dt As DataTable = New DataTable()
dt.Columns.AddRange(New DataColumn() _
{ _
New DataColumn("ID#", Type.GetType("System.Int32")), _
New DataColumn("Log date/time", Type.GetType("System.DateTime")) _
})
dt.Rows.Add(New Object(){111111, #09/10/2018 7:30#})
dt.Rows.Add(New Object(){111111, #09/10/2018 10:30#})
dt.Rows.Add(New Object(){111111, #09/10/2018 13:30#})
dt.Rows.Add(New Object(){111111, #09/10/2018 17:30#})
dt.Rows.Add(New Object(){222222, #09/10/2018 7:30#})
dt.Rows.Add(New Object(){222222, #09/10/2018 17:30#})
dt.Rows.Add(New Object(){333333, #09/10/2018 7:30#})
dt.Rows.Add(New Object(){333333, #09/10/2018 18:30#})
'clone DataTable
Dim dtFinal As DataTable = dt.Clone()
'remove second column => "Log date/time"
dtFinal.Columns.Remove("Log date/time")
'group data by ID#
Dim dataGroupedByID = dt.AsEnumerable() _
.OrderBy(Function(x) x.Field(Of Integer)("ID#")) _
.ThenBy(Function(x) x.Field(Of DateTime)("Log date/time")) _
.GroupBy(Function(x) x.Field(Of Integer)("ID#")) _
.Select(Function(grp) New With _
{ _
.ID = grp.Key, _
.Dates = grp.Select(Function(x) x.Field(Of DateTime)("Log date/time")).ToList() _
}) _
.ToList()
'get max count of occurences of "Log date/time"
'to be able to find out how many columns od "Log date/time" have to be added
Dim maxOccurance = dataGroupedByID _
.Select(Function(x) x.Dates.Count()) _
.Max()
'add "Log date/time" columns
Dim i As Integer = 0
For i = 1 To maxOccurance
dtFinal.Columns.Add(New DataColumn(String.Format("Log date/time {0}", i), Type.GetType("System.DateTime")))
Next
'loop throug the collection of items in dataGroupedByID list
For Each item In dataGroupedByID
'define new row
Dim dr = dtFinal.NewRow()
'
dr("ID#") = item.ID
'insert date into corresponding column
For i = 0 To item.Dates.Count()-1
dr(String.Format("Log date/time {0}", i+1)) = item.Dates(i)
Next
'add row
dtFinal.Rows.Add(dr)
Next