OnEdit() e.source возвращает первый лист в электронной таблице, а не отредактированный лист

Для контекста у меня есть таблица Google, которую мы используем для инвентаризации и цен. Я создал еще одну таблицу, в которую импортируются нужные нам диапазоны из оригинала, чтобы показывать покупателям оптовые запасы без каких-либо цен. В настоящее время я использую ImportRange() для копирования содержимого, но мне бы хотелось сохранить форматирование предыдущего листа.

Я использую этот скрипт onEdit() для обновления форматирования (в оригинале я использую триггер):

function setFormatOnEdit(e) {
  if (!e)
    throw new Error("This function is automatically called, do not run this manually")
  const lock = LockService.getScriptLock()
  if (lock.tryLock(350000)) {
    try {
      const {
        master,
        sources
      } = variables_();
      const { range, source } = e;
      const { editRange } = sources.find(({ sheetName }) => sheetName == source.getSheetName());
      const srcRange = source.getRange(editRange);
      const editedSheetName = range.getSheet().getSheetName();
      if (editedSheetName != srcRange.getSheet().getSheetName())
        return;
      //Reformatting Code Here
    } catch ({stack}) {
      console.error(stack)
    } finally {
      lock.releaseLock();
      console.info("Done");
    }
  } else { console.error("Timeout") }
}

И переменные_() это:

function variables_() {
  const masterSpreadsheetId = "###"

  const sourceSheetName1 = "Mixed Oak"
  ...
  const sourceSheetName13 = "Misc/Random Inventory"

  const sourceSheet1Range = "Mixed Oak!A1:I"
  ...
  const sourceSheet13Range = "Misc/Random Inventory!A1:I"

  return {
    master: { masterSpreadsheetId },
    sources: [
      { sheetName: sourceSheetName1, editRange: sourceSheet1Range },
      ...
      { sheetName: sourceSheetName13, editRange: sourceSheet13Range }
    ]
  };
}

В настоящее время у меня возникла проблема с тем, что e.source возвращает первый лист в исходной электронной таблице (который представляет собой сводную информацию о ценах; я не хочу копировать этот лист) после каждого редактирования, независимо от того, какой лист редактируется.

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

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

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

variables_() не определено
Cooper 12.06.2024 17:03
variables_() — функция вне этого блока. Кроме того, не имеет значения, на каком листе возвращается e.source.
Nathan Gramm 12.06.2024 17:08

редактируемый лист: e.range.getSheet();

Cooper 12.06.2024 17:08

Итак, источник просто возвращает электронную таблицу, а при запросе листа он просто возвращает первую?

Nathan Gramm 12.06.2024 17:09

Тогда это не должно быть частью вашего минимально воспроизводимого примера потому что мы не можем его воспроизвести.

Cooper 12.06.2024 17:09

Кроме того, у меня все еще есть проблема, когда e.range.getSheet() возвращает сводный лист, хотя я редактирую второй лист.

Nathan Gramm 12.06.2024 17:30

Я обновил пост, включив в него функцию varaibles_().

Nathan Gramm 12.06.2024 17:35
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
7
60
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Свойство source триггера события при редактировании возвращает активный SpreasheetApp.Spreadsheet, а не SpreadsheetApp.Sheet.

С другой стороны, следующая часть сценария в вопросе не имеет для меня смысла:

const { editRange } = sources.find(({ sheetName }) => sheetName == source.getSheetName());
const srcRange = source.getRange(editRange);
const editedSheetName = range.getSheet().getSheetName();
if (editedSheetName != srcRange.getSheet().getSheetName())
        return;

Если вы хотите получить отредактированный диапазон, используйте e.range, e.source.getActiveSheet().getActiveRange() или SpreadsheetApp.getActiveSheet().getActiveRange(). Первый вариант предпочтительнее из-за краткости и интуитивно он должен быть быстрее. Кроме того, возвращаемый объект расширяется свойствами rowStart, columnStart, rowEnd и columnEnd, которые удобны во многих случаях использования.

Чтобы получить имя редактируемого листа, вы можете использовать e.range.getSheet().getName() или e.source.getActiveSheet().getName(), SpreadsheetApp.getActiveSheet().getName(). Предпочтителен любой из первых двух вариантов.

Примечание. Что касается объяснения концепций электронных таблиц и того, как работают электронные таблицы Google, я думаю, что документация API Google Sheets более полная и понятная, чем документация службы электронных таблиц Google Apps Script и даже раздел Google Sheets на сайте https://support. google.com/docs. Я упомянул об этом, потому что в документации API Google Таблиц упоминается, как в некоторых случаях определяется возвращаемый лист или диапазон.

Спасибо, что изучили это. Первая строка с переменной editRange используется для проверки из готового списка того, что редактируемый лист на самом деле является одним из копируемых листов. Остальное, вероятно, бесполезно, поскольку оно проверяло, что источник и диапазон были из одного и того же листа... Однако у меня все еще возникает проблема: когда я редактирую лист «Смешанный дуб», Logger.log(e.range.getSheet().getName()) из выполнения триггера все еще возвращает «Сводка» ' вместо.

Nathan Gramm 12.06.2024 21:19

@NathanGramm Возможно, вы смотрите не на то событие. Что вы делаете, чтобы активировать триггер onEdit?

Wicket 12.06.2024 21:30

И, что еще более важно, вы, возможно, слишком много об этом думаете... вместо использования IMPORTRANGE и сценария гораздо лучше использовать сценарий для копирования значений и формата.

Wicket 12.06.2024 21:31

Ах да, я заметил, что когда я добавляю строку, выводится лист «Сводка», но при изменении значений ячейки выводится правильное имя листа. И да, возможно, вместо этого я рассмотрю возможность простого копирования содержимого, что должно решить эту проблему.

Nathan Gramm 12.06.2024 21:37

@NathanGramm, я думаю, вы используете триггер при изменении вместо триггера при редактировании, потому что триггер при редактировании не активируется при вставке строки.

Wicket 12.06.2024 22:25

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