Есть ли способ повторно использовать logi c, который добавляет строку на лист при обходе столбца значений? - PullRequest
2 голосов
/ 13 июля 2020

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

Затем они нажимают кнопку сохранения вверху, которая переносит данные в другую таблицу, в которой хранятся их данные о тренировках.

На главной странице, которую заполняют спортсмены, есть 4 раздела, в каждой из которых по 10 строк с раскрывающимися списками для настройки различных тренировок.

У меня есть работающий код , но будет очень длинным. Ниже приведен код. В настоящее время у меня должно быть 10 партий указанного кода (2 перечисленных) для каждой из 4 областей обучения. Это означает 250 строк в разделе, то есть 1000 строк для всего кода.

Видно, что я просто меняю оператор if на одну строку вниз за раз, а затем все входные диапазоны меняются соответственно, есть ли способ сократить этот код до конца?

//Input values for routines data row 1
var routinesTRPDMT = inputS.getRange("A29").getValues(); 
if (routinesTRPDMT == "TRP"){
var routines = [[inputS.getRange("R1").getValue(),//DAY
inputS.getRange("V1").getValue(),//DATE
inputS.getRange("Z1").getValue(),//MONTH
inputS.getRange("AD1").getValue(),//SESSION
inputS.getRange("B29").getValue(),//ROUTINE
inputS.getRange("D29").getValue(),//SECTION
inputS.getRange("F29").getValue(),//REPS
inputS.getRange("J29").getValue(),//ATTEMPT 1
inputS.getRange("L29").getValue(),//ATTEMPT 2
inputS.getRange("N29").getValue(),//ATTEMPT 3
inputS.getRange("P29").getValue(),//ATTEMPT 4
inputS.getRange("R29").getValue(),//ATTEMPT 5
inputS.getRange("T29").getValue(),//ATTEMPT 6
inputS.getRange("V29").getValue(),//ATTEMPT 7
inputS.getRange("X29").getValue(),//ATTEMPT 8
inputS.getRange("Z29").getValue(),//ATTEMPT 9
inputS.getRange("AB29").getValue(),//ATTEMPT 10
inputS.getRange("AD29").getValue(),//ATTEMPT 11
inputS.getRange("AF29").getValue(),//ATTEMPT 12
dtCurrentTime]];
              
routinesS.getRange(routinesS.getLastRow()+1, 1, 1, 20).setValues(routines);
               
}   

//Input values for routines data row 2
var routinesTRPDMT = inputS.getRange("A30").getValues(); 
if (routinesTRPDMT == "TRP"){
var routines = [[inputS.getRange("R1").getValue(),//DAY
inputS.getRange("V1").getValue(),//DATE
inputS.getRange("Z1").getValue(),//MONTH
inputS.getRange("AD1").getValue(),//SESSION
inputS.getRange("B30").getValue(),//ROUTINE
inputS.getRange("D30").getValue(),//SECTION
inputS.getRange("F30").getValue(),//REPS
inputS.getRange("J30").getValue(),//ATTEMPT 1
inputS.getRange("L30").getValue(),//ATTEMPT 2
inputS.getRange("N30").getValue(),//ATTEMPT 3
inputS.getRange("P30").getValue(),//ATTEMPT 4
inputS.getRange("R30").getValue(),//ATTEMPT 5
inputS.getRange("T30").getValue(),//ATTEMPT 6
inputS.getRange("V30").getValue(),//ATTEMPT 7
inputS.getRange("X30").getValue(),//ATTEMPT 8
inputS.getRange("Z30").getValue(),//ATTEMPT 9
inputS.getRange("AB30").getValue(),//ATTEMPT 10
inputS.getRange("AD30").getValue(),//ATTEMPT 11
inputS.getRange("AF30").getValue(),//ATTEMPT 12
dtCurrentTime]];
              
routinesS.getRange(routinesS.getLastRow()+1, 1, 1, 20).setValues(routines);
               
}                     

структура листа

Ответы [ 2 ]

2 голосов
/ 14 июля 2020

Рассматривайте свой код не как набор инструкций и больше как алогритм. В вашем случае для достижения цели предпринимаются следующие шаги:

  1. Обход столбца A, для каждой [ ячейки ] выполните:

    1. Если [ значение ячейки ] равно "TRP", то:

      1. Получить 4 значения из строки 1, столбцов «R», «V». "," Z "," AD "
      2. Получить 15 значений из строки в [ строке, соответствующей ячейке ]
      3. Объединить 1 и 2 в строку, добавить метку времени и добавить к [ лист ]

Вы могли заметить, что:

  1. Шаг 1 в условии имеет постоянные значения, поэтому его можно повторно использовать из l oop
  2. «ячейка» и «соответствующая строка», изменяющиеся на каждой итерации, поэтому они могут стать параметрами

Коллекции элементов просматриваются с помощью l oop, повторное использование кода достигается с помощью функций .

Ниже приведена служебная функция для сопоставления начальных данных с желаемым выходом. Вы можете использовать его в al oop для обхода значений столбца «A: A», полученных с помощью getValues() (вам не нужно каждый раз получать одно значение ячейки, просто расширьте диапазон). Как вы хотите, чтобы это было связано с вами:

const mapRoutine = (rowIdx, constants, rows, callback) => {
  const row = rows[rowIdx];  

  const [ 
    , routine ,, section ,, reps ,,,, 
    a1 ,, a2 ,, a3 ,, a4 , ...restAttempts
  ] = row;
  
  //skip odd indices columns starting from attempt 1 (i.e. !(0 % 2) = !0 => true )
  const attempts5to12 = restAttempts.filter((a,i) => !(i % 2));

  const values = [ routine,section,reps,a1,a2,a3,a4, ...attempts5to12 ];
  
  callback([ 
    ...constants.slice(0,-1), 
    ...values, 
    ...constants.slice(-1) 
  ]);
}

//testing:

const rowIndex = 0;
const constants = [1,2,3,4,5];
const firstRow = [,"R",,"S",,"RP",,,,"1",,"2",,"3",,"4","5",,"6",,"7",,"8",,"9",,"10",,"11",,"12"];

mapRoutine(
  rowIndex, 
  constants,
  [ firstRow ], 
  console.log 
);

подпись приведенной выше утилиты проста, за исключением последнего параметра, который является функцией - поскольку функции в JavaScript являются первоклассными объекты и, следовательно, могут передаваться как параметры, как и любой другой объект.

В вашем случае callback может выглядеть примерно так (обратите внимание на currying в последней строке) :

const sheet = //get sheet somehow;
const appendRow = (sheet) => (row) => sheet.appendRow(row);
const curriedAppend = appendRow(sheet); //still a function

Вам необходимо включить более новую среду выполнения V8 , чтобы вышеперечисленное работало

1 голос
/ 14 июля 2020

Кажется, у вас есть довольно уникальный набор случаев и то, как ваша электронная таблица может быть настроена немного проще, чтобы делать то, что я собираюсь предложить, но это значительно сократит ваш код:

var date = inputS.getRange("V1").getValue(),//DATE
var month = inputS.getRange("Z1").getValue(),//MONTH
var session = inputS.getRange("AD1").getValue(),//SESSION
var routines = inputS.getRange(29,1,10,32).getValues(); //get the whole range

for (var i = 0; i< routines.length; i++) {
  var row = routines[i];
  
  if(row[0] == 'TRP') {
  var array = [date,month,session];
  for (var j = 0; j< row.length; j++) {
        if(j == 6) {
            j = j + 3; //because there are 3 blank columns
        } else if (j >9) {
            j++; //because every other cell is hidden past column J
        }
        array.push(row[j])
     }
  routineS.appendRow(array)
  }
}
...