Использование setvalues ​​с циклом for - PullRequest
1 голос
/ 23 октября 2019

В настоящее время я пытаюсь выполнить действие «copyTo» или «setValues». Мне нужно скопировать одну сетку (Лист1! J16: Q36) в другую сетку (Лист2! J16: Q36), но не каждая ячейка должна быть скопирована. Только те значения, которые не идентичны значениям Sheet1, должны копироваться.

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

Я также использовал третью сетку, которая сравнивала значения sheet1 и 2 и возвращала 1 или 0. Только если показывалось значение 1, ячейка рассматривалась циклом for. Я так понимаю, это неэффективно.

Спасибо за вашу помощь. Я очень ценю это.

 var ratenprogramm = SpreadsheetApp.getActiveSpreadsheet(); 
 var ratenprogrammmain = ratenprogramm.getSheetByName("Ratenprogramm");
 var vorlageratenprogramm = 
 ratenprogramm.getSheetByName("VorlageRatenprogramm");

for(i=1;i<=21;i++)
{
  for(j=1;j<=8;j++)
  {
    if(vorlageratenprogramm.getRange(37+i,9+j).getValue() == 1)
    {
      vorlageratenprogramm.getRange(15+i,9+j).copyTo(ratenprogrammmain.getRange(15+i,9+j),{contentsOnly: true}); 
    }

  }
}

1 Ответ

1 голос
/ 23 октября 2019
  • Как вы заметили, вызов любых внешних служб, включая такие методы, как getValue(), замедляет выполнение сценария, см. Рекомендации по использованию сценариев приложений .

  • Ваш код можно оптимизировать, заменив несколько запросов getValue() на один getValues().

  • В рамках вложенных циклов вы можете указать несколько диапазонов и значений, которые можно записать с помощью Advanced Sheets Service , с помощью метода API Sheets spreadsheets.values.batchUpdate в соответствующие диапазоны листа назначения, см. также здесь .

Образец

function myFunction() {

 var ratenprogramm = SpreadsheetApp.getActiveSpreadsheet(); 
 var ratenprogrammmain = ratenprogramm.getSheetByName("Ratenprogramm");
 var vorlageratenprogramm = ratenprogramm.getSheetByName("VorlageRatenprogramm");
 var data=[];
 var range=vorlageratenprogramm.getRange(15,9,21,8);
 var values=range.getValues();
 for(i=0;i<4;i++)
  {
    for(j=0;j<1;j++)
    {
      if(values[i+1][j] == 1)
       {
        var cell=range.getCell(i+1,j+1).getA1Notation();
        data.push([{ range:'Ratenprogramm!'+ cell, values: [[values[i+1][j]]]}]);
      }
    }
  }
  var resource = {
    valueInputOption: "USER_ENTERED",
    data: data
  };
  Sheets.Spreadsheets.Values.batchUpdate(resource, spreadsheetId);
}

Имейте в виду, что если у вас много разных диапазонов, может быть проще и быстрее перезаписать лист с полным диапазоном, чем использовать циклическое вложение. Например, vorlageratenprogramm.getRange(15,9,21,8).copyTo(ratenprogrammmain.getRange(15,9,21,8),{contentsOnly: true});.

...