【问题标题】:Loop through datagridview and total amount of the same id循环遍历datagridview和同一个id的总量
【发布时间】:2017-01-19 05:42:30
【问题描述】:

我正在尝试获取每个 ID 在每个日期的总金额。

示例数据:

ID                  Date        Amount
619|RENE ABERIA     2017-01-03  418.80
619|RENE ABERIA     2017-01-03  497.48
619|RENE ABERIA     2017-01-03  29.13
620|JAMES APRECIO   2017-01-03  460.70
620|JAMES APRECIO   2017-01-03  76.33
620|JAMES APRECIO   2017-01-04  460.70
620|JAMES APRECIO   2017-01-04  59.32
620|JAMES APRECIO   2017-01-06  460.70

这一切都在一个数据网格视图中,并且有很多行。对于“2017-01-03”上的“619”,我有 3 个不同的金额,例如418.80、497.48 和 29.13。我想合计这个金额并将其放在最后一个条目的下方,如下所示。

ID                  Date        Amount
619|RENE ABERIA     2017-01-03  418.80
619|RENE ABERIA     2017-01-03  497.48
619|RENE ABERIA     2017-01-03  29.13
                    Total:      945.41
620|JAMES APRECIO   2017-01-03  460.70
620|JAMES APRECIO   2017-01-03  76.33
                    Total:      537.03
620|JAMES APRECIO   2017-01-04  460.70
620|JAMES APRECIO   2017-01-04  59.32
                    Total:      520.02
620|JAMES APRECIO   2017-01-06  460.70
                    Total:      460.70

我想我必须使用 FOR LOOP 才能转到每一行,但我不知道如何去做或继续。以下是我目前所拥有的,显然,要完成它还有很长的路要走。

 private void GetTotalShareForDay()
        {
        string laborerOrig = null;
        string laborerCopy = null;
        string dateOrig = null;
        string dateCopy = null;

        var share = 0.0;

        for (var i = 0; i < dgvSummary.Rows.Count; i++)
        {
            if (i == 0)
            {
                laborerOrig = dgvSummary.Rows[i].Cells[0].Value.ToString();
                dateOrig = dgvSummary.Rows[i].Cells[1].Value.ToString();
                laborerCopy = laborerOrig;
                dateCopy = dateOrig;

                share += Convert.ToDouble(dgvSummary.Rows[i].Cells[5].Value);
                Console.WriteLine(dateOrig + @" - " +dgvSummary.Rows[i].Cells[0].Value + @" - " + share);
                continue;
            }
            else
            {
                laborerOrig = dgvSummary.Rows[i].Cells[0].Value.ToString();
                dateOrig = dgvSummary.Rows[i].Cells[1].Value.ToString();
                if (laborerCopy == laborerOrig && dateCopy == dateOrig)
                {
                    share += Convert.ToDouble(dgvSummary.Rows[i].Cells[5].Value);
                    Console.WriteLine(dateOrig + @" - " + dgvSummary.Rows[i].Cells[0].Value + @" - " + share);
                }
                else if (laborerCopy == laborerOrig && dateCopy != dateOrig)
                {
                    dateCopy = dateOrig;
                    share = Convert.ToDouble(dgvSummary.Rows[i].Cells[5].Value);
                    Console.WriteLine(dateOrig + @" - " + dgvSummary.Rows[i].Cells[0].Value + @" - " + share);
                }
                else
                {
                    laborerCopy = laborerOrig;
                    dateCopy = dateOrig;
                    share = Convert.ToDouble(dgvSummary.Rows[i].Cells[5].Value);
                    Console.WriteLine(dateOrig + @" - " + dgvSummary.Rows[i].Cells[0].Value + @" - " + share);
                }

            }
        }
    }

这与“how I can show the sum of in a datagridview column?”中的问题不同,因为该示例仅汇总该列中的所有内容。我需要的是对具有相同 ID 和相同日期的列的值求和。

非常感谢您的帮助。

【问题讨论】:

  • 你当前的代码有什么问题?
  • 该代码只是一个尝试。我不知道如何去创建 for 循环来完成我所需要的。
  • 这与“如何在 datagridview 列中显示总和?”中的问题不同。因为该示例仅汇总了该列中的所有内容。我需要的是对具有相同 ID 和相同日期的列的值求和。
  • 我之前也遇到过这种问题。虽然有可能,但我建议创建多个网格视图,每个组一个(在您的情况下为 id)。通过这种方式,您可以轻松添加包含对象总和的行,我认为如果操作正确,它有可能对用户更加友好
  • 如果我为每个ID和Date创建一个gridview,那么它将是数千个datagridview。

标签: c# datagridview


【解决方案1】:

一旦将类似信息收集到字典中,就会遍历数据。

现在字典将包含可以轻松计算的每个 ID 和日期的数字列表。

private void GetTotalShareForDay()
{
    var results = new Dictionary<string,List<decimal>>();

    for (var i = 0; i < dgvSummary.Rows.Count; i++)
    {
        string laborerId = dgvSummary.Rows[i].Cells[0].Value.ToString();
        string date = dgvSummary.Rows[i].Cells[1].Value.ToString();

        string uniqueKey = laboredId + ","  + date; // Looking at your data, this should provide a unique ID

        decimal share = Convert.ToDecimal(dgvSummary.Rows[i].Cells[5].Value);

        if (!results.ContainsKey(uniqueKey)) 
            results.Add(uniqueKey, new List<decimal>());
        results[uniqueKey].Add(share);
    }

    foreach(var key in results.Keys)
    {
        // key is laborerID + "," + date
        var sum = results[key].Sum();
    }
}

使用元组的版本(首选)

private void GetTotalShareForDay()
{
    var results = new Dictionary<Tuple<string, string>,List<decimal>>();

    for (var i = 0; i < dgvSummary.Rows.Count; i++)
    {
        string laborerId = dgvSummary.Rows[i].Cells[0].Value.ToString();
        string date = dgvSummary.Rows[i].Cells[1].Value.ToString();

        Tuple<string, string> uniqueKey = new Tuple<string, string>(laborerID, date); // laborerID and date combined provide uniqueness

        decimal share = Convert.ToDecimal(dgvSummary.Rows[i].Cells[5].Value);

        if (!results.ContainsKey(uniqueKey)) 
            results.Add(uniqueKey, new List<double>());
        results[uniqueKey].Add(share);
    }

    foreach(var key in results.Keys)
    {
        // key.Item1 is laborerID
        // key.Item2 is Date as string
        decimal sum = results[key].Sum();
        Console.Write("Laborer ID:" + key.Item1);
        Console.Write("Date:" + key.Item2);
        Console.Write("Sum:" + sum);
    }
}

【讨论】:

  • 我们实际上有相同的想法,但您的编码方式与我的方式不同。意思是,你的比我的先进得多,我喜欢它。我只是无法让它工作。 “元组”我需要学习。我已经发布了我的代码编辑,它对我有用,但如果你可以让它与我创建的相似,那就是使用字典、元组等,这将对我的进步有很大帮助。
  • 请注意,您的算法有效,但假设相似数据是连续的。我的代码依赖于这样一个事实,即结合 labourerid 和 date 提供了一个唯一的身份,所有金额都可以分组,因此顺序不是算法中的一个因素。
  • 我做了一个字符串版本的代码,而不是使用元组
  • 前 3 行的总和应该是 945.41,但是使用你给我的代码,第一个总和是 1890.82,之后的 2 行总和是 537.03,但是你的代码给我 1074.06。它将“总和”乘以 2。
  • 只有当我们能够摆脱乘以 2 的小错误时,您的解决方案才会很棒。也许我可以将它除以 2 以获得正确的答案,但我真的很想知道为什么会这样发生错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-18
  • 2012-11-08
  • 1970-01-01
  • 1970-01-01
  • 2019-03-25
相关资源
最近更新 更多