从电子表格中的一列生成所有非唯一值

时间:2014-10-01 13:51:47

标签: google-apps-script google-sheets unique-values

我有这种形式的电子表格

 A
ABC
DEF
GHI
FOO
BAR
BAZ
ABC

当然,桌子要长得多。

我想插入更多值,但我想首先验证它们的唯一性。 换句话说,每当我插入表中已存在的值时,我希望电子表格通知我。

我还想知道是否有办法从表单窗口向表单窗口插入数据,当我尝试插入非唯一值时,表单窗口将通知并且不会插入我的数据。

提前致谢

2 个答案:

答案 0 :(得分:0)

如果您将数据作为数组返回,则可以使用JavaScript indexOf()方法检查现有值。

  • 从电子表格中获取数据
  • 使用要写入的值来检查现有值
  • 如果存在值,请通知您。

获取数据

Google Documentation - Get Values

// The code below will get the values for the range C2:G8
// in the active spreadsheet.  Note that this will be a javascript array.
var values = SpreadsheetApp.getActiveSheet().getRange(2, 3, 6, 4).getValues();
Logger.log(values[0][0]);

检查重复:

var returnFromIndexOf = values.indexOf(valueToChk);

通知你:

if (values.indexOf(valueToChk) != -1) {
  //Send me an email
// Send an email with two attachments: a file from Google Drive (as a PDF) and an HTML file.
 var file = DriveApp.getFileById('1234567890abcdefghijklmnopqrstuvwxyz');
 var blob = Utilities.newBlob('Insert any HTML content here', 'text/html', 'my_document.html');
 MailApp.sendEmail('mike@example.com', 'Attachment example', 'Two files are attached.', {
     name: 'Automatic Emailer Script',
     attachments: [file.getAs(MimeType.PDF), blob]
 });
};

Google Documentation - Send Email

您需要将Google表单安装到Google云端硬盘才能创建新表单。

Google Site - Google Forms

提交表单时,有一些方法可以运行一些代码。您可以在提交表单时从电子表格或附加到电子表格的表单中运行事件。

在“应用程序脚本代码”编辑器中,打开资源菜单并添加触发器以运行提交表单的函数。

答案 1 :(得分:0)

  

我想插入更多值,但我想验证它们的唯一性   第一。换句话说,每当我插入一个已存在的值时   在表格中我希望电子表格通知我。

如果您的意思是直接在工作表中输入值,并且想要在单元格中输入/编辑数据时执行唯一性检查,那么您有2种方法可以执行此操作:

  1. 使用数据验证

    如果您想要具有唯一值的列是A列,请通过单击其标题选择整个列,选择菜单 Data-> Validation ... ,然后在下标准选择“自定义公式为”选项并输入以下公式:

    =IF(ROW(A1)=1, ISNA(MATCH(A1, $A$2:$A, 0)), IF(ROW(A1)=ROWS($A:$A), ISNA(MATCH(A1, INDIRECT("$A$1:$A$"&(ROWS($A:$A)-1)), 0)), AND(ISNA(MATCH(A1, INDIRECT("$A$1:$A$"&(ROW(A1)-1)), 0)), ISNA(MATCH(A1, INDIRECT("$A$"&(ROW(A1)+1)&":$A"), 0)))))
    

    这将检查您为A列中的所有其他值输入的值,以确保它是唯一的。现有的非唯一单元格会在其中插入注释,通知您该值是非唯一的。如果您的唯一列不是A列,请相应地编辑公式。

  2. 使用onEdit()触发器。您可以向工作表添加onEdit()触发器,如下图所示,它将检查已编辑的单元格,如果编辑的值对列不唯一,则提醒您,并删除它们。 [ UPDATE 2014-10-05:代码已经重新编写,可以正确处理粘贴值,甚至是多列粘贴。将columnToCheck变量值更改为要监视的唯一性列。有关更多详细信息,请参阅代码中的注释。]

    function onEdit(e) {
      var r = e.range; // reference to edited range of cells
      var columnToCheck = 2; // which column should be monitored for uniqueness? 1=A, 2=B, ... Change as necessary.
      var isMultiColRange = (r.getNumColumns()>1); // check if edited range has single column or multiple columns
      if (isMultiColRange) {
        // if range has multiple columns, check that it includes our monitored column
        var monitoredColumnIsInRange = 0;
        for ( var i=1; i<=r.getNumColumns(); ++i) {
          if (r.getCell(1, i).getColumn()==columnToCheck) {
            monitoredColumnIsInRange = i;
            break;
          }
        }
      }
      else {
        // if edited range is single column, check that that is the monitored column
        var monitoredColumnIsInRange = (r.getColumn()==columnToCheck) ? 1 : 0;
      }
      if (monitoredColumnIsInRange) { // only proceed if monitored column was edited
        var monitoredColValues = r.getValues().map(function(el){return el[monitoredColumnIsInRange-1];}); // store edited/pasted values of monitored column in array
        if (monitoredColValues.join("")!="") { // only proceed if non-blank values were entered
          var ss = SpreadsheetApp.getActiveSheet(),
              numRows = ss.getMaxRows(),
              rangeFirstRow = r.getRow(), 
              rangeLastRow = rangeFirstRow+r.getNumRows()-1;
          var values; // will hold an array of current monitored column values
          // get all values in monitored column except currently edited cell's value
          if ( rangeFirstRow==1 ) { // data was entered/edited/pasted into first row in monitored column
            values = ss.getRange(rangeLastRow+1, columnToCheck, numRows-rangeLastRow).getValues();
          }
          else if (rangeLastRow==numRows) { // data was entered/edited/pasted into the last cell in monitored column
            values = ss.getRange(1, columnToCheck, numRows-r.getNumRows()).getValues();
          }
          else { // data was entered/edited/pasted into some other cell in monitored column
            values = ss.getRange(1, columnToCheck, rangeFirstRow-1).getValues().concat(ss.getRange(rangeLastRow+1, columnToCheck, numRows-rangeLastRow).getValues());
          }
          values = values.join().split(","); // convert current values of monitored column into a 1-D array
          var arrDuplicates = []; // will hold non-unique edited/pasted values for alert prompt
          // loop over edited/pasted values and check each for uniqueness
          for ( var j=0, lenEditedValues=monitoredColValues.length; j<lenEditedValues; j++ ) {
            var val = monitoredColValues[j].toString(); // need .toString(), otherwise numbers become decimal values, which 
            if ( values.indexOf(val)>-1 ) { // this value is NOT unique
              arrDuplicates.push(val); // save it in arrDuplicates for reporting
              r.getCell(j+1, monitoredColumnIsInRange).clear(); // clear the cell value
            }
            else { // this value is unique => add it to values array so that it is used in further uniqueness checks (to prevent pasting multiple same values) 
              values.push(val);
            }
          }
          if ( arrDuplicates.length ) {
            SpreadsheetApp.getUi().alert("You entered "+arrDuplicates.length+" values ("+arrDuplicates.join(', ')+") that are NOT unique to the column.\nThese values will be removed.");
          }
        }
      }
    };
    
  3. 以上是一个例子 - 适应您自己的需要。

      

    我还想知道是否有办法将数据插入到   表格窗口中的电子表格将通知并且不会插入   我尝试插入非唯一值时的数据。

    这绝对是可能的。您可以使用HTMLService创建和发布webapp,例如,使用HTML表单允许您输入数据,检查其唯一性,如果一切正常则将其插入电子表格,或者如果数据不唯一则显示错误。 Sandy Good在他的回答中给了你一些起点。