Рейтинг:
5
Maciej Los
Проверить это:
Dim dt As DataTable = New DataTable()
dt.Columns.AddRange({New DataColumn("Day", GetType(Int32)), _
New DataColumn("Date", GetType(DateTime)), _
New DataColumn("Room No.", GetType(Int32)), _
New DataColumn("Room Rate", GetType(Double)), _
New DataColumn("No. of Person", GetType(Int32)), _
New DataColumn("Amount", GetType(Double))})
dt.Rows.Add(New Object(){1, New DateTime(2018, 4, 9), 101, 900.00, 2, 1800.00})
dt.Rows.Add(New Object(){2, New DateTime(2018, 4, 10), 101, 900.00, 2, 1800.00})
dt.Rows.Add(New Object(){3, New DateTime(2018, 4, 10), 101, 900.00, 2, 1800.00})
dt.Rows.Add(New Object(){1, New DateTime(2018, 4, 9), 102, 1000.00, 3, 3000.00})
dt.Rows.Add(New Object(){2, New DateTime(2018, 4, 10), 102, 1000.00, 3, 3000.00})
dt.Rows.Add(New Object(){3, New DateTime(2018, 4, 10), 102, 1000.00, 3, 3000.00})
Dim result = dt.AsEnumerable() _
.GroupBy(Function(x) x.Field(Of Int32)("Room No.")) _
.Select(Function(grp) New With _
{ _
.RoomNo = grp.Key, _
.TotalAmt = grp.Take(grp.Count-1).Sum(Function(x) x.Field(Of Double)("Amount")) _
}) _
.Sum(Function(x) x.TotalAmt) '9600 ;)
В LINQ[
^] делает жизнь проще :) Видеть:
Введение в LINQ в Visual Basic | Microsoft Docs[
^]
DataTableExtensions.AsEnumerable Method (DataTable) (System.Data)[
^]
Несколько слов объяснения:
Dim result = dt.AsEnumerable() _ 'Returns an IEnumerable<T> object, where the generic parameter T is DataRow
.GroupBy(Function(x) x.Field(Of Int32)("Room No.")) _ 'group data by [Room No.]
.Select(Function(grp) New With _ 'select
{ _
.RoomNo = grp.Key, _ '[Room No.]
.TotalAmt = grp.Take(grp.Count-1) 'skip last row!!!
.Sum(Function(x) x.Field(Of Double)("Amount")) _ 'get sum of amount for each room
}) _
.Sum(Function(x) x.TotalAmt) 'get total amount
Перечислимый.GroupBy(TSource, TKey, TElement) Способ (Интерфейс IEnumerable(Метод), Функция(Метод TKey), Функции(Метода, TElement)) (System.Linq)[
^]
Перечислимый.Граф(Способ, Метод) (Интерфейс IEnumerable(Метод), Функция(Метод Логических)) (System.Linq)[
^]
Перечислимый.Take(TSource) Method (IEnumerable(TSource), Int32) (System.Linq)[
^]
Перечисли.Сумма(TSource) Для (Интерфейс IEnumerable(Метод), Функция(Метод Двойной)) (System.Linq)[
^]
Angel Deeyaz
Я попробовал его, и его результат равен 0.
Dim groupedTable = From objtbl In BookingDataSet.Tables("dt_Lodging").AsEnumerable() Group objtbl By key = objtbl.Field(Of String)("RoomNo") Into Group Select RoomNo = key, _ amount = Group.Sum(Function(objtbl) objtbl("Amount"))
То, что я пытаюсь сделать, - это сгруппировать RoomNo и не включать последнюю запись для каждой группы. Приведенный выше код просто сгруппирован и получает сумму, включающую последнюю строку каждой группы.
Я новичок в Linq, но я пытаюсь наклониться и понять его. :)
Maciej Los
Я попробовал свое решение, и оно отлично работает.
Angel Deeyaz
Проблема в том, что
.TotalAmt = grp.Take(grp.Count-1)
.
Ошибка также возникает, если одна строка удаляется.
Maciej Los
Я не понимаю, что вы имеете в виду. Вы пробовали мое решение (основанное на вашем примере)?
Я создал .чистая скрипка: здесь
Angel Deeyaz
Я попробовал ваше решение, да, оно работает. Но когда он попробовал это сделать с моим собственным,
общая сумма равна нулю. Когда я удалил "-1" в
".TotalAmt = grp.Take(grp.Count-1) ", он отображает общую общую сумму (включая последнюю строку каждой группы).
Angel Deeyaz
Я попробовал также В скрипке с другим набором данных, и я думаю, что что-то не так.
Imports System
Imports System.Data
Imports System.Data.DataSetExtensions
Imports System.Linq
Imports System.Xml
Public Module Module1
Public Sub Main()
Dim dt As DataTable = New DataTable()
dt.Columns.AddRange({New DataColumn("Day", GetType(Int32)), _
New DataColumn("Date", GetType(DateTime)), _
New DataColumn("Room No.", GetType(Int32)), _
New DataColumn("Room Rate", GetType(Double)), _
New DataColumn("No. of Person", GetType(Int32)), _
New DataColumn("Amount", GetType(Double))})
dt.Rows.Add(New Object(){1, New DateTime(2018, 4, 9), 101, 900.00, 2, 1800.00})
dt.Rows.Add(New Object(){2, New DateTime(2018, 4, 10), 101, 900.00, 2, 1800.00})
dt.Rows.Add(New Object(){3, New DateTime(2018, 4, 10), 101, 900.00, 2, 1800.00})
dt.Rows.Add(New Object(){1, New DateTime(2018, 4, 9), 102, 1000.00, 3, 3000.00})
Dim result = dt.AsEnumerable() _
.GroupBy(Function(x) x.Field(Of Int32)("Room No.")) _
.Select(Function(grp) New With _
{ _
.RoomNo = grp.Key, _
.TotalAmt = grp.Take(grp.Count-1).Sum(Function(x) x.Field(Of Double)("Amount")) _
}) _
.Sum(Function(x) x.TotalAmt)
Console.WriteLine("result: {0}", result)
End Sub
End Module
Результат должен быть 6, 600.00.
результат = 1800 + 1800 + 3000
Maciej Los
Почему 6600,00?
Вы хотели пропустить последнюю запись. В этом случае последний = первый для комнаты № 102.
Если вы хотите получить 6600,00, измените свой код на:
.TotalAmt = grp.Take(If(grp.Count>1,grp.Count-1, 1)).Sum(Function(x) x.Field(Of Double)("Amount")) _
Angel Deeyaz
Следует пропустить последнюю запись каждой группы.
Он работает в нашем демонстрационном образце. Однако после изменения кода в моем конце он суммирует сумму, включая последнюю запись каждой комнаты(группы).
Angel Deeyaz
Я не знаю, потому ли это, что моя таблица данных фильтруется по дням.
Maciej Los
Спасибо, Карло.
Angel Deeyaz
Я получил его несколько дней назад. Спасибо!
Maciej Los
Всегда пожалуйста. Пожалуйста, примите мой ответ как решение (зеленая кнопка), чтобы удалить ваш вопрос из списка без ответа.
Овации,
Мацей