GoogleScript - ускорение простой цикл - PullRequest
0 голосов
/ 08 января 2020

Я только начал заниматься VBA для Google Sheets и написал скрипт, однако он безумно медленный, это из-за ошибки ниже или есть способ ускорить его?

смысл этого скрипта - иметь 3 рабочих вкладок и одну таблицу для ежедневного сохранения данных. После того, как все VLookUps установлены, я скопирую и вставлю их как значения, но пока l oop слишком медленный, чтобы даже подумать об его использовании.

function autoJ7(){

  var masterSheet= SpreadsheetApp.getActive().getSheetByName('New Accounts Q4');
  var masterLength = masterSheet.getLastRow();
  
  for(var row = 1; row < masterLength; row++){
    
    var rowPath=masterSheet.getRange(row,8).getValue();
    
    if(rowPath<6) {}
    
    else if(rowPath<13) {
    
      masterSheet.getRange(row,16,1,1).activate().setFormula("=vlookup(A"+row+",\'J+7\'!A:M,13,0)");            
      Logger.log("Path A");
    }
    
    
    else if(rowPath<20) {
    masterSheet.getRange(row,17,1,1).activate().setFormula("=vlookup(A"+row+",\'J+14\'!A:M,13,0)");
    Logger.log("Path B");   
    }
    
    else if(rowPath<42) {
      masterSheet.getRange(row,18,1,2).activate().setFormula("=vlookup($A"+row+",\'J+21\'!$A:$M,13,0)");    
      Logger.log("Path C");    
    }
    
  };
  

Ответы [ 2 ]

2 голосов
/ 08 января 2020

Иногда проще использовать прямую запись, потому что вы не хотите возиться с перезаписью формул, которые на самом деле не являются частью процесса. Но эта функция удаляет отдельные операции чтения для каждой переменной rowPath, а также удаляет activates (), которые так часто используются в макросах.

function autoJ7() {
  var ss=SpreadsheetApp.getActive();
  var msh=ss.getSheetByName('New Accoounts Q4');
  var mrg=msh.getRange(1,8,msh.getLastRow(),1);
  var mvA=mrg.getValues();
  mvA.forEach(function(r,i){
    var row=i+1;
    if(r[0]<13) {
      msh.getRange(row,16,1,1).setFormula("=vlookup(A"+row+",\'J+7\'!A:M,13,0)");            
      Logger.log("Path A");
    }else if(r[0]<20){
      msh.getRange(row,17,1,1).setFormula("=vlookup(A"+row+",\'J+14\'!A:M,13,0)");
      Logger.log("Path B");
    }else if(r[0]<42){
      msh.getRange(row,18,1,2).setFormula("=vlookup($A"+row+",\'J+21\'!$A:$M,13,0)");    
      Logger.log("Path C");
    }
  });
}
0 голосов
/ 08 января 2020

Несколько способов ускорить процесс:

  1. Делайте меньше вызовов на листе: a. по возможности получить все данные с листа за один вызов (как здесь) b. отправьте данные или формулы на лист за один вызов.

  2. Если у вас много условий if-else, switch-case может быть быстрее. В этом случае, возможно, нет. Но я нахожу это более элегантным. : -D

Вот как бы я написал скрипт:

function autoJ7() {
  var masterSheet= SpreadsheetApp.getActiveSpreadsheet().getSheetByName('New Accounts Q4');
  var data = masterSheet.getDataRange().getValues(); // Get all the sheet data in one call
  var rowPath, sheetRow; // This avoids defining variables repeatedly inside the loop
  var formulas = []; // Array to hold formulas to be posted back to the Sheet
  for (var row = 0; row < data.length; row++) {
    sheetRow = row + 1; //To adjust for the array being zero-based
    rowPath = data[row][7];
    switch (rowPath) {
      case (rowPath < 6):
        formulas.push(["", "", ""]);
        break;
      case (rowPath < 13):
        formulas.push(["=vlookup(A"+sheetRow+",\'J+7\'!A:M,13,0)", "", ""]);
        break;
      case (rowPath < 20):
        formulas.push(["", "=vlookup(A"+sheetRow+",\'J+14\'!A:M,13,0)", ""]);
        break;
      case (rowPath < 42):
        formulas.push(["", "", "=vlookup($A"+sheetRow+",\'J+21\'!$A:$M,13,0)"]);
    }
  }
  masterSheet.getRange(1, 16, formulas.length, 3).setFormulas(formulas); // Post to sheet in one call
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...