VB.NET去除DataGridView重复数据:按月显示考勤数据
解决VB.NET DataGridView考勤数据重复问题
核心原因分析
重复数据通常来自两个场景:
- MySQL查询返回了同一日期的多条考勤记录(比如员工同一天多次打卡)
- 代码中合并日期列表与考勤数据时,未做去重处理,导致同一日期被多次添加
具体解决办法
1. 从SQL查询层面去重(推荐)
直接在查询时确保每个日期仅返回一条有效记录,避免后续代码处理冗余数据。假设考勤表为attendance,字段包含emp_id、record_date(日期)、time_in、time_out,可通过分组聚合获取每个日期的有效打卡记录:
SELECT record_date, MIN(time_in) AS time_in, -- 取当日最早签到时间 MAX(time_out) AS time_out -- 取当日最晚签退时间 FROM attendance WHERE emp_id = @EmpId AND DATE_FORMAT(record_date, '%Y-%m') = DATE_FORMAT(NOW(), '%Y-%m') GROUP BY record_date ORDER BY record_date
如果需要保留特定规则的记录(比如最新录入的),可改用ROW_NUMBER()窗口函数:
SELECT record_date, time_in, time_out FROM ( SELECT record_date, time_in, time_out, ROW_NUMBER() OVER(PARTITION BY record_date ORDER BY create_time DESC) AS rn FROM attendance WHERE emp_id = @EmpId AND DATE_FORMAT(record_date, '%Y-%m') = DATE_FORMAT(NOW(), '%Y-%m') ) AS t WHERE rn = 1
2. 代码层面处理DataTable去重
如果无法修改SQL查询,可在获取数据后对DataTable进行去重,再与日期列表合并:
' 第一步:构建当月1-31天的基础数据表 Dim dtDays As New DataTable() dtDays.Columns.Add("日期", GetType(Date)) dtDays.Columns.Add("Time_in", GetType(String)) dtDays.Columns.Add("Time_out", GetType(String)) Dim currentYear = DateTime.Now.Year Dim currentMonth = DateTime.Now.Month Dim totalDays = DateTime.DaysInMonth(currentYear, currentMonth) For day = 1 To totalDays Dim dr = dtDays.NewRow() dr("日期") = New DateTime(currentYear, currentMonth, day) dr("Time_in") = DBNull.Value dr("Time_out") = DBNull.Value dtDays.Rows.Add(dr) Next ' 第二步:获取数据库考勤数据并去重 ' 假设dtAttendance是从MySQL查询得到的原始数据 Dim dtUniqueAttend = dtAttendance.DefaultView.ToTable(True, "record_date", "time_in", "time_out") ' 参数True表示保留唯一行,后面列名指定去重依据的字段 ' 第三步:将考勤数据匹配到日期表(避免重复添加) For Each drAttend In dtUniqueAttend.Rows Dim targetDate = CDate(drAttend("record_date")) Dim matchRows = dtDays.Select($"日期 = '{targetDate:yyyy-MM-dd}'") If matchRows.Length > 0 Then matchRows(0)("Time_in") = drAttend("time_in").ToString() matchRows(0)("Time_out") = drAttend("time_out").ToString() End If Next ' 第四步:绑定到DataGridView(绑定前清空原有数据源) DataGridView1.DataSource = Nothing DataGridView1.DataSource = dtDays
3. 排查绑定逻辑的重复操作
检查代码中是否存在多次绑定数据源的情况,比如在按钮点击事件中重复执行DataGridView1.DataSource = dtData而未先清空。确保每次绑定前重置数据源:
' 绑定前清空 DataGridView1.DataSource = Nothing ' 再设置新数据源 DataGridView1.DataSource = dtFinalData
额外排查点
- 检查MySQL数据库中是否存在同一员工同一日期的冗余打卡记录,若为业务误操作,需清理数据;
- 若截图中显示的重复是日期与考勤记录的重复组合,可对比上述方法逐一验证。
内容的提问来源于stack exchange,提问作者so-me
相关产品推荐
相关产品推荐

