如何按日/周/月筛选DataGridView数据并计算InstallmentAmount列总计?
实现每日/每周/每月筛选DataGridView并计算金额总和
Hey there! Let's walk through how to add daily, weekly, and monthly filtering to your DataGridView, plus calculate the total of the InstallmentAmount column. I'll use C# WinForms for examples since that's the typical context for DataGridView.
1. 准备基础数据结构
首先确保你的DataGridView绑定了DataTable(或类似结构化数据源),其中至少包含:
- 日期列(比如
TransactionDate,类型为DateTime) InstallmentAmount列(推荐用decimal类型存储金额)
以下是初始化DataTable的示例代码:
// 初始化数据表 DataTable transactionTable = new DataTable(); transactionTable.Columns.Add("TransactionDate", typeof(DateTime)); transactionTable.Columns.Add("InstallmentAmount", typeof(decimal)); // 填充示例数据(替换为你的实际数据逻辑) transactionTable.Rows.Add(new DateTime(2024, 5, 1), 150.50m); transactionTable.Rows.Add(new DateTime(2024, 5, 5), 200.00m); // 绑定到DataGridView dataGridView1.DataSource = transactionTable;
2. 添加筛选维度选择UI
在窗体上添加一个ComboBox控件,让用户选择筛选维度。在窗体加载事件中初始化它:
private void Form1_Load(object sender, EventArgs e) { comboBoxFilter.Items.AddRange(new string[] { "每日", "每周", "每月" }); comboBoxFilter.SelectedIndex = 0; // 默认选中每日筛选 }
3. 实现筛选与金额计算逻辑
创建一个可复用的方法,同时处理数据筛选和金额总计,让代码更整洁易维护。
方案一:使用DataView.RowFilter(适合中小型数据集)
private void ApplyFilterAndCalculateTotal(string filterType) { DataTable originalTable = (DataTable)dataGridView1.DataSource; DataView filteredView = originalTable.DefaultView; DateTime today = DateTime.Today; switch (filterType) { case "每日": // 筛选今日的记录 filteredView.RowFilter = $"TransactionDate >= #{today:yyyy-MM-dd}# AND TransactionDate < #{today.AddDays(1):yyyy-MM-dd}#"; break; case "每周": // 计算本周起始日(以周一为一周开始,可按需调整) int daysToMonday = (int)today.DayOfWeek - (int)DayOfWeek.Monday; daysToMonday = daysToMonday < 0 ? daysToMonday + 7 : daysToMonday; DateTime weekStart = today.AddDays(-daysToMonday); DateTime weekEnd = weekStart.AddDays(7); filteredView.RowFilter = $"TransactionDate >= #{weekStart:yyyy-MM-dd}# AND TransactionDate < #{weekEnd:yyyy-MM-dd}#"; break; case "每月": // 筛选当月的记录 DateTime monthStart = new DateTime(today.Year, today.Month, 1); DateTime monthEnd = monthStart.AddMonths(1); filteredView.RowFilter = $"TransactionDate >= #{monthStart:yyyy-MM-dd}# AND TransactionDate < #{monthEnd:yyyy-MM-dd}#"; break; } // 更新DataGridView显示筛选后的数据 dataGridView1.DataSource = filteredView.ToTable(); // 计算InstallmentAmount总和 decimal total = 0; foreach (DataRow row in ((DataTable)dataGridView1.DataSource).Rows) { if (row["InstallmentAmount"] != DBNull.Value) { total += Convert.ToDecimal(row["InstallmentAmount"]); } } // 在Label控件中显示总计(需提前在窗体上添加Label) lblTotalAmount.Text = $"总金额: {total:C}"; }
方案二:使用LINQ(适合大型数据集,效率更高)
如果数据量较大,LINQ查询更高效且可读性更强:
private void ApplyFilterAndCalculateTotal(string filterType) { DataTable originalTable = (DataTable)dataGridView1.DataSource; DateTime today = DateTime.Today; DataTable filteredTable; switch (filterType) { case "每日": filteredTable = originalTable.AsEnumerable() .Where(r => r.Field<DateTime>("TransactionDate").Date == today.Date) .CopyToDataTable(); break; case "每周": int daysToMonday = (int)today.DayOfWeek - (int)DayOfWeek.Monday; daysToMonday = daysToMonday < 0 ? daysToMonday + 7 : daysToMonday; DateTime weekStart = today.AddDays(-daysToMonday); filteredTable = originalTable.AsEnumerable() .Where(r => r.Field<DateTime>("TransactionDate") >= weekStart && r.Field<DateTime>("TransactionDate") < weekStart.AddDays(7)) .CopyToDataTable(); break; case "每月": DateTime monthStart = new DateTime(today.Year, today.Month, 1); filteredTable = originalTable.AsEnumerable() .Where(r => r.Field<DateTime>("TransactionDate") >= monthStart && r.Field<DateTime>("TransactionDate") < monthStart.AddMonths(1)) .CopyToDataTable(); break; default: filteredTable = originalTable; break; } // 更新DataGridView dataGridView1.DataSource = filteredTable; // 用LINQ计算总和 decimal total = filteredTable.AsEnumerable() .Sum(r => r.Field<decimal?>("InstallmentAmount") ?? 0); lblTotalAmount.Text = $"总金额: {total:C}"; }
4. 关联筛选UI与逻辑
给ComboBox添加选中事件,触发筛选和计算:
private void comboBoxFilter_SelectedIndexChanged(object sender, EventArgs e) { if (comboBoxFilter.SelectedItem != null) { ApplyFilterAndCalculateTotal(comboBoxFilter.SelectedItem.ToString()); } }
关键注意事项
- 日期格式:使用
DataView.RowFilter时,务必用yyyy-MM-dd格式的日期字符串,避免因区域设置导致的筛选错误。 - 空值处理:计算总和时一定要检查
DBNull.Value(或用LINQ的可空类型),防止运行时异常。 - 周起始日调整:示例中以周一为一周开始,若需要以周日为起始,修改
daysToMonday的计算逻辑,改用DayOfWeek.Sunday即可。
内容的提问来源于stack exchange,提问作者Suvo Ghosh
相关产品推荐
相关产品推荐

