В форме мне нужно заполнить содержимое одного и того же столбца электронной таблицы примерно 50 раз.Есть ли способ написать эту логику с меньшим количеством итераций - PullRequest
1 голос
/ 22 сентября 2019

Я работаю над формой, в которой мне нужно 50 раз извлечь содержимое столбца электронной таблицы, чтобы попытаться ввести несколько элементов из списка.Я вижу, что могу сделать это, определив несколько переменных и снова и снова переделывая небольшой фрагмент скрипта.Я хочу посмотреть, сможет ли кто-нибудь помочь мне преодолеть этот длинный скрипт, чтобы сделать его меньше с меньшим количеством итераций.Спасибо.

function updateForm(){
  // call the form and connect to the drop-down items
  var Form_SQ = FormApp.openById("FORM ID");
  var SQ_IT01_List = Form_SQ.getItemById("ITEM 01").asListItem();
  var SQ_IT02_List = Form_SQ.getItemById("ITEM 02").asListItem();
  //Similarly defining upto 50 dropdown lists.


  var SS01 = SpreadsheetApp.getActive();
  var SQ_IT01_Names = SS01.getSheetByName("Sheet2");
  var SQ_IT02_Names = SS01.getSheetByName("Sheet2");
  //Similarly defining upto 50 names lists.


  // Item_01 Part Number Dropdown
  var SQ_IT01_Values = SQ_IT01_Names.getRange(2, 1, SQ_IT01_Names.getMaxRows() - 1).getValues();
  var SQ_IT01_Items = [];
  for(var i = 0; i < SQ_IT01_Values.length; i++)
  if(SQ_IT01_Values[i][0] != "")
  SQ_IT01_Items[i] = SQ_IT01_Values[i][0];
  SQ_IT01_List.setChoiceValues(SQ_IT01_Items);

  // Item_02 Part Number Dropdown
var SQ_IT02_Values = SQ_IT01_Names.getRange(2, 1, SQ_IT02_Names.getMaxRows() - 1).getValues();
  var SQ_IT02_Items = [];
  for(var i = 0; i < SQ_IT02_Values.length; i++)
  if(SQ_IT02_Values[i][0] != "")
  SQ_IT02_Items[i] = SQ_IT02_Values[i][0];
  SQ_IT02_List.setChoiceValues(SQ_IT02_Items);

  //Similarly defining upto 50 lookup lists.

}

1 Ответ

2 голосов
/ 23 сентября 2019

Проблема

Повторное использование кода и использование циклов.Сценарии основаны на эффективности (см. Принцип DRY ): делайте как можно меньше назначений и кодирование с одинаковой функциональностью - используйте циклы, перемещайте фрагменты кода многократного использования в функции, которые можно вызывать по требованию и т. Д.

Решение

Этот образец делает несколько предположений:

  1. SQ_IT01_Names отличается для каждого элемента (в вашем примере это всегда Sheet2 -если это так, вам не нужно переназначать его 50 раз, одно присвоение переменной будет вполне нормальным).
  2. Вы намеревались что-то сделать, когда значение является пустой строкой (образец просто фильтрует ихвне).Поскольку вы используете нотацию [index], эти значения в результирующем Array будут undefined (и это не то, что нужно при Array выбранных значениях).
  3. Все элементы по выборуэлементы (если вам нужна фильтрация id, образец легко расширяется).

function updateForm() {
  var form = FormApp.openById("FORM ID");

  //access every item;
  var items = form.getItems();

  var ss = SpreadsheetApp.getActive();

  //loop over items;
  items.forEach(function(item,i){
    var namesSheet = ss.getSheetByName('Sheet'+i); //assuming this is diff each time;
    var namesRange = namesSheet.getRange(2,1,namesSheet.getLastRow());
    var namesValues = namesRange.getValues();

    //map values to first column;
    namesValues = namesValues.map(function(value){
      return value[0];
    });

    //filter out undefined (undefined and false functional equivalence);
    namesValues = namesValues.filter(function(value){
      return value;
    });

    item.asListItem().setChoiceValues(namesValues);
  });
}

Примечания

  1. Пожалуйстаиспользуйте замыкания {} с циклами и операторами if, таким образом вы сможете отслеживать, какие операторы заключены в нем, и сэкономить время отладки при циклическом выполнении / подготовке нескольких операторов.
  2. Посколькувам нужны только строки, в которых есть данные, используйте метод getLastRow() вместо getMaxRows()-1 calc, который вы должны выполнить в своем скрипте.

Ссылка

  1. forEach() метод ссылка ;
  2. filter() метод ссылка ;
  3. map() метод ссылка;
  4. getLastRow() метод ссылка ;
...