Я пытаюсь написать скрипт, который при изменении ячейки на листе "Негатив отсутствует" заменит значение ячейки на другом листе значением "Нерелевант". Помогите пожалуйста, что я сделал не так?
function ChangeTone(event) {
if (event.source.getActiveRange().getValue()= = "Негатив отсутствует" && event.source.getActiveSheet()= = "Разметка ТОП100 по суду"){
var sheet = SpreadsheetApp.getActiveSheet();
var currRow = sheet.getActiveCell().getRow();
var value = sheet.getRange(currRow, 1).getDisplayValue();
var pasteSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Тональность");
var data = pasteSheet.getDataRange().getValues();
// if (currRow > 2){
// sheet.deleteRow(currRow);
// }
for(var i = 1; i<data.length;i++){
if (data[i][1] == value){
pasteSheet.getRange((i), 2).clear({contentsOnly: true});
pasteSheet.getRange((i), 2).setValue('Нерелевант');
break;
}
};
// sheet.getActiveCell().setValue("");
}
}



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Проблема:
Существует явная проблема с вашим кодом и, в частности, здесь:
event.source.getActiveSheet()= = "Разметка ТОП100 по суду"
Вы сравниваете объект листа со строкой, и это всегда возвращает false. Правильный способ сделать это:
event.source.getActiveSheet().getName()= = "Разметка ТОП100 по суду"
но здесь я также попытался оптимизировать ваш код, потому что он довольно неэффективен.
Оптимизация:
Вы не в полной мере используете объект события.
SpreadsheetApp.getActiveSpreadsheet() можно заменить на e.source.Вы также определяете одни и те же переменные несколько раз, когда вам нужно сделать это только один раз:
event.source.getActiveSheet() и var sheet = SpreadsheetApp.getActiveSheet(); вы можете определить одну переменную для хранения активного объекта листа и вызывать его всякий раз, когда вам это нужно.Последний, но тем не менее важный. Я не совсем уверен в вашей логике относительно цикла for, поскольку вы не упомянули об этом в своем вопросе.
Но я вижу, что вы используете цикл for, оператор if и строку break, чтобы выйти из цикла for, как только есть совпадение между исходным значением и значением на листе вставки.
Вместо использования цикла for вы можете использовать findIndex, чтобы найти значение, соответствующее критерию data[i][1] == value.
Также полный getDataRange() не нужен, если вы собираетесь использовать только один столбец, поэтому я меняю и эту часть.
function onEdit(e){
const ss = e.source;
const ar = e.range;
const activeSheet = ss.getActiveSheet();
const pasteSheet = ss.getSheetByName("Тональность");
if (ar.getValue()= = "Негатив отсутствует" && activeSheet.getName()= = "Разметка ТОП100 по суду"){
const value = activeSheet.getRange(ar.getRow(), 1).getValue();
const data = pasteSheet.getRange('B1:B'+pasteSheet.getLastRow()).getValues().flat();
const indx = data.findIndex((element) => element == value);
if (indx>-1){
const pasteRng = pasteSheet.getRange(indx+1,2);
pasteRng.clearContent();
pasteRng.setValue('Нерелевант');
}
}
}
Дайте мне знать, если это сработало для вас, в противном случае я хотел бы изменить его, чтобы он работал.
Большое спасибо! Скрипт работает =) Я также сделал рабочий скрипт раньше. Но это мой первый скрипт, поэтому он намного медленнее и не такой... лаконичный. Также он был запущен с помощью триггера, а ваш работает как простое событие. Моя старая версия:
function ChangeTone(event) {
if (event.source.getActiveRange().getValue()= = "Негатив отсутствует" && event.source.getActiveSheet().getName() == "Разметка ТОП100 СУД"){
var sheet = SpreadsheetApp.getActiveSheet();
var currRow = sheet.getActiveCell().getRow();
sheet.getRange("A"+currRow+":F"+currRow).setBackground('#ff5a5a');
var value = sheet.getRange(currRow, 1).getDisplayValue();
var pasteSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Тональность");
var data = pasteSheet.getDataRange().getValues();
for(var i = 1; i<data.length;i++){
if (data[i][0] == value){
pasteSheet.getRange((i+1), 2).setValue('Нерелевант');
sheet.getRange("C"+currRow+":F"+currRow).deleteCells(SpreadsheetApp.Dimension.ROWS);
}
};
sheet.getRange("A"+currRow+":B"+currRow).setBackground('#ffffff');
}
}
Поэтому взял ваш код и добавил удаление строки после замены значения ячейки. Окончательный вариант:
function onEdit(e){
const ss = e.source;
const ar = e.range;
const arRow = ar.getRow();
const activeSheet = ss.getActiveSheet();
const pasteSheet = ss.getSheetByName("Тональность");
if (ar.getValue()= = "Негатив отсутствует" && activeSheet.getName()= = "Разметка ТОП100 СУД"){
const value = activeSheet.getRange(arRow, 1).getValue();
const data = pasteSheet.getRange('A1:A'+pasteSheet.getLastRow()).getValues().flat();
const indx = data.findIndex((element) => element == value);
if (indx>-1){
const pasteRng = pasteSheet.getRange(indx+1,2);
pasteRng.clearContent();
pasteRng.setValue('Нерелевант');
activeSheet.getRange("C"+arRow+":F"+arRow).deleteCells(SpreadsheetApp.Dimension.ROWS);
}
}
}
Еще раз спасибо за помощь =)