Google表格-数据验证-从下拉列表中强制唯一性

时间:2019-05-03 09:54:56

标签: google-apps-script google-sheets

我在Google工作表中有一个列,用户需要从下拉列表中选择一个项目列表,但是该列中的每个值都必须是唯一的。

我已经找到了几种方法,但是都没有那么好。

首先,我尝试使用此解决方案-https://infoinspired.com/google-docs/spreadsheet/distinct-values-in-drop-down-list-in-google-sheets/-该解决方案使用查询功能创建一个动态更改的列,数据验证指向该列。它可以工作,但是问题在于,一旦输入值,它就会变得无效并引发看起来不专业的错误。

我还尝试了onEdit函数,该函数通过选项列表不断更新单元格验证:

function onEdit(){
 var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet 1");
 var original = sheet.getRange(7,8,20,1).getValues(); /list of cells for data validation to be added
 var option = new Array();
 dvSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Drop Downs");
 option = dvSheet.getRange('G1:G250').getValues();
 option.push(["dummy"])
 var i
 var dv = SpreadsheetApp.newDataValidation();
 for(i=0;i<20;i++){
    option[250][0] = original[i][0];
    dv.setAllowInvalid(false);  
 // dv.setHelpText("Some help text here");
    dv.requireValueInList(option, true);
    sheet.getRange(i+7,8).setDataValidation(dv.build());
  }
}

'Drop Downs'!G1:G250是从解决方案1生成的列表。代码获取该列表并将单元格的内容添加到该列表中,然后将该列表设置为数据验证。

同样可以,但是更新验证列表会有所延迟,这意味着如果用户足够快,他们可以添加多个相同的值。

我想到的另一种选择是将每个单元格指向由解决方案1组成的唯一列,并将该单元格的内容添加到末尾。但是我不希望为每个单元格创建列,因为会有很多列(超过代码中隐含的20个列)。

很棒的是,如果Google允许您在数据验证中合并范围,那么我可以将解决方案1中的列与当前单元格合并。但据我所知没有。

有人还能想到别的吗?我的感觉是我要么太复杂了,有一个简单的解决方案-要么我太挑剔了。

1 个答案:

答案 0 :(得分:0)

对于将来遇到此问题的任何人:

按照TheMaster的建议,我编写了一个onEdit函数,该函数从完整的单元格中删除验证,并向空单元格中添加验证:

function onEdit(){
    var spreadsheet = SpreadsheetApp.getActive();
  var i
  var j
   var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet 1");
  var original = sheet.getRange(7,8,20,1).getValues();
  var emptyarray = new Array();
  var fullarray = new Array();
  for (i=0;i<20;i++){
    if (original[i][0] === ""){
emptyarray.push(i);
  }
  else {
fullarray.push(i);
  }
}

      for each(i in fullarray){
        j=Number(i)+7
        sheet.getRange('H'+j).clearDataValidations()
      }
        for each(i in emptyarray){
          j=Number(i)+7
          sheet.getRange('\'Sheet 1\'!H'+j).setDataValidation(SpreadsheetApp.newDataValidation()
          .setAllowInvalid(true)
          .requireValueInRange(spreadsheet.getRange('\'Drop Downs\'!$G:$G'), true)
          .build());
      }
}