=LET(
places;UNIQUE(A2:A);
dates;BYROW(places;LAMBDA(_p;TO_DATE(INDEX(SORT(FILTER(B2:B;A2:A=_p);1;0);2))));
{places\dates}
)
/**
*
* @param {GoogleAppsScript.Spreadsheet.Range} range
* @returns
*/
function insertCheckBoxesToRange_(range) {
return range.insertCheckboxes();
}
function userActionInsertCheckBoxes() {
const sheet = SpreadsheetApp.getActive().getSheetByName('Вставить чекбокс скриптом');
sheet.appendRow(['']);
const lr = sheet.getLastRow() + 1;
const range = sheet.getRange(`${lr}:${lr}`);
insertCheckBoxesToRange_(range);
}
00:00-06:00
. Далее необходимо значение перевести в числа, т.к. это самый простой способ не ошибиться в сравнении и уже к этим данным наложить FILTER
const xml = UrlFetchApp.fetch(url).getContentText()
const document = XmlService.parse(xml)
SpreadsheetApp
, getDataRange().getValues()
SpreadsheetApp
, getDataRange().setValues()
/**
*
* @param {GoogleAppsScript.Document.Document} doc
* @param {Record<string,unknown>} data
*/
function fillDoc_(doc, data) {
const body = doc.getBody();
Object.entries(data).forEach(([key, value]) => {
body.replaceText(`(?i){{${key}}}`, value);
});
body.replaceText(`(?i){{.*?}}`, '');
}
const file = DriveApp.getFileById('192avJeIyh524ofvFvuQRaf9QPyqH7FKBEzwNLoHJa-g').makeCopy();
const doc = DocumentApp.openById(file.getId());
Важно, заменяемый текст в шаблоне должен быть обернут в {{заменяемый текст}}
.
const values = SpreadsheetApp.getActive()
.getRange("'Заполнение Документа данными из Таблицы'!2:2")
.getDisplayValues()[0];
const data = {
заголовок: 'тестовый заголовок',
имя: values[1],
};
fillDoc_(doc, data);
function calcData() {
const book = SpreadsheetApp.getActive();
const spravochnik = book.getRange("'Как заменить формулу скриптом'!M2:N5")
.getValues().reduce((a, r) => {
if (r[0] && r[1]) {
a[r[0]] = r[1];
}
return a;
}, {});
const headersX = book.getRange("'Как заменить формулу скриптом'!D2:G2").getValues()[0]
.map(h => spravochnik[h] || 0);
const voprosData = book.getRange("Как заменить формулу скриптом!D3:G8")
.getValues();
const voprosData2 = book.getRange("Как заменить формулу скриптом!H3:I8")
.getValues();
const values = voprosData.map((row, j) => {
return [row.reduce((a, v, i) => a + headersX[i] * v, 0)
+ +voprosData2[j].reduce((a, v) => a + v, 0)];
});
book.getSheetByName("Как заменить формулу скриптом")
.getRange(3, 10, values.length, values[0].length).setValues(values)
.activate();
}
calcData
как вызов для триггера события Edit
. Если добавляете в событие, то нужно еще будет проверить имя активного листа и изменяемый диапазон.onEdit
- зарезервированное имя функции для простого триггера.getRichTextValue()
, возвращаемый объект имеет метод getLinkUrl()
.cell.getRichTextValue().getLinkUrl();
/**
*
* @param {GoogleAppsScript.Spreadsheet.Range} ref
*/
function extractLink_(ref) {
const richTextValues = ref.getRichTextValues();
return richTextValues.map((row) =>
row.map((cell) => {
return cell.getLinkUrl();
}),
);
}