请求修改Google Apps Script实现删除重复签到签出的两条记录
解决Google Sheets签到签出记录成对删除问题
原代码仅能删除重复项的第二条记录,且依赖r[1]+r[2]的字符串匹配(如果签到/签出的时间戳不同,这个匹配逻辑本身就不成立)。要实现同一人员完成签到+签出后删除两条记录,可以调整思路,先按员工标识分组收集行号,再批量删除成对记录:
function deleteCheckInOutPairs() { const ss = SpreadsheetApp.getActive(); const sh = ss.getActiveSheet(); const startRow = 1; // 若表头在第1行、数据从第2行开始,修改为2 const dataRange = sh.getDataRange(); const values = dataRange.getDisplayValues(); const rowCount = values.length; // 按员工标识分组存储对应的行号 const employeeRows = {}; // 遍历所有行,收集每个员工的记录行号 for (let i = 0; i < rowCount; i++) { const rowNumber = i + startRow; const employeeId = values[i][1]; // 第2列为员工唯一标识(姓名/ID),按需修改列索引 if (!employeeId) continue; // 跳过空行或无效记录 if (!employeeRows[employeeId]) { employeeRows[employeeId] = []; } employeeRows[employeeId].push(rowNumber); } // 筛选出有且仅有两条记录的员工,收集对应的行号 const rowsToDelete = []; for (const id in employeeRows) { const rows = employeeRows[id]; if (rows.length === 2) { rowsToDelete.push(...rows); } // 若需处理多次扫描的情况,可调整此处逻辑(比如删除所有记录) } // 按行号降序排序,避免删除时索引混乱 rowsToDelete.sort((a, b) => b - a); // 批量删除目标行 rowsToDelete.forEach(row => { sh.deleteRow(row); }); }
关键改动说明
- 分组收集行号:不再单次遍历检测重复,而是先按员工唯一标识(姓名/ID)分组,记录该员工的所有记录行号,确保能找到成对的签到/签出记录。
- 批量删除逻辑:筛选出刚好有2条记录的员工,将这两条记录的行号加入删除列表,再按降序排序后删除——这样删除下方的行不会影响上方行的索引,避免漏删或错删。
- 灵活适配表头:通过
startRow参数控制起始行,若你的表单响应表表头在第1行,将startRow改为2即可避免误删表头。
注意事项
- 确认
values[i][1]对应的是员工的唯一标识列,若标识在其他列(比如第3列),修改为values[i][2]即可。 - 若需要处理员工多次扫描的场景(比如重复签到后才签出),可调整
rows.length === 2的判断逻辑,比如改为rows.length >= 2来删除所有记录,或保留最新两条记录。
内容的提问来源于stack exchange,提问作者Joshua Schwartz
相关产品推荐
相关产品推荐

