使用应用程序脚本自动完成 - 如果不存在,则将元素添加到数据验证

AUTOCOMPLETE with app script - add element to data validation if not exist

我正在编写一个程序,其中一个功能是创建一个包含一些值的下拉列表(作为自动完成)。但是,如果我给出的值不在下拉列表中,我希望能够将该元素添加到下拉列表中(而不是显示错误消息)。

我花了很多时间试图弄清楚我该怎么做,但我完全被困住了。我认为最好的解决方案是使用数据验证,它除了添加新数据的功能外效果很好。

我也试过在下拉列表中包含一个标记为其他的选项。当我点击它时,我从单元格中删除数据验证,写入值,然后更新包括该值的所有单元格的数据验证。但是,我认为这不是最好的主意,因为它对用户不是很友好。

其他可能的解决方案是每次我写一封信时动态创建下拉列表元素(因为我从数据库中获取信息,我可以从数据库中获取匹配项,然后将它们写入下拉列表).但是,我每次写信都没有找到触发条件。

摘要: 第一列所有单元格中的下拉列表,其中包含数据库中的元素。如果我写的元素不在下拉列表中,将其添加到数据库和所有A单元格的下拉列表中。

如果需要澄清或更多信息,请问我。如果有人能帮助我,我将不胜感激!

我必须在我的项目中完全这样做,所以它基本上是一个复制粘贴。 log() 是我制作的自定义函数,所以不用担心。显然在我的实现中,下拉列表包含一个“标志”列表,但可以根据需要命名。我没有包含创建按钮的代码

/**
 * Function that handles button press to create a new flag
 */
function createFlagInteract(){
  var ui = SpreadsheetApp.getUi();

  //Prompt user for flag name
  var flagName = ui.prompt("Please enter a name for your new flag", ui.ButtonSet.OK).getResponseText();
  log("User's flag name input: \""+flagName+"\"");

  //cancel if entry box is blank
  if(isBlank(flagName)||isEmpty(flagName)){
    ui.alert("No name was entered, please close this dialogue and try again.");
    log("User did not enter a flag name");
    return;
  }

  /**
   * This code block is modified from my implementation. I had a global array with all flags. This is a jerry-rigged simple implementation of getting all values.
   */
  //get an array of existing flags
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("FlagsList");
  const emptyRow = sheet.getLastRow()+1;
  //returns n x 1 array
  var values = sheet.getRange(1,1,emptyRow).getValues();
  //flips array to have length of n
  values = values[0].map((col, i) => values.map(row => row[i]))[0];

  //Check if flag name already exists
  for(var i in values){
    if(values[i]==flagName){
      ui.alert("A flag with this name already exists, please close this dialogue and try again.");
      log("User entered name of flag that already exists.");
      return;
    }
  }

  //Add flag to spreadsheet
  createFlag(flagName);
}

/**
 * Adds flag to spreadsheet and updates dropdown
 * @param {String} flagName Name of flag
 */
function createFlag(flagName){
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("FlagsList");
  const emptyRow = sheet.getLastRow()+1;
  var range = sheet.getRange(emptyRow,1);

  range.setValue(flagName);

  //returns n x 1 array
  var values = sheet.getRange(1,1,emptyRow).getValues();
  //flips array to have length of n
  values = values[0].map((col, i) => values.map(row => row[i]))[0];

  updateDropdown(values);
}

/**
 * Updates dropdown
 */
function updateDropdown(values){
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("User Input");
  var range = sheet.getRange("A:A");

  var rule = SpreadsheetApp.newDataValidation().requireValueInList(values,true).build();

  range.setDataValidation(rule);
}

当数据验证选项应该是动态的时,恕我直言,最好使用范围作为数据验证选项的来源,因为这对电子表格性能的影响小于更新数据验证选项列表通过使用脚本。

  1. 如果您不知道选项可以变成多少位,请将您的数据验证设置为使用整列,即 Options!A:A
  2. On Options!A:A 从数据库中添加数据
  3. 使用编辑触发器添加到选项的第一个空单元格!A:A 新值