Google Sheet API循环删除行部分失败问题排查与方案咨询
问题原因
行只删除了一部分的核心问题是正序按索引删行会导致索引动态偏移:
- 你存在
deletion数组里的行号是调用getRows()时拿到的初始静态索引 - 表格每删除1行,被删行下方的所有行都会自动上移1位,提前存好的索引就全部错位了
- 举个实际例子:你要删索引为2、5、7的三行,先删索引2的行后,原来索引5的行现在实际位置是4,原来索引7的行实际位置是6,后续再按原数组的索引去删,要么漏删目标行,要么错删非目标行。
另外你的匹配逻辑还有个小bug:遇到Discord字段为空的行时,只累加了行号i,没有重置匹配指针j,会导致j快速递增到数组长度,把后面正常的行误判为待删除行。
解决方法
方法1:最小改动,倒序删除
不需要调整前面收集待删除行的逻辑,只要把待删除索引按从大到小排序,从最下面的行开始往上删就行——删下方的行不会影响上方行的索引位置,完全不会出现错位问题:
// 待删除索引倒序排序 deletion.sort((a, b) => b - a) for(let i = 0; i < deletion.length; i++) { console.log("deleting " + rowCharacter[deletion[i]].Discord) await rowCharacter[deletion[i]].delete() console.log("deleted " + rowCharacter[deletion[i]].Discord) }
注:你原代码里的日志单词拼错了,正确拼写是deleting
方法2:批量删除,性能更好
不需要逐行循环调用删除接口,直接用Sheets的批量更新接口一次性删完所有目标行,执行速度更快,也不会有索引错位问题:
// 先把待删除索引从小到大排序,合并连续的行区间 deletion.sort((a, b) => a - b) const deleteRequests = [] let start = deletion[0] let end = deletion[0] for (let i = 1; i < deletion.length; i++) { if (deletion[i] === end + 1) { end = deletion[i] } else { // getRows返回的索引从0开始,Sheets API删除区间为左闭右开 deleteRequests.push({ deleteDimension: { range: { sheetId: this.character.sheetId, dimension: "ROWS", startIndex: start, endIndex: end + 1 } } }) start = deletion[i] end = deletion[i] } } // 补上最后一个区间 deleteRequests.push({ deleteDimension: { range: { sheetId: this.character.sheetId, dimension: "ROWS", startIndex: start, endIndex: end + 1 } } }) // 执行批量删除 await this.character.spreadsheet.batchUpdate({ requests: deleteRequests })
匹配逻辑bug修复
把你原来遍历匹配行的循环调整下,遇到空行、匹配完成、判定待删除时都重置j指针,避免误判:
for(let j = 0; i < rowCharacter.length; j++) { console.log("checking " + rowCharacter[i].Discord) if(rowCharacter[i]?.Discord == undefined) { i++ j = -1 // 重置j,下轮循环从0开始匹配 continue } if(j >= discordtag.length) { // 所有标签都没匹配到,标记为退休 console.log(rowCharacter[i].Discord) rowCharacter[i].Character = rowCharacter[i].Character + " [retired]" console.log("rows to add " + rowCharacter[i].Character) row.push(rowCharacter[i]) deletion.push(i) i++ j = -1 // 重置j continue } if(discordtag[j] == rowCharacter[i].Discord) { i++ j = -1 // 重置j } }
内容的提问来源于stack exchange,提问作者NewCoderOnTheBlock
相关产品推荐
相关产品推荐

