Заменить значение ячейки в Google Script Apps

Я пытаюсь написать скрипт, который при изменении ячейки на листе "Негатив отсутствует" заменит значение ячейки на другом листе значением "Нерелевант". Помогите пожалуйста, что я сделал не так?

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("");
    
    
}
}
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
0
366
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Объяснение / Проблемы:

Проблема:

Существует явная проблема с вашим кодом и, в частности, здесь:

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);
  }
  }
}

Еще раз спасибо за помощь =)

Другие вопросы по теме