查找唯一 ID,将行复制并粘贴到新选项卡,如果 ID 重复,则将某些行合并在一起

Find unique ID, copy and paste rows to new tab and merge certain rows together if ID is duplicate

我是 GAS 新手,对 Javascript

了解不多

我正在尝试读取 ID 列表('Outbound' sheet 中的 A 列)并将 ID 粘贴到新的 'temp' sheet(A 列)如果 ID 重复,则显示一次 ID,我的这部分代码工作正常。

接下来,如果 ID 匹配,我想将数据行从 'Outbound' sheet 复制到新的 'temp' sheet,但如果 ID 重复,则它将合并列 E:K。 我还没有进入合并部分,因为我的代码在查看 ID 并粘贴相关行时无法正常工作。

Link 到 Google Sheet 和脚本:Click Here

到目前为止,这是我的代码,感谢一些 variables/lines 代码没有被使用,因为我一直在研究我的代码,可能有一些方法可以加快速度。

var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var newdata = new Array();
var data = ss.getDataRange().getValues();         // get all data
var destSheet = ss.getSheetByName("temp");
var lastRow = sheet.getLastRow();
var lastCol = sheet.getLastColumn();

function main(){
  var data = findUnique();
  sort();
  copyRowData();
}

function findUnique(){
  for(nn in data){
    var duplicate = false;
    for(j in newdata){
      if(data[nn][col] == newdata[j][0]){
        duplicate = true;
      }
    }
    if(!duplicate){
      newdata.push([data[nn][col]]);
    }
  }
  //Logger.log(newdata);
}

function sort(){
  newdata.sort(function(x,y){
    var xp = Number(x[0]);                      // ensure you get numbers
    var yp = Number(y[0]);
    return xp == yp ? 0 : xp < yp ? -1 : 1;     // sort on numeric ascending
  });
  //Logger.log(newdata);

  destSheet.clear();
  destSheet.getRange(1,1,newdata.length,newdata[0].length).setValues(newdata);    // Paste unique HS ID to new tab
}

function copyRowData() {  
  //var sheet = ss.getSheetByName('Outbound'); //source sheet
  var range = sheet.getRange(2,1,lastRow,5).getValues();
  Logger.log(range);
  var destlastRow = destSheet.getLastRow();
  var criteria = destSheet.getRange(1,1,destlastRow).getValues();
  Logger.log(criteria);
  var data1 = [];
  var j =[];
  Logger.log(range.length);

  //Condition to check in A:A, if true, copy the same row to data array 
  for (i=0;i<range.length;i++) {
    for (j=0; j<criteria.length; j++){
      if (range[i] == criteria[j]) {
        data1.push(range[i]);
      }
    }
  }
  Logger.log(data1.length);
  //Copy data array to destination sheet
  destSheet.getRange(2,2,data1.length).setValues(data1);
  //targetrange.setValues(data1)
}  

我正在寻找与此类似的输出,其中 Shaun 和 Kennedy 合并了单元格 E 到 K 中的数据: Click for image of expected outcome

非常感谢任何帮助。

修改脚本

我处理这个问题的方式与您的脚本略有不同。

function main() {
  let file = SpreadsheetApp.getActive();
  let sourceSheet = file.getSheetByName("Outbound");
  let sourceRange = sourceSheet.getDataRange();
  let sourceValues = sourceRange.getValues();

  // Removing header row into its own variable
  let headers = sourceValues.shift();

  //==========================================

  // PHASE 1 - dealing with duplicates

  // Initializing the duplicate checking object
  // Using the ID as the key, objects will not
  // allow duplicate keys.
  let data = {}

  // For each row in the source
  // create another object with a key for each header
  // for each key assign an array with the values
  sourceValues.forEach(row => {
    let rowId = row[0]
    // If the id has already been added
    if (rowId in data) {
      // add the data to the array for each header
      headers.forEach((header, index) => {
        data[rowId][header].push(row[index]);
      })
    } else {
      // create a new object with an array for each header
      // initialize the array with one item
      // the value of the cell
      let entry = {}
      headers.forEach((header, index) => {
        entry[header] = [row[index]];
      })
      data[rowId] = entry
    }
  })

  // PHASE 2 - creating the output

  let output = []
  // You don't want the name to be merged
  // so put the indices of the columns that need to be merged here
  let indicesToMerge = [4,5,6,7,9,10]

  // For each unique id
  for (let id in data) {
    // create a row
    let newRow = []
    // temporary variable of id's content
    let entry = data[id]
    // for each header
    headers.forEach((header, index) => {
      // If this field should be merged
      if (indicesToMerge.includes(index)) {
        // joing all the values with a new line
        let content = entry[header].join("\n")
        // add to the new row
        newRow.push(content)
      } else {
        // if should not be merged
        // take the first value and add to new row
        newRow.push(entry[header][0])
      }
    })
    // add the newly constructed row to the output
    output.push(newRow)
  }

  //==========================================

  // update the target sheet with the output
  let targetSheet = file.getSheetByName("temp");
  let targetRange = targetSheet.getRange(
    2,1,output.length, output[0].length
  )
  targetRange.setValues(output)
}

temp sheet 上输出:

脚本的工作原理

此脚本使用 object 来存储数据,这是脚本第一阶段完成后的示例条目:

'87817': 
{
  ID: [87817, 87817, 87817],
  Name: ["Kennedy", "Kennedy", "Kennedy"],
  Surname: ["FFF", "FFF", "FFF"],
  Shift: ["NIGHTS", "NIGHTS", "NIGHTS"],
  "Area Manager completing initial conversation": ["AM1", "AM1", "AM1"],
  "WC Date ": [
    Sun Nov 29 2020 19:00:00 GMT-0500 (Eastern Standard Time),
    Sun Feb 14 2021 19:00:00 GMT-0500 (Eastern Standard Time),
    Sun Mar 07 2021 19:00:00 GMT-0500 (Eastern Standard Time),
  ],
  "Score ": [0.833, 0.821, 0.835],
  Comments: ["Comment 6", "Comment 10", "Comment 13"],
  "Intial Conversation date": ["Continue to monitor - no action", "", ""],
  "Stage 1 Meeting Date": [
    "N/A",
    Fri Feb 19 2021 19:00:00 GMT-0500 (Eastern Standard Time),
    Mon Mar 29 2021 19:00:00 GMT-0400 (Eastern Daylight Time),
  ],
  "Stage 1 Outcome": ["", "Go to Stage 1", "Stage 2"],
};

如您所见,如果它发现了重复的 ID,在第一遍中,它只是复制所有信息,包括名字和姓氏等。

下一阶段涉及遍历每个条目并合并需要合并的 headers 通过用换行符 \n 连接结果,得到如下一行:

[
  87817,
  "Kennedy",
  "FFF",
  "NIGHTS",
  "AM1\nAM1\nAM1",
  "Sun Nov 29 2020 19:00:00 GMT-0500 (Eastern Standard Time)\nSun Feb 14 2021 19:00:00 GMT-0500 (Eastern Standard Time)\nSun Mar 07 2021 19:00:00 GMT-0500 (Eastern Standard Time)",
  "0.833\n0.821\n0.835",
  "Comment 6\nComment 10\nComment 13",
  "Continue to monitor - no action",
  "N/A\nFri Feb 19 2021 19:00:00 GMT-0500 (Eastern Standard Time)\nMon Mar 29 2021 19:00:00 GMT-0400 (Eastern Daylight Time)",
  "\nGo to Stage 1\nStage 2",
]

评论

我认为此脚本与您的脚本之间的主要区别在于它在内存中执行所有操作。也就是说,它获取 all 数据,然后再也不会调用 getRangegetValues。只有在最后它才使用 getRange 只是为了输出到 sheet.

另一个区别似乎是这个使用 objects 的内置 属性 来识别重复项。 IE。 object 键不能在 object.

中复制

也许这种方法对数据进行两次传递,因为开销很小,否则代码就很难理解。

像这样合并数据可能会变得无穷无尽,因为可以实施许多调整和检查,但这是一个有效的 bare-bones 解决方案,可以帮助您入门。