Google App Script删除重复行代码导致日期格式异常问题
问题:Google Sheets去重后日期格式变为序列化数字
执行以下Google App Script代码删除重复行后,表格中的日期(如1/1/2024)变成了序列化数字(如45290):
function deleteDuplicateRows() { const ss = SpreadsheetApp.getActiveSheet(); let data = ss.getDataRange().getValues(); data = data.map(row => row.join(";")); const uniqueRows = [... new Set(data)].filter(String) const newData = uniqueRows.map(row => row.split(";")); const newLastRow = newData.length; const newLastCol = newData[0].length; ss.clearContents(); ss.getRange(1, 1, newLastRow, newLastCol).setValues(newData) }
执行前效果:
执行后效果:
问题原因
原代码通过row.join(";")将每行数据转为字符串时,日期对象会被自动转为对应的序列化数字字符串(Google Sheets中日期本质是代表天数的数字)。后续split(";")拆分后,这些数字以字符串形式存在,调用setValues写入表格时,会被识别为普通文本而非日期,同时丢失原有的日期格式设置。
另外,join和split的操作还会破坏其他数据类型(如数字、布尔值)的原有类型,导致数据格式异常。
解决方案
换一种不破坏数据类型的去重方式,直接基于数组内容判断唯一性,同时保留原数据的类型和格式关联。以下是修正后的代码:
function deleteDuplicateRows() { const sheet = SpreadsheetApp.getActiveSheet(); const dataRange = sheet.getDataRange(); const values = dataRange.getValues(); const formats = dataRange.getNumberFormats(); // 保存原单元格格式 // 用JSON.stringify将行转为唯一标识,同时保留数据类型信息 const uniqueMap = new Map(); values.forEach((row, index) => { const key = JSON.stringify(row); if (!uniqueMap.has(key)) { uniqueMap.set(key, { row, format: formats[index] }); } }); // 提取去重后的行和对应的格式 const uniqueRows = []; const uniqueFormats = []; uniqueMap.forEach(item => { uniqueRows.push(item.row); uniqueFormats.push(item.format); }); // 清空表格并写入数据 sheet.clearContents(); const outputRange = sheet.getRange(1, 1, uniqueRows.length, uniqueRows[0].length); outputRange.setValues(uniqueRows); outputRange.setNumberFormats(uniqueFormats); // 恢复原格式 }
代码说明
- 保留数据类型:使用
JSON.stringify将行转为字符串作为唯一键,相比直接join,它能区分不同数据类型(比如数字45290和字符串"45290"),避免类型丢失。 - 保存并恢复格式:通过
getNumberFormats()获取原单元格的格式设置,写入数据后用setNumberFormats()恢复,确保日期、数字等格式和原表格一致。 - Map去重:利用
Map的键唯一性实现去重,同时记录对应的行数据和格式,确保去重后的数据完整。
内容的提问来源于stack exchange,提问作者TimeCard Admin
相关产品推荐
相关产品推荐

