简体   繁体   English

将值从一张纸粘贴到另一张纸并删除重复的纸

[英]Paste values from one sheet to another and remove duplicates

I have two worksheets in my google spreadsheet: 我的Google电子表格中有两个工作表:

Input data is coming into the Get Data worksheet via the importxml function. 输入数据通过importxml函数进入“ Get Data工作表。

However, I would like to copy all values of the Get Data sheet to the Final Data sheet and if there are duplicates(in terms of rows) append the unique row. 但是,我想将“ Get Data表的所​​有值复制到“ Final Data表,如果有重复项(就行而言),请追加唯一行。

Here is what I tried: 这是我尝试过的:

function onEdit() {
   //get the data from old Spreadsheet
 var ss = SpreadsheetApp.openById("1bm2ia--F2b0495iTJotp4Kv1QAW-wGUGDUROwM9B-D0");
 var dataRange = ss.getSheetByName("Get Data").getRange(1, 1, ss.getLastRow(), ss.getLastColumn());
 var dataRangeFinalData = ss.getSheetByName("Final Data").getRange(1, 1, ss.getLastRow(), ss.getLastColumn());
 var myData = dataRange.getValues();
 //Open new Spreadsheet & paste the data
newSS = SpreadsheetApp.openById("1bm2ia--F2b0495iTJotp4Kv1QAW-wGUGDUROwM9B-D0");
Logger.log(newSS.getLastRow());

newSS.getSheetByName("Final Data").getRange(newSS.getLastRow()+1, 1, ss.getLastRow(), ss.getLastColumn()).setValues(myData);
//remove duplicates in the new sheet
removeDups(dataRangeFinalData)
}

function getId() {
  Browser.msgBox('Spreadsheet key: ' + SpreadsheetApp.getActiveSpreadsheet().getId());
}

function removeDups(array) {
  var outArray = [];
  array.sort(lowerCase);
  function lowerCase(a,b){
    return a.toLowerCase()>b.toLowerCase() ? 1 : -1;// sort function that does not "see" letter case
  }
  outArray.push(array[0]);
  for(var n in array){
    Logger.log(outArray[outArray.length-1]+'  =  '+array[n]+' ?');
    if(outArray[outArray.length-1].toLowerCase()!=array[n].toLowerCase()){
      outArray.push(array[n]);
    }
  }
  return outArray;
}

Below you can find the link to a sample spreadsheet: 您可以在下面找到示例电子表格的链接:

Sample Sheet 样本表

My problem is that the data does not get pasted. 我的问题是不会粘贴数据。

I appreciate your replies! 感谢您的答复!

tl;dr: See script at bottom. tl; dr:请参阅底部的脚本。

An onEdit() function is inappropriate for your use case, as cell contents modified by spreadsheet functions are not considered "edit" events. onEdit()函数不适合您的用例,因为由电子表格函数修改的单元格内容不视为“编辑”事件。 You can read more about that in this answer . 您可以在此答案中了解更多有关该内容的信息。 If you want this to be automated, then a timed trigger function would be appropriate. 如果您希望将其自动化,那么定时触发功能将是适当的。 Alternatively, you could manually invoke the function by a menu item, say. 或者,您可以通过菜单项手动调用该功能。 I'll leave that to you to decide, as the real meat of your problem is how to ensure row-level uniqueness in your final data set. 我将由您决定,因为问题的实质是如何确保最终数据集中的行级唯一性。

Merging unique rows 合并唯一行

Although your original code is incomplete, it appears you were intending to first remove duplicates from the source data, utilizing case-insensitive string comparisons. 尽管原始代码不完整,但您似乎打算首先使用不区分大小写的字符串比较从源数据中删除重复项。 I'll suggest instead that some other JavaScript magic would help here. 我会建议其他JavaScript魔术在这里有所帮助。

We're interested in uniqueness in our destination data, so we need to have a way to compare new rows to what we already have. 我们对目标数据的唯一性感兴趣,因此我们需要一种将新行与已有行进行比较的方法。 If we had arrays of strings or numbers, then we could just use the techniques in How to merge two arrays in Javascript and de-duplicate items . 如果我们有字符串或数字数组,那么我们可以使用如何在Javascript中合并两个数组并删除重复项中的技术 However, there's a complication here, because we have an array of arrays, and arrays cannot be directly compared. 但是,这里有一个复杂问题,因为我们有一个数组数组,并且数组不能直接比较。

Hash 哈希

Fine - we could still compare rows element-by-element, which would require a simple loop over all columns in the rows we were comparing. 很好-我们仍然可以逐个元素比较行,这将需要一个简单的循环遍历正在比较的行中的所有列。 Simple, but slow, what we would call an O(n 2 ) solution (Order n-squared). 简单但缓慢,我们称之为O(n 2 )解 (阶数为n平方)。 As the number of rows to compare increased, the number of unique comparison operations would increase exponentially. 随着要比较的行数增加,唯一比较操作数将成倍增加。 So, let's not do that. 所以,我们不要那样做。

Instead, we'll create a separate data structure that mirrors our destination data but is very efficient for comparisons, a hash . 相反,我们将创建一个单独的数据结构,该结构镜像我们的目标数据,但对于比较非常有效,即hash

In JavaScript we can quickly access the properties of an object by their name, or key. 在JavaScript中,我们可以通过名称或键快速访问对象的属性。 Further, that key can be any string. 此外,该键可以是任何字符串。 We can create a simple hash table then, with an object whose properties are named using strings generated from the rows of our destination data. 然后,我们可以创建一个简单的哈希表,其中包含一个对象,该对象的属性使用从目标数据行生成的字符串命名。 For example, this would create a hash object, then add the array row to it: 例如,这将创建一个哈希对象,然后向其添加数组row

var destHash = {};
destHash[row.join('')] = true; // could be anything

To create our key, we're join ing all the values in the row array with no separator. 要创建键,我们将不带分隔符的row数组中的所有值join在一起。 Now, to test for uniqueness of a row, we just check for existence of an object property with an identically-formed key. 现在,要测试一行的唯一性,我们只需检查具有相同格式键的对象属性是否存在。 Like this: 像这样:

var alreadyExists = destHash.hasOwnProperty(row.join(''));

One additional consideration: since the source data can conceivably contain duplicate rows that aren't yet in the destination data, we need to continuously expand the hash table as unique rows are identified. 另一个注意事项:由于源数据可以包含目标数据中尚未存在的重复行,因此我们需要在标识唯一行时不断扩展哈希表。

Filter & Concatenate 筛选并连接

JavaScript provides two built-in array methods that we'll use to filter out known rows, and concatenate only unique rows to our destination data. JavaScript提供了两个内置的数组方法,我们将使用它们过滤掉已知行,并将唯一的行连接到目标数据。

In its simple form, that would look like this: 用它的简单形式,看起来像这样:

// Concatentate source rows to dest rows if they satisfy a uniqueness filter
var mergedData = destData.concat(sourceData.filter(function (row) {
  // Return true if given row is unique
}));

You can read that as "create an array named mergedData that consists of the current contents of the array named destData , with filtered rows of the sourceData array concatenated to it." 您可以将其读为“创建一个名为mergedData的数组,该数组由名为destData的数组的当前内容组成,并将sourceData数组的过滤后的行连接在一起。”

You'll find in the final function that it's a little more complex due to the other considerations already mentioned. 由于已经提到的其他注意事项,在最终功能中您会发现它稍微复杂一些。

Update spreadsheet 更新电子表格

Once we have our mergedData array, it just needs to be written into the destination Sheet. 一旦有了mergedData数组,只需将其写入目标工作表即可。

Padding rows: The source data contains rows of inconsistent width, which will be a problem when calling setValues() , which expects all rows to be squared off. 填充行:源数据包含宽度不一致的行,这在调用setValues()时会出现问题,因为setValues()期望所有行都被平方。 This will require that we examine and pad rows to avoid this sort of error: 这将要求我们检查并填充行,以避免此类错误:

Incorrect range width, was 6 but should be 5 (line ?, file "Code") 范围宽度不正确,为6,但应为5(第?行,“代码”文件)

Padding rows is done by push ing blank "cells" at the end of the row array until it reaches the intended length. 通过push空白“单元格” push行数组的末尾直到达到预期的长度来完成填充行。

for (var col=mergedData[row].length; col<mergedWidth; col++)
  mergedData[row].push('');

With that taken care of for each row, we're finally ready to write out the result. 完成每一行的处理后,我们终于可以写出结果了。

Final script 最终脚本

function appendUniqueRows() {
  var ss = SpreadsheetApp.getActive();
  var sourceSheet = ss.getSheetByName('Get Data');
  var destSheet = ss.getSheetByName('Final Data');

  var sourceData = sourceSheet.getDataRange().getValues();
  var destData = destSheet.getDataRange().getValues();

  // Check whether destination sheet is empty
  if (destData.length === 1 && "" === destData[0].join('')) {
    // Empty, so ignore the phantom row
    destData = [];
  }

  // Generate hash for comparisons
  var destHash = {};
  destData.forEach(function(row) {
    destHash[row.join('')] = true; // could be anything
  });

  // Concatentate source rows to dest rows if they satisfy a uniqueness filter
  var mergedData = destData.concat(sourceData.filter(function (row) {
    var hashedRow = row.join('');
    if (!destHash.hasOwnProperty(hashedRow)) {
      // This row is unique
      destHash[hashedRow] = true;   // Add to hash for future comparisons
      return true;                  // filter -> true
    }
    return false;                   // not unique, filter -> false
  }));

  // Check whether two data sets were the same width
  var sourceWidth = (sourceData.length > 0) ? sourceData[0].length : 0;
  var destWidth = (destData.length > 0) ? destData[0].length : 0;
  if (sourceWidth !== destWidth) {
    // Pad out all columns for the new row
    var mergedWidth = Math.max(sourceWidth,destWidth);
    for (var row=0; row<mergedData.length; row++) {
      for (var col=mergedData[row].length; col<mergedWidth; col++)
        mergedData[row].push('');
    }
  }

  // Write merged data to destination sheet
  destSheet.getRange(1, 1, mergedData.length, mergedData[0].length)
           .setValues(mergedData);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 将值从一个Google表格粘贴到另一个,然后根据ID列删除重复项 - Paste values from one Google Sheet to another and remove duplicates based on ID column 如何将值从一张纸粘贴到另一张纸到特定列的最后一行 - How to paste values from one sheet to another to last row of specific column 如何使用 Google Sheets Macros 从一张工作表复制值并将它们粘贴到另一张工作表中? - How to copy values from one sheet and paste them into another using Google Sheets Macros? 将背景颜色从一列复制/粘贴到具有匹配值的列中的另一张工作表 - Copy / paste background color from one column to another sheet in a column with matched values 如何使用 Google 脚本从 1 个 Google 工作表中复制特定值并粘贴到另一个工作表? - How can I copy specific values from 1 Google Sheet and paste to another Sheet using Google Script? 复制单元格中的值并将值粘贴到同一工作表中的另一个单元格 - Copy values from cell and paste the values onto another cell in the same sheet Google Sheet App Script:将 1 个值从一张纸匹配到另一张纸,然后如果条件满足设置背景 - Google Sheet App Script: Match 1 values from one sheet to another sheet and then if condition met set background Google电子表格将值从一行复制到另一张工作表 - Google spreadsheet copy values from one row to another sheet 根据条件将单元格值从一个Google工作表复制到另一个 - Copy cell values from one google sheet to another based on condition 在另一个JQuery的一个列表框中删除重复项 - Remove duplicates in one list box in another JQuery
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM