оптимизация гугл скрипта - доступ к 25 таблицам - PullRequest
1 голос
/ 27 июня 2019

Я работаю над некоторыми электронными таблицами (25 из них), каждая из которых предназначена для одного сотрудника и имеет 12 листов, по одному на месяц.Иногда, увы, все электронные таблицы нуждаются в некоторых изменениях.Теперь им нужно внести некоторые изменения в форматирование.И скрипт ниже работает.Но это очень медленно. Можете ли вы помочь мне с оптимизацией? Я думаю, что основной областью оптимизации должен быть переход к определенным ячейкам для создания границ.Я понятия не имею, что я могу сделать, чтобы сделать это быстрее.

Второе, что касается оптимизации, заключается в том, что этот скрипт работает для 4 электронных таблиц - если я дам все 25 электронных таблиц одновременно, он заканчивается в середине 5-го числа.

 function format() {

//list of spreadsheetIDs, I have 25 of them, each one is a summary for one employee
var summary = [
'example1_asdfghjklqwertyuiop',
'example2_asdfghjklqwertyuiop’,
……
……
……
'example24_asdfghjklqwertyuiop’,
'example25_asdfghjklqwertyuiop’
];

//list of sheets in every spreadsheet, they are the same in everyone spreadsheet, month names are here in Polish
var month= ['Styczeń','Luty','Marzec','Kwiecień','Maj','Czerwiec','Lipiec','Sierpień','Wrzesień','Październik','Listopad','Grudzień'];

     for each (ss in summary){
     var s = SpreadsheetApp.openById(ss);
          for each (m in month){
          var sheet = s.getSheetByName(m);
              if (m == 'Styczeń'||m == 'Marzec'||m == 'Maj'||m == 'Lipiec'||m == 'Sierpień'||m == 'Październik'||m == 'Grudzień'){
                   var days = 31; 
              } else if (m == 'Kwiecień'||m == 'Czerwiec'||m == 'Wrzesień'||m == 'Listopad'){
                   days = 30;
              } else {
                   days = 28;
              };

       sheet.getRangeList(['F11:F43', 'K11:K43', 'M11:M43', 'U11:U43', 'AA11:AA43']).setFontColor('#999999');
          for (var i = 1 ; i<=days ; i++){
          //13 row is the first row for 1st January, February…
var cell = sheet.getRange(12 + i, 7);
          //checking if background color of a cell is white (holidays, saturdays and sundays have different backgroung)
         var bg_color = sheet.getRange(12 + i, 7).getBackground();
             if (bg_color == "#ffffff") {
//if a day is weekday then its row needs to have some cells with border
             sheet.getRange(12 + i,  7).setBorder(true, true, true, true, true, true, '#000000', SpreadsheetApp.BorderStyle.SOLID);
             sheet.getRange(12 + i, 12).setBorder(true, true, true, true, true, true, '#000000', SpreadsheetApp.BorderStyle.SOLID);
             sheet.getRange(12 + i, 14).setBorder(true, true, true, true, true, true, '#000000', SpreadsheetApp.BorderStyle.SOLID);
             sheet.getRange(12 + i, 21).setBorder(true, true, true, true, true, true, '#000000', SpreadsheetApp.BorderStyle.SOLID);
             sheet.getRange(12 + i, 27).setBorder(true, true, true, true, true, true, '#000000', SpreadsheetApp.BorderStyle.SOLID);
             //sheet.getRange('A1:AE50').setBorder(false, false, false, false, false, false);
             }
          }
       }
     }
}

1 Ответ

0 голосов
/ 28 июня 2019

У вас есть два способа оптимизации без существенного изменения рабочего процесса.Первый является очень незначительным и удаляет цепочку if-else:

if (m == 'Styczeń'||m == 'Marzec'||m == 'Maj'||m == 'Lipiec'||m == 'Sierpień'||m == 'Październik'||m == 'Grudzień'){
  var days = 31; 
} else if (m == 'Kwiecień'||m == 'Czerwiec'||m == 'Wrzesień'||m == 'Listopad'){
  days = 30;
} else {
  days = 28;
};

становится

var daysFromMonth = {
  'Styczen': 31,
  'Marzec': 31,
  'Maj': 31,
   ...
  'Kwiecien': 30,
   ...
};

и перемещается за пределы цикла над идентификаторами электронных таблиц.Затем, внутри вашего цикла, вы используете его как:

var days = daysFromMonth[m] || 28;

|| 28 будет обрабатывать все случаи, когда значение, возвращаемое при обращении к свойству, имя которого содержится в m, является «ложным» (0, false, null, undefined, ''), в соответствии с вашим else условием.

Главное улучшение, которое необходимо сделать, - это использовать пакетные методы в соответствии с рекомендациями Сценария приложений.Вы уже используете один пакетный метод (RangeList#setFontColor), и вам просто нужно выполнить пакетное чтение (превращение Range#getBackground в Range#getBackgrounds) и выполнить еще несколько пакетных операций (используя RangeList#setBorder вместо Range#setBorder):

Внутри вашего цикла над электронными таблицами, после того, как вы получите количество дней и установите цвет шрифта:

...
sheet.getRangeList(['F11:.......]).setFontColor('#999999');
var start = { row: 13, col: 7 };
var backgrounds = sheet.getRange(start.row, start.col, days, 1).getBackgrounds(); // read all backgrounds at once

Теперь вы можете просмотреть все цвета фона и определить, какие адреса форматировать, используя чистый JS, вместо этогоповторного вызова службы электронных таблиц (очень медленно) между вашими JS (очень быстро).

var rgToBorderize = [];
var colsToInclude = [7, 12, 14, 21, 27];
backgrounds.forEach(function (bgColor, idx) { // idx is 0-based
  if (bgColor === '#ffffff') {
    colsToInclude.forEach(function (col) {
      rgToBorderize.push('R' + (start.row + idx) + 'C' + col);
    });
  }
});
sheet.getRangeList(rgToBorderize).setBorder(/** your border spec here */);

Некоторые ссылки:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...