icavs Ответов: 1

Транспонировать результат таблицы данных в другую таблицу данных


Всем Привет,

Просто хотел бы попросить вашей помощи о том, как это сделать дальше vb.net-да..
Необходимо перенести результат таблицы данных в другую таблицу данных.
Все журналы определенного идентификатора# должны быть переупорядочены только в одну строку.

Таков сценарий.

Данные таблица 1 результат
ID#	    Log date/time
111111	09/10/2018 7:30
111111	09/10/2018 10:30
111111	09/10/2018 13:30
111111	09/10/2018 17:30
222222	09/10/2018 7:30
222222	09/10/2018 17:30
333333	09/10/2018 7:30
333333	09/10/2018 18:30


Перенесите данные из таблицы 1 в эту таблицу
Таблица данных 2
ID#	    Log date/time 1	  Log date/time 2	  Log date/time 3	  Log date/time 4
111111	09/10/2018 7:30	  09/10/2018 10:30	  09/10/2018 13:30	  09/10/2018 17:30
222222	09/10/2018 7:30	  09/10/2018 17:30		
333333	09/10/2018 7:30	  09/10/2018 18:30		


Что я уже пробовал:

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

Заранее спасибо.

1 Ответов

Рейтинг:
11

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