Для контекста у меня есть таблица 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_()
— функция вне этого блока. Кроме того, не имеет значения, на каком листе возвращается e.source.
редактируемый лист: e.range.getSheet();
Итак, источник просто возвращает электронную таблицу, а при запросе листа он просто возвращает первую?
Тогда это не должно быть частью вашего минимально воспроизводимого примера потому что мы не можем его воспроизвести.
Кроме того, у меня все еще есть проблема, когда e.range.getSheet()
возвращает сводный лист, хотя я редактирую второй лист.
Я обновил пост, включив в него функцию varaibles_()
.
Свойство 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())
из выполнения триггера все еще возвращает «Сводка» ' вместо.
@NathanGramm Возможно, вы смотрите не на то событие. Что вы делаете, чтобы активировать триггер onEdit?
И, что еще более важно, вы, возможно, слишком много об этом думаете... вместо использования IMPORTRANGE и сценария гораздо лучше использовать сценарий для копирования значений и формата.
Ах да, я заметил, что когда я добавляю строку, выводится лист «Сводка», но при изменении значений ячейки выводится правильное имя листа. И да, возможно, вместо этого я рассмотрю возможность простого копирования содержимого, что должно решить эту проблему.
@NathanGramm, я думаю, вы используете триггер при изменении вместо триггера при редактировании, потому что триггер при редактировании не активируется при вставке строки.
variables_()
не определено