Метод Range.getValue интенсивно используется скриптом - PullRequest
0 голосов
/ 12 октября 2018

У меня есть скрипт, который работает, но на его завершение уходит очень много времени.У меня есть несколько эффективных копий в различных книгах и листах.Мои знания сценариев ограничены, и я очень рад, что мне удалось заставить это работать вообще.Время выполнения действительно мусор, хотя около 15 минут, и я даже не настроил его, чтобы закончить все необходимые циклы.Совет по лампочке гласит:

Метод Range.getValue активно используется сценарием.Свернуть
Файл: копия учащегося. Строка: 17
В сценарии используется метод, который считается дорогим.Каждый вызов генерирует длительный вызов на удаленный сервер.Это может оказать критическое влияние на время выполнения сценария, особенно для больших данных.Если производительность является проблемой для сценария, вы должны рассмотреть возможность использования другого метода, например Range.getValues ​​().

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

function myFunction() {
  var spreadsheet = SpreadsheetApp.getActive();
  var studentID = spreadsheet.getSheetByName('Sheet11');
  var sourceSheet = spreadsheet.getSheetByName('Sheet6');
  var createLink = spreadsheet.getSheetByName('Sheet14');

  var i ,j, k;

  for( var k = 1; k< 3; k++) {

    // copy studentID
    studentID.getRange(k, 2).copyTo(createLink.getRange(4, 4 ,{contentsOnly: true}));

    for( var i = 1; i< 21; i++) {
      //copy students subject
      var subjectName = sourceSheet.getRange(i+1,7*k-5).getValue();
      if (subjectName =="") {
        break;
      }else {
        createLink.getRange(4, 6).setValue(subjectName)
        //copy row number of reflection
        for (var j = 1; j<31; j++){
          var rownumber = j+5;
          createLink.getRange(4, 8).setValue(rownumber);
          SpreadsheetApp.flush(); 
          //copy link of student reflection into teacher marksheet
          var markSheetID = sourceSheet.getRange(i+1, 7*k-3).getValue();
          var groupNumber = sourceSheet.getRange(i+1,7*k-2).getValue();
          var MarkSheet = SpreadsheetApp.openById(markSheetID).getSheets()[groupNumber-1];
          var linkvalue = createLink.getRange(4, 10).getValue();
          MarkSheet.getRange(2+k, 6*j).setValue(linkvalue);}
      }
    }
  }
}

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

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

Ответы [ 2 ]

0 голосов
/ 13 октября 2018

Трудно сделать это в вакууме без возможности запуска программы с реальными данными.

Не так много изменений.Но если вы можете жить с SpreadsheetApp.flush, это было бы хорошо.Кроме этого, я мог бы заменить только пару getValue () одним getValues ​​().Я только что закомментировал строки, которые я заменил.

  function myFunction() {
  var spreadsheet = SpreadsheetApp.getActive();
  var studentID = spreadsheet.getSheetByName('Sheet11');
  var sourceSheet = spreadsheet.getSheetByName('Sheet6');
  var createLink = spreadsheet.getSheetByName('Sheet14');
  for( var k = 1; k< 3; k++) {
    // copy studentID
    studentID.getRange(k, 2).copyTo(createLink.getRange(4, 4 ,{contentsOnly: true}));
    for( var i = 1; i< 21; i++) {
      //copy students subject
      var subjectName = sourceSheet.getRange(i+1,7*k-5).getValue();
      if (subjectName =="") {
        break;
      }else {
        createLink.getRange(4, 6).setValue(subjectName)
        //copy row number of reflection
        for (var j = 1; j<31; j++){
          var rownumber = j+5;
          createLink.getRange(4, 8).setValue(rownumber);
          //SpreadsheetApp.flush(); 
          //copy link of student reflection into teacher marksheet
          var mgvA=sourceSheet.getRange(i+1, 7*k-3, 1, 2).getValues();
          //var markSheetID = sourceSheet.getRange(i+1, 7*k-3).getValue();
          //var groupNumber = sourceSheet.getRange(i+1,7*k-2).getValue();
          var MarkSheet=SpreadsheetApp.openById(mgvA[0][0]).getSheets()[mgvA[0][1]-1];
          //var MarkSheet = SpreadsheetApp.openById(markSheetID).getSheets()[groupNumber-1];
          var linkvalue = createLink.getRange(4, 10).getValue();
          MarkSheet.getRange(2+k, 6*j).setValue(linkvalue);}
      }
    }
  }
}
0 голосов
/ 12 октября 2018

Весьма вероятно, что системное сообщение было вызвано использованием setValue внутри вложенных циклов for (есть три цикла for), а также наличием SpreasheetApp.flush () внутри вложенных циклов for, что мешает механизму скриптов приложений использовать его.встроенные алгоритмы оптимизации записи.

Старайтесь избегать использования setValue () внутри циклов for.Для этого вы можете использовать массив JavaScript для хранения значений, а затем использовать setValues ​​() для одновременной передачи нескольких значений вместо передачи одно за другим.

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