Оптимизация функции Google Scripts - Поиск последней строки - PullRequest
1 голос
/ 20 января 2020

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

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

У меня есть функциональность на месте, но я беспокоюсь, что, как только мой лист дойдет до ста или нескольких сотен строк, это Функция будет работать очень медленно столбцов, а не только последняя строка на всем листе.

Код ниже:

function moveDoneTask()
{

 var ss = SpreadsheetApp.getActiveSpreadsheet();
 var sheet = SpreadsheetApp.getActiveSheet();

 var columnNumberToWatch = 7;
 var range = sheet.getActiveCell();

 var lastRowinProgressColumns; 
 var lastRowinDoneColumns = 0;

 for (var i=1, doneRows=sheet.getRange("K:S").getNumRows(); i<=doneRows; i++) {
    if ( !sheet.getRange(i, 11, 1, 9).isBlank() ) 
    {
      lastRowinDoneColumns = i;
      Logger.log("last done row" +lastRowinDoneColumns);
    }
  }

  for (var j=1, notDoneRows=sheet.getRange("A:I").getNumRows(); j<=notDoneRows; j++) {
    if (!sheet.getRange(j, 1, 1, 9).isBlank()) 
    {
      lastRowinProgressColumns = j;
      Logger.log("last not done row" +lastRowinProgressColumns);
    }
  }

 if (range.getColumn() == columnNumberToWatch && range.isChecked()) 
 {
   Logger.log("is checked");

   targetRange = sheet.getRange(lastRowinDoneColumns + 1, 11)
   cellsToMove = sheet.getRange(range.getRow(), 1, 1, 9)
   belowCellsToMove = cellsToMove.offset(1, 0) //get the row of cells below the cells that are about to be moved
   rangeMovingUp = sheet.getRange("A"+belowCellsToMove.getRow()+":I"+lastRowinProgressColumns)

   Logger.log("row below me is row " + belowCellsToMove.getRow());

   cellsToMove.moveTo(targetRange);
   rangeMovingUp.moveTo(cellsToMove);

 }
}

Спасибо за вашу помощь!

Редактировать 2: Воспользовался советом ниже и сделал некоторые изменения в скрипте, теперь он работает быстрее:

function moveDoneTask()
{
 var sheet = SpreadsheetApp.getActiveSheet(); 
 var columnNumberToWatch = 7;
 var range = sheet.getActiveCell(); 

 if (range.getColumn() == columnNumberToWatch && range.isChecked()) 
 {
   targetRow = (sheet.getRange('M11:S').getNextDataCell(SpreadsheetApp.Direction.DOWN).getRow() + 1);
   targetRange = sheet.getRange(targetRow, 11)
   notDoneRows = sheet.getRange("A:I").getNumRows()
   cellsToMove = sheet.getRange(range.getRow(), 1, 1, 9)
   belowCellsToMove = cellsToMove.offset(1, 0)
   rangeMovingUp = sheet.getRange("A"+belowCellsToMove.getRow()+":I"+notDoneRows)

   cellsToMove.moveTo(targetRange);
   rangeMovingUp.moveTo(cellsToMove);
 }
} 

Ответы [ 2 ]

1 голос
/ 21 января 2020

Новый слегка оптимизированный код:

{
 var ss = SpreadsheetApp.getActiveSpreadsheet();
 var sheet = SpreadsheetApp.getActiveSheet();

 var columnNumberToWatch = 7;
 var range = sheet.getActiveCell();

 var targetRow;
 var lastRowinProgressColumns = 0;

 if (range.getColumn() == columnNumberToWatch && range.isChecked()) 
 {
   targetRow = (sheet.getRange('L3:S').getNextDataCell(SpreadsheetApp.Direction.DOWN).getRow() + 1);
   targetRange = sheet.getRange(targetRow, 11)

     for (var j=1, notDoneRows=sheet.getRange("A:I").getNumRows(); j<=notDoneRows; j++) {
    if (!sheet.getRange(j, 1, 1, 9).isBlank()) 
    {
      lastRowinProgressColumns = j;
      Logger.log("last not done row" +lastRowinProgressColumns);
    }
  }
   cellsToMove = sheet.getRange(range.getRow(), 1, 1, 9)
   belowCellsToMove = cellsToMove.offset(1, 0)
   rangeMovingUp = sheet.getRange("A"+belowCellsToMove.getRow()+":I"+lastRowinProgressColumns)

   cellsToMove.moveTo(targetRange);
   rangeMovingUp.moveTo(cellsToMove);
 }
}
0 голосов
/ 20 января 2020
  • Для получения последней строки определенного столбца можно использовать getNextDataCell (direction) . Это возвращает следующую ячейку на ребре в пустой диапазон (что эквивалентно первой пустой строке, если между ними нет пустых ячеек). Имейте в виду, что есть ошибка документации, правильный синтаксис: var lastRowinProgressColumns=sheet.getRange(1, 11).getNextDataCell(SpreadsheetApp.Direction.DOWN).getRow();
  • Чтобы сделать код более эффективным, сначала проверьте, находится ли активный диапазон в правильном столбце (if (range.getColumn() == columnNumberToWatch && range.isChecked())), и получите lastRowinProgressColumns в выражении if (нет причин извлекать его, если кодировка не выполняется).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...