aakar Ответов: 3

Вычислите итоговую сумму в таблице данных.


Привет!


У меня есть DataTable, который извлекает данные в следующем формате.

Регион Класс Активов Дивиденды PnL Бонус
Азия экс-Япония облигации 10000 10000 10000
Азия экс-Япония облигации 20000 20000 20000
Азия экс-Япония облигации 30000 30000 30000
Азия экс-Япония облигации 40000 40000 40000
Азия ex-Japan Cash Equities 11500 11500 11500
Asia ex-Japan Cash Equities 20500 20500 20500
Азия ex-Japan Cash Equities 16200 16200 16200
Азия экс-Япония кабриолеты 3000 3000 3000
Азия экс-Япония кабриолеты 2000 2000 2000
Americas Cash Equities 18000 18000 18000
Americas Cash Equities 17000 17000 17000
Американские Облигации 6600 6600 6600
Американские Облигации 5700 5700 5700
Япония Кабриолеты 14000 14000 14000
Япония Кабриолеты 14500 14500 14500


То, что нам нужно, - это общая сумма для каждой группы и подгруппы в приведенной выше таблице данных, как показано ниже :

Регион Класс Активов Дивиденды PnL Бонус
Азия экс-Япония облигации 10000 10000 10000
Азия экс-Япония облигации 20000 20000 20000
Азия экс-Япония облигации 30000 30000 30000
Азия экс-Япония облигации 40000 40000 40000
Облигации Итого 100000 100000 100000
Азия ex-Japan Cash Equities 11500 11500 11500
Азия ex-Japan Cash Equities 20500 20500 20500
Азия ex-Japan Cash Equities 16200 16200 16200
Денежные Средства Акции Итого 48200 48200 48200
Азия экс-Япония кабриолеты 3000 3000 3000
Азия экс-Япония кабриолеты 2000 2000 2000
Кабриолеты Всего 5000 5000 5000
Азия экс-Япония Итого 153200 153200 153200
Americas Cash Equities 18000 18000 18000
Americas Cash Equities 17000 17000 17000
Денежные Средства Акции Итого 35000 35000 35000
Американские Облигации 6600 6600 6600
Американские Облигации 5700 5700 5700
Облигации Итого 12300 12300 12300
Америка Итого 47300 47300 47300
Япония Кабриолеты 14000 14000 14000
Япония Кабриолеты 14500 14500 14500
Кабриолеты Всего 28500 28500 28500
Япония Итого 43000 43000 43000


Кроме того, нам нужно распечатать вышеприведенные данные в excel (т. е. мы не используем какой-либо инструмент отчетности, где можно было бы легко вычислить итоговые и субсчеты).

Как мы могли бы достичь этого? Любая помощь будет очень признательна.


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

Чарви.

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

Я пробовал перебирать данные и вычислять сумму, но это, похоже, работает только для внутренней группы, а не для внешней.

3 Ответов

Рейтинг:
5

sonymon mishra

// Надеюсь, что это работает с вашим предыдущим кодом

var _result1 = (from r1 in DT.AsEnumerable()
                           group r1 by new
                           {
                               RegionAsset = r1.Field<string>("Region Asset"),
                               Class = r1.Field<string>("Class"),

                           } into g
                           select new
                           {
                               RegionAsset = g.Key.RegionAsset,
                               Class = g.Key.Class,
                               TotalDividends = g.Sum(x => x.Field<int>("Dividends")),
                               TotalPnL = g.Sum(x => x.Field<int>("PnL")),
                               TotalBonus = g.Sum(x => x.Field<int>("Bonus"))

                           }).ToList();


           var _result2 = (from r1 in DT.AsEnumerable()
                           group r1 by new
                           {
                               RegionAsset = r1.Field<string>("Region Asset")

                           } into g
                           select new
                           {
                               RegionAsset = g.Key.RegionAsset,

                               TotalDividends = g.Sum(x => x.Field<int>("Dividends")),
                               TotalPnL = g.Sum(x => x.Field<int>("PnL")),
                               TotalBonus = g.Sum(x => x.Field<int>("Bonus"))

                           }).ToList();

           DataTable DTResult = DT.Clone();
           foreach (var r1 in _result1)
           {
               foreach (DataRow dr in DT.AsEnumerable().Where(p => p.Field<string>("Region Asset") == r1.RegionAsset && p.Field<string>("Class") == r1.Class))
               {
                   DataRow dtrow = DTResult.NewRow();
                   dtrow.ItemArray = new String[] { r1.RegionAsset, r1.Class, dr.Field<int>("Dividends").ToString(), dr.Field<int>("Dividends").ToString(), dr.Field<int>("Dividends").ToString() };
                   DTResult.Rows.Add(dtrow);
               }
               DataRow dtrow1 = DTResult.NewRow();
               dtrow1.ItemArray = new String[] { r1.Class + "Total", "", r1.TotalDividends.ToString(), r1.TotalPnL.ToString(), r1.TotalBonus.ToString() };
               DTResult.Rows.Add(dtrow1);

           }


aakar

Привет Sonymon,

Спасибо за решение. Это прекрасно работает, однако мне требуется 2 уровня итогов
то есть региональный актив-это Азия экс-Япония, А класс-облигации.
Поэтому мне потребовалось бы как общее количество классов, так и общее количество активов региона.

Ваше решение помогло мне получить общее количество классов в моем наборе данных. Как мне также получить общую сумму активов региона?

Рейтинг:
13

sonymon mishra

//попробовать это

var _result = from r1 in DT.AsEnumerable()
                         group r1 by new
                         {
                             RegionAsset = r1.Field<string>("Region Asset"),
                             Class = r1.Field<string>("Class"),


                         } into g
                         select new
                         {
                             RegionAsset = g.Key.RegionAsset,
                             Class = g.Key.Class,
                             TotalDividends = g.Sum(x => x.Field<int>("Dividends")),
                             TotalPnL = g.Sum(x => x.Field<int>("PnL")),
                             TotalBonus = g.Sum(x => x.Field<int>("Bonus"))

                         };


//Для Загрузки Excel
 using Excel = Microsoft.Office.Interop.Excel;
public static bool ExportDataTableToExcel(DataTable dt, string filepath)
       {
           Excel.Application oXL;
           Excel.Workbook oWB;
           Excel.Worksheet oSheet;

           try
           {
               // Start Excel and get Application object.
               oXL = new Excel.Application();

               // Set some properties
               oXL.Visible = true;
               oXL.DisplayAlerts = false;

               // Get a new workbook.
               oWB = oXL.Workbooks.Add(Missing.Value);

               // Get the Active sheet
               oSheet = (Excel.Worksheet)oWB.ActiveSheet;
               oSheet.Name = "Data";

               int rowCount = 1;
               foreach (DataRow dr in dt.Rows)
               {
                   rowCount += 1;
                   for (int i = 1; i < dt.Columns.Count + 1; i++)
                   {
                       // Add the header the first time through
                       if (rowCount == 2)
                       {
                           oSheet.Cells[1, i] = dt.Columns[i - 1].ColumnName;
                       }
                       oSheet.Cells[rowCount, i] = dr[i - 1].ToString();
                   }
               }

               oWB.SaveAs(filepath, Microsoft.Office.Interop.Excel.XlFileFormat.xlWorkbookDefault, Type.Missing, Type.Missing,
                           false, false, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange,
                           Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
               oWB.Close();
               oWB = null;
               oXL.Quit();
           }
           catch
           {
               throw;
           }
           finally
           {
               GC.WaitForPendingFinalizers();
               GC.Collect();
               GC.WaitForPendingFinalizers();
               GC.Collect();
           }
           return true;
       }


aakar

Привет Sonymon,
Спасибо за решение.
Но это устаревшее приложение, которое было построено в VS 2008. Мы не можем использовать LINQ здесь. Есть ли какой-нибудь способ сделать это с помощью C#2.0?

sonymon mishra

Эй, Извини, что я был немного занят в эти дни, проблема решена или тебе все еще нужно решение. Пожалуйста, дайте мне знать.

aakar

да, решение, которое вы предлагаете, работает как заклинание. Но только 1 вещь.
В настоящее время я получаю результаты буксировки :

var _result1 = из r1 в DT.Методом asenumerable()
группа Р1 по новой
{
RegionAsset = r1. Field & lt;string> ("актив региона"),
Class = r1. Field & lt;string> ("класс"),


} в g
выберите новый
{
RegionAsset = г.Ключ.RegionAsset,
Класс = g.Key.Class,
TotalDividends = g. Sum(x = & gt; x.Field< int> ("дивиденды")),
TotalPnL = г.Сумма(х => У Х.Поле И Л;int> У("НЛП")),
TotalBonus = g. Sum(x = & gt; x.Field< int> ("бонус"))

};


var _result2 = из r1 в DT.Методом asenumerable()
группа Р1 по новой
{
RegionAsset = r1. Field & lt;string> ("актив региона")

} в g
выберите новый
{
RegionAsset = г.Ключ.RegionAsset,

TotalDividends = g. Sum(x = & gt; x.Field< int> ("дивиденды")),
TotalPnL = г.Сумма(х => У Х.Поле И Л;int> У("НЛП")),
TotalBonus = g. Sum(x = & gt; x.Field< int> ("бонус"))

};

Теперь, как мне перебрать вышеприведенные два var (т. е. _result1 и _result2)
и получите o/p в нужном формате.
Второй ВАР т. е. _result2 имеет информацию, сгруппированную на более высоком уровне, в то время как первый ВАР т. е. _result1 имеет информацию, сгруппированную на один уровень вниз.

Сначала мне потребуется общая сумма внешней группы в excel, а затем общая сумма внутренней группы. Есть идеи?

sonymon mishra

Извините, я немного запутался. Пожалуйста, предоставьте мне желаемый результат.

aakar

Регион Класс Активов Дивиденды PnL Бонус
Азия экс-Япония облигации 10000 10000 10000
Азия экс-Япония облигации 20000 20000 20000
Азия экс-Япония облигации 30000 30000 30000
Азия экс-Япония облигации 40000 40000 40000
Облигации Итого 100000 100000 100000
Азия экс-Япония Итого 153200 153200 153200

O/p требуется в приведенном выше формате для каждого региона (т. е. общая сумма внешней группы) и класса активов (т. е. общая сумма внутренней группы)

Надеюсь, я все понял...

sonymon mishra

опубликовано решение 3. Пожалуйста, проверьте и дайте мне знать