Google Sheets onEdit (e) не захватывает несколько изменений - PullRequest
1 голос
/ 28 октября 2019

Функция onEdit (e) в редакторе скриптов Google Sheets записывает изменения только в отдельные ячейки. Есть ли способ сделать так, чтобы он записывал изменения в нескольких ячейках, например, если я копирую информацию в 20 ячеек, может ли onEdit (e) распознать, что было отредактировано 20 ячеек, а не только первая ячейка?

IЯ везде искал решение этой проблемы, и я не могу найти ни одного случая, чтобы кто-то задавал этот вопрос.

function recordChange(c){
  var range = c.range;
  var column = 8; //Column for change log
  var row = range.getRow();
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheets()[0];

  var oldRow = range.getRow();
  var oldColumn = range.getColumn();

  sheet.getRange(oldRow, oldColumn).setBackground("orange");

  var changeCell = sheet.getRange(row, column)
  changeCell.setValue(new Date())

  var testCell = sheet.getRange(2, 2)
  var test = range.getValues();
  var newT = test.map(function(x){ return x});
  testCell.setValue(newT)

}

function recordAction(c){

  var range = c.range;
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheets()[0];
  var row = range.getRow();

  for (var i = 1; i<9; i++){
    sheet.getRange(row, i).setBackground(null);
  }

}

//Main Function
function onEdit(e){

  var range = e.range;
  if (range.getRow() != 1){
    if (range.getColumn() != 9 && range.getColumn() != 8) {recordChange(e);} else {recordAction(e);}
  }
}

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

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

Ответы [ 2 ]

0 голосов
/ 29 октября 2019

В основном ваш код не выполняет то, что вы ожидаете, потому что диапазоны, которые вы получаете в строках, как этот:

sheet.getRange(oldRow, oldColumn).setBackground("orange");

- это всего лишь одна ячейка.

При использовании getRange следует включить параметры numRows и numColumns, если вы хотите, чтобы диапазон включал более одной строки или столбца соответственно (см. Дополнительную информацию здесь ).

Ваша функция recordChange может выглядеть следующим образом:

function recordChange(c) {
  var range = c.range;
  var ss = c.source; // This returns the spreadsheet from which the event was triggered
  var sheet = ss.getSheets()[0];
  var column = 8; //Column for change log
  var firstRow = range.getRow();
  var numRows = range.getNumRows();
  range.setBackground("orange");
  var dateCells = sheet.getRange(firstRow, column, numRows);
  dateCells.setValue(new Date())
}

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

При установке даты выпуска в столбце 8 вам необходимо использовать getRange. Как видите, вам нужно указать количество строк, которое будет иметь диапазон (что соответствует количеству строк отредактированного диапазона), и вы получите это количество строк, используя getNumRows .

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

function recordAction(c) {
  var range = c.range;
  var ss = c.source;
  var sheet = ss.getSheets()[0];
  var row = range.getRow();
  var firstRow = range.getRow();
  var firstColumn = 1;
  var numRows = range.getNumRows();
  var numCols = 8;
  var editedRange = sheet.getRange(firstRow, firstColumn, numRows, numCols);
  editedRange.setBackground(null);
}

Здесь вам также необходимо использовать getRange, поскольку диапазон, который вы хотите изменить, не совпадает с диапазоном, полученным из объекта события. ,Для этого вам необходимо предоставить соответствующие параметры. Опять же, вы можете получить количество строк, используя getNumRows. И если вы хотите удалить фон для первых 8 столбцов, вы уже знаете оба параметра столбца (1 и 8).

Надеюсь, это вам поможет.

0 голосов
/ 29 октября 2019

Вам необходимо использовать некоторые методы в объекте e.range.

Я написал небольшой пример кода:

function onEdit(e) {

  var sheet = SpreadsheetApp.getActive().getActiveSheet();
  var changes = e.range.getValues();
  // +1 because of header row
  var lastRow = e.range.getLastRow() + 1;
  var date = new Date();
  var dateOfChange = date.toLocaleDateString() + " at " + date.toLocaleTimeString();
  var timeColumn = 4

  //sheet.getDataRange().getLastColumn()
  for (var i = 0; i < changes.length; i++) {
    var row = (lastRow - changes.length) + i;
    var timeCell = sheet.getRange(row, timeColumn);

    //this is quick and dirty but you will probably want to add more advanced data validation
    var validator = 0
    changes[i].forEach(function(x) {x.toString().length > 0 ? validator++ : null;})

    if (validator > 0 && e.range.getLastColumn() < timeColumn) {
      timeCell.setValue(dateOfChange);
    } else {
      timeCell.clear()
    }
  }
}

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

Вот его изображение, работающее с простой электронной таблицей: Forgot to add any foos or bars

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