使用 Google Apps 脚本查找重复行并将其替换为定义范围内的最新数据

Find and replace duplicate rows with the newest data in a defined range using Google Apps Script

Google sheet 使用列 A:M。每天都会将一组新的原始数据(大约 30 行)手动粘贴到 B 列中的下一个可用行。此原始数据包含自前一天以来具有一些更新的列内容的重复行。 C 列包含用于确定重复项的作业编号,A 列包含从 1 到 n 的顺序 ID。

我需要创建一个函数,根据 C 列查找重复行,然后使用 A 列值最大的行覆盖 A 列值最低的数据,以便将作业编号的顺序添加到sheet 一旦有工作就永远不会改变。Image of sheet currently 在图像中;第 4 行的作业 22,484 的截止日期将更新为 22 年 10 月 5 日,并且第 5 行的作业数据将被删除。 对于每天的原始数据,将有 20-25 个重复条目。

使用的最大行数为 5000,因此脚本在必要时可能效率低下。

谢谢!康纳

这里是a link to dummy sheet! (感谢迈克)

解决方案:

function myFunction() {

  const sheet = SpreadsheetApp.getActiveSpreadsheet()
                              .getSheetByName(`YOUR_SHEET`)
  
  let data = sheet.getRange(`B2:M`)
                  .getDisplayValues()
                  .filter(row => row.every(cell => cell.length))

  const duplicates = [...new Set(data.flatMap(i => i[1]))].map(i => data.filter(item => item[1] === i))
                                                          .filter(i => i.length > 1)
                                                          .map(i => i[i.length-1])

  duplicates.forEach(i => {
    const removeRow = data.splice(data.findIndex(item => item === i), 1)
    data[data.findIndex(item => item[1] === i[1])] = removeRow.flat()
  })

  sheet.getRange(`B2:M`).clear()
  sheet.getRange(2, 2, data.length, data[0].length).setValues(data)

}

这将获取 table 数据的所有 non-empty 行,查找重复项,并用新数据替换以前的(旧)条目。

让我知道这是否适合您!

评论:

function myFunction() {

  const sheet = SpreadsheetApp.getActiveSpreadsheet()
                              .getSheetByName(`YOUR_SHEET`)

  // Get the target range..
  let data = sheet.getRange(`B2:M`)
                  // As text.. (Avoids date issues)
                  .getDisplayValues() 
                  // ...and ignore blank rows.
                  .filter(row => row.every(cell => cell.length))

  // Get all unique `Job No`'s and replace their value in this array with the relevant rows from 'data'...
  const duplicates = [...new Set(data.flatMap(i => i[1]))].map(i => data.filter(item => item[1] === i))
                                                          // Keep all `Job No`'s rows with more than 1 entry..
                                                          .filter(i => i.length > 1)
                                                          // ...And keep only the most recent.
                                                          .map(i => i[i.length-1])

  // For each of these duplicates..
  duplicates.forEach(i => {
    // Remove the 'new' row..
    const removeRow = data.splice(data.findIndex(item => item === i), 1)
    // Replace the 'old' row..
    data[data.findIndex(item => item[1] === i[1])] = removeRow.flat()
  })

  sheet.getRange(`B2:M`).clear()
  sheet.getRange(2, 2, data.length, data[0].length).setValues(data)

}

删除重复项

function removeDupsOnColC() {
  const ss = SpreadsheetApp.getActive();
  const sh = ss.getSheetByName(`DEBUG`)
  let data = sh.getRange(`B2:M` + sh.getLastRow()).getDisplayValues();
  let ua = [];
  let oA = [];
  data.forEach((r,i) => {
    if(!~ua.indexOf(r[2])) {
      ua.push(r[2]);
      oA.push(r);
    }
  })
  sh.getRange(2, 2, oa.length, oa[0].length).setValues(oa)
}