【问题标题】:Adding running sum in group by date in new row在新行中按日期添加分组中的运行总和
【发布时间】:2021-10-05 05:54:42
【问题描述】:

我正在使用 Syncfusion DocIO 在 .docx 中使用一些道具创建表,但无法按日期创建行 => 在每个新年我都需要新的行数。 我已经创建了 sum 行,但是该行返回所有 sum 以获取其他道具(列), 所以我需要的只是每一年的新行总和。

我的例子:

Months Anuity InterestPaid PrincipalPaid BalanceDue Date
1 84,69 2,50 82,19 917,81 2021/11/12
2 84,69 2,29 82,40 835,41 2021/12/12
Sum for year 2021
3 84,69 2,09 82,61 752,80 2022/1/12
4 84,69 1,88 82,81 669,99 2022/2/12
5 84,69 1,67 83,02 586,97 2022/3/12
6 84,69 1,47 83,23 503,75 2022/4/12
7 84,69 1,26 83,43 420,31 2022/5/12
8 84,69 1,05 83,64 336,67 2022/6/12
9 84,69 0,84 83,85 252,82 2022/7/12
10 84,69 0,63 84,06 168,75 2022/8/12
11 84,69 0,42 84,27 84,48 2022/9/12
12 84,69 0,21 84,48 0,00 2022/10/12
Sum for year 2022
Sum all 1016,32 16,32 1000,00

我的代码:

        int i = 1;
        
        foreach (var amortizationData in aAmortizationPlanLoanPayment)
        {
            WTableRow tableRow = tableAmortizationData.AddRow(true);

            tableRow.Cells[0].AddParagraph().AppendText(i.ToString());
            tableRow.Cells[1].AddParagraph().AppendText(amortizationData.Anuity.ToString());
            tableRow.Cells[2].AddParagraph().AppendText(amortizationData.InterestPaid.ToString());
            tableRow.Cells[3].AddParagraph().AppendText(amortizationData.PrincipalPaid.ToString());
            tableRow.Cells[4].AddParagraph().AppendText(amortizationData.BalanceDue.ToString());
            tableRow.Cells[5].AddParagraph().AppendText(amortizationData.Date.AddMonths(aAmortizationPlanLoanPaymentData.Moratorium).ToString("yyyy/M/dd"));
            i++;
            
            if (amortizationData.Date.Month == 12)
            {
                    WTableRow YearSumrow = tableAmortizationData.AddRow(true);

                    WTableCell cell1 = YearSumrow.Cells[0];

                    var sumYearIWTextRange = cell1.AddParagraph().AppendText($"Sum for year {amortizationData.Date.Year}");

                sumYearIWTextRange = YearSumrow.Cells[1].AddParagraph().AppendText(); // need here running sum inside appendText();

                sumYearIWTextRange = YearSumrow.Cells[2].AddParagraph().AppendText(); // need here running sum inside appendText();

                sumYearIWTextRange = YearSumrow.Cells[3].AddParagraph().AppendText(); // need here running sum inside appendText();
            }

            if (amortizationData.BalanceDue == 0.00)
            {
                WTableRow LastYearRow = tableAmortizationData.AddRow(true);

                WTableCell cellLastYear = LastYearRow.Cells[0];

                var sumLastYearIWTextRange = cellLastYear.AddParagraph().AppendText($"Sum for year {amortizationData.Date.Year}");

                sumLastYearIWTextRange = LastYearRow.Cells[1].AddParagraph().AppendText(); // need here running sum inside appendText();

                sumLastYearIWTextRange = LastYearRow.Cells[2].AddParagraph().AppendText(); // need here running sum inside appendText();

                sumLastYearIWTextRange = LastYearRow.Cells[3].AddParagraph().AppendText(); // need here running sum inside appendText();
            }
        }

        
        WTableRow tableRowSum = tableAmortizationData.AddRow(true);
        WTableCell cell = tableRowSum.Cells[0];

        var totalIWTextRage = cell.AddParagraph().AppendText("Sum all");

        var totalAmountIWTextRage = tableRowSum.Cells[1].AddParagraph().AppendText(aAmortizationPlanLoanPayment.Sum(p => p.Anuity).ToString());

        totalAmountIWTextRage = tableRowSum.Cells[2].AddParagraph().AppendText(aAmortizationPlanLoanPayment.Sum(p => p.InterestPaid).ToString());

        totalAmountIWTextRage = tableRowSum.Cells[3].AddParagraph().AppendText(aAmortizationPlanLoanPayment.Sum(p => p.PrincipalPaid).ToString());

【问题讨论】:

  • “我已经用 Linq 创建了 sum 行,但是....” LINQ 在哪里?为什么不能使用 Linq 创建这个总和?你尝试了什么?没有人能说出它失败的原因,因为你没有分享你尝试过的东西......
  • 去掉不相关的字体大小和粗线将使我们的代码更具可读性;也许您应该将这些代码移到生成器方法中以真正清理它
  • 总之,它看起来像是我不会使用 LINQ 的那种东西;改用 foreach 循环。 Linq 是一把锤子,但不是所有问题都是钉子

标签: c# system.linq.dynamic syncfusion-blazor


【解决方案1】:

如果您有一堆数字(已经分组并汇总到不同的日期,但不必如此);

(DateTime D, int V)[] rows = new [] {
  (new(1999, 12, 1), 111), 
  (new(2000, 1, 1), 222), 
  (new(2000, 2, 1), 333), 
  (new(2000, 3, 1), 444),
  (new(2001, 1, 1), 555)
}

那么,当然,您可以使用 LINQ 来计算总和:

foreach(var row in rows){
  var runSum = rows.Where(r => r.D <= row.D).Sum(r => r.V);
}

但这比仅仅保留一个变量更浪费资源:

var runSum = 0;
foreach(var row in rows){
  runSum += row.V;
}

如果您希望您的运行总和不时重新开始,只需记住前一行(当然您的行需要按顺序排列):

var prevRow = rows[0];
var runSum = 0;
foreach(var row in rows){

  if(prevRow.D.Year != row.D.Year)
    runSum = 0;

  runSum += row.V;
}

如果您不希望当前行的值出现在总计中,则将输出置于增加 runSum 的行之上,如果这样做,则将输出置于其之下

【讨论】:

  • “但这比仅仅保留一个变量更浪费资源” 我们要讨论这个问题吗?你的说法很有主见。许多人认为 LINQ 表达式更好地说明了意图,并且更不容易出错(例如,for 循环缺少过滤器 -> select/if 语句)。潜在的性能损失通常并不重要,但可维护性得到了改善。
  • 你的说法很自以为是 - 不;这是事实。拥有一千长的数字列表,并将变量递增 一千次 比将变量递增 五十万 次所需的资源更少
  • 我认为我们处于不同的波长。我以为您在谈论 LINQ 的性能不如 for 循环的一般情况。显然你不是,或者你是吗?我发现很难比较您的代码示例,因为每个示例似乎都在做不同的事情。
  • 哦,是的,可能出现了一些混乱;当我观察资源消耗时,它正在比较第一个代码块,即在每次循环迭代中对所有先前值进行 LINQ 总和,即 O((n^2)/2),与简单增量(第二个代码块)的外部循环变量,这将是 O(n)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-09
  • 2023-03-04
  • 2021-09-30
相关资源
最近更新 更多