【问题标题】:Find unique ID, copy and paste rows to new tab and merge certain rows together if ID is duplicate查找唯一 ID,将行复制并粘贴到新选项卡,如果 ID 重复,则将某些行合并在一起
【发布时间】:2021-03-12 08:26:50
【问题描述】:

我是 GAS 新手,对 Javascript 有一点了解

我正在尝试读取 ID 列表(“出站”表中的 A 列)并将 ID 粘贴到新的“临时”表(A 列),如果 ID 重复,则仅显示一次 ID,我的这部分代码是工作正常。

接下来,如果 ID 匹配,我想将数据行从“出站”表复制到新的“临时”表,但如果 ID 重复,则它将合并列 E:K。 我没有进入合并部分,因为我的代码在查看 ID 并粘贴相关行时不起作用。

链接到 Google 表格和脚本:Click Here

这是我到目前为止的代码,我很欣赏没有使用一些变量/代码行,因为我一直在玩我的代码,并且可能有一些方法可以加快速度。

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

非常感谢任何帮助。

【问题讨论】:

  • 很遗憾,我无法打开您的示例电子表格。可以再确认一下吗?
  • @您链接的 Google 表格是否尚未公开,没有人可以访问它。
  • 抱歉,它已链接到我的工作帐户,无法授权外部用户。我已将副本复制到我的个人帐户并更新了链接。它现在应该可以工作了。 @Tanaike
  • @iansedano 链接已修复

标签: arrays google-apps-script google-sheets merge copy-paste


【解决方案1】:

修改后的脚本

我的处理方式与你的脚本有点不同。

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 工作表上输出:

脚本的工作原理

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

'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,对于第一遍,它只是复制所有信息,包括姓名和姓氏等。

下一阶段涉及遍历每个条目并合并需要合并的标题 通过将结果与换行符\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",
]

评论

我相信这个脚本和你的主要区别在于它在内存中做所有事情。也就是说,它获取所有数据,然后再也不会调用getRangegetValues。只有在最后它才使用getRange 只是为了输出到工作表。

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

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

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

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2016-11-18
  • 2018-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多