/**
*
*/
const SETTINGS = Object.freeze({
fns: [
'danon',
'mars',
'curren1',
'curren2',
'vilma',
'seitek',
'radost',
'rolls',
'lysse',
],
});
/**
*
*/
function addTriggers() {
ScriptApp.getProjectTriggers().forEach((trigger) => {
if (
trigger.getEventType() === ScriptApp.EventType.CLOCK &&
SETTINGS.fns.includes(trigger.getHandlerFunction())
) {
ScriptApp.deleteTrigger(trigger);
}
});
SETTINGS.fns.forEach((fn) =>
ScriptApp.newTrigger(fn).timeBased().everyHours(6).create()
);
}
function include(filename) {
return HtmlService.createHtmlOutputFromFile(filename)
.getContent();
}
<style>
Тут код вашего BS
</style>
<script>
Тут код вашей JQ
</script>
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<?!= include('bs'); ?>
</head>
<body>
<h1>Welcome</h1>
<p>Please enjoy this helpful script.</p>
<?!= include('jq'); ?>
</body>
</html>
function showSidebar() {
var htmlTemplate = HtmlService
.createTemplateFromFile('client');
SpreadsheetApp.getUi().showSidebar(htmlTemplate.evaluate()
.setTitle('Цвет текста в ячейке поменялся'));
}
/**
*
*/
function runOnce() {
trigger_();
}
/**
*
*/
function trigger_() {
try {
triggerAction();
} catch (error) {
console.error(error.message, error);
} finally {
var hours = 10;
var minutes = 17;
var seconds = 56;
var now = new Date();
var nextTime = new Date();
nextTime.setHours(0, 0, 24 * 3600 + hours * 3600 + minutes * 60 + seconds);
var delta = nextTime.getTime() - now.getTime();
ScriptApp.newTrigger('trigger_')
.timeBased()
.after(delta)
.create();
}
}
/**
*
*/
function triggerAction() {
console.log("I'm fine");
}
triggerAction
- это то, что выполняет ваш скриптrunOnce
- это то, что вы должны запустить один раз при первом запуске вашего триггера. Другие настройки не требуютсяtrigger_
- это и триггер и конфигурация вашего триггера/**
* Get currencies by a date
*/
function run() {
const httpResponse = UrlFetchApp.fetch(
'https://www.cnb.cz/cs/financni-trhy/devizovy-trh/kurzy-devizoveho-trhu/kurzy-devizoveho-trhu/denni_kurz.txt?date=20.05.2020'
);
const data = Utilities.newBlob(httpResponse.getContent(), 'plain/text')
.getDataAsString()
.split('\n')
.map((line) => line.split('|'))
.slice(1);
console.log(data);
/*
// Paste to a sheet
sheet.getRange(1, 1, data.length, data[0].length).setValues(data);
*/
}
spec
- массив имен листов, которые нужно экспортироватьspreadsheet
- копия Таблицы для экспорта/**
*
*/
function runSheet() {
const spec = ['COUNTIF']; // List of sheets for export
const spreadsheet = SpreadsheetApp.openById(
'1TpHUfTvA7xBi4TLnWaplGasDumauA3YyMgXjXeQ2cyo'
).copy('tmp');
spec.forEach(sheetName => {
const dr = spreadsheet.getSheetByName(sheetName).getDataRange();
dr.setValues(dr.getValues());
});
spreadsheet.getSheets().forEach(sheet => {
if (spec.indexOf(sheet.getName()) < 0) spreadsheet.deleteSheet(sheet);
});
const spreadsheetId = spreadsheet.getId();
const file = exportSpreadsheetToFile_(spreadsheetId, 'xlsx');
DriveApp.getFileById(spreadsheetId).setTrashed(true);
return file;
}
exportSpreadsheetToFile_
можно найти тут google-apps-script-snippets/standalone/export_spre... SpreadsheetApp.flush()
.flush
толку не будет. В этих формулах так же не работают set-операторы./**
* @OnlyCurrentDoc
*/
/**
*
* The TESTCACHESERVICE function
*
* @param {param} param
* @return {number}
* @customfunction
*/
function TESTCACHESERVICE(param) {
const cache = CacheService.getScriptCache();
const cached = param === 'break' ? 0 : +cache.get('cached') + 1 || 0;
cache.put('cached', cached);
return cached;
}
function onOpen() {
SpreadsheetApp.getUi()
.createMenu('Reset sheet')
.addItem('Make a copy before reset', 'userActionMakeCopyBeforeReset')
.addToUi();
}
function userActionMakeCopyBeforeReset() {
const book = SpreadsheetApp.getActive();
const sheet = book.getActiveSheet();
makeCopyBeforeReset_(sheet, book);
}
function makeCopyBeforeReset_(sheet, book) {
const copy = sheet.copyTo(book);
const rangesAddressesList = ['B5', 'B7', 'B9', 'B11'];
resetByRangesList_(sheet, rangesAddressesList);
return copy;
}
function resetByRangesList_(sheet, rangesAddressesList) {
sheet.getRangeList(rangesAddressesList).clearContent();
}
Utilities
поддерживали локали.DateTimeFormat
function myFormatDate(date) {
const y = new Intl.DateTimeFormat('ru',{
year: 'numeric'
}).format(date)
const m = new Intl.DateTimeFormat('ru',{
month: 'long'
}).format(date)
return `${m}-${y}`
}
function test(){
const date = new Date();
console.log(Utilities.formatDate(date, "GMT+3", "MMM-yyyy"));
console.log(myFormatDate(date));
}
"MMM-d"
не вернет год - вернет дату. getDisplayValues()
var drr = sheet.getRange(sheet.getLastRow(), 1, 1, 3).getDisplayValues()[0];
0.00%
, то вернет именно 0.00%
, если 1-02-20
, то 1-02-20
.x-www-form-urlencoded
. При получении аргумента формы вы должны "преобразовать" его к требуемому формату. В вашем случаеconst payments = JSON.parse(e.parameter.payments);
/**
*
* @param {GoogleAppsScript.Events.DoPost} e
*/
function doPost(e) {
const payments = JSON.parse(e.parameter.payments);
return ContentService.createTextOutput(JSON.stringify(payments.products[0]));
}
doPost
объект нужно сделатьform2Json(e.postData.contents)
/* global form2Json */
/* exported doPost */
/**
*
* @param {GoogleAppsScript.Events.DoPost} e
*/
function doPost(e) {
// const payments = JSON.parse(e.parameter.payments);
return ContentService.createTextOutput(
JSON.stringify(form2Json(e.postData.contents), null, ' ')
);
}
const data = form2Json(contents);
console.log(JSON.stringify(data.payment.products[0]));
flush()
SpreadsheetApp.flush();
/**
*
* @param {GoogleAppsScript.Events.SheetsOnEdit} e
*/
function onEdit(e) {
var activeSheet = e.source.getActiveSheet();
SpreadsheetApp.getActive().toast(['Лист'].indexOf(activeSheet.getName()));
if (['Лист'].indexOf(activeSheet.getName()) == -1) return;
var r = SpreadsheetApp.getActiveRange();
var cols = r.getColumn();
if (cols == 6) {
// если изменяем 6 колонку, то тригер работает и:
var cell1 = activeSheet.getRange(2, 2); // во второй колонке берет данные из второй строки (там лежит формула)
var destination1 = activeSheet.getRange(activeSheet.getLastRow(), 2); // находит последнюю строку с данными и выбирает вторую колонку
cell1.copyTo(destination1); // копирует из второй строчки в последнюю
var cell2 = activeSheet.getRange(2, 3); // тоже самое но только для 3 колонки
var destination2 = activeSheet.getRange(activeSheet.getLastRow(), 3); // тоже самое но только для 3 колонки
cell2.copyTo(destination2); // тоже самое но только для 3 колонки
var cell3 = activeSheet.getRange(2, 5); // тоже самое но только для 5 колонки
var destination3 = activeSheet.getRange(activeSheet.getLastRow(), 5); // тоже самое но только для 5 колонки
cell3.copyTo(destination3); // тоже самое но только для 5 колонки
var cell4 = activeSheet.getRange(2, 8); // тоже самое но только для 8 колонки
var destination4 = activeSheet.getRange(activeSheet.getLastRow(), 8); // тоже самое но только для 8 колонки
cell4.copyTo(destination4); // тоже самое но только для 8 колонки
SpreadsheetApp.flush();
destination1.copyTo(
destination1,
SpreadsheetApp.CopyPasteType.PASTE_VALUES,
false
); // во второй колонке меняет формулу на значение
destination2.copyTo(
destination2,
SpreadsheetApp.CopyPasteType.PASTE_VALUES,
false
); // в третьей колонке меняет формулу на значение
destination3.copyTo(
destination3,
SpreadsheetApp.CopyPasteType.PASTE_VALUES,
false
); // в пятой колонке меняет формулу на значение
destination4.copyTo(
destination4,
SpreadsheetApp.CopyPasteType.PASTE_VALUES,
false
); // в восьмой колонке меняет формулу на значение
SpreadsheetApp.getActive().toast('Готово');
}
}
V8
, STABLE
, DEPRECATED_ES5
.V8
порядок файлов однозначно не играет роли и даже не все файлы загружаются для исполнения. Поэтому лучше избегать этой условности.STABLE
, DEPRECATED_ES5
порядок обычно зависит от алфавитного расположения файлов, но это негарантировано.код.gs
и код2.gs
. В обоих есть функция onOpen
. При загрузке текста программы в исполнительную среду одна функция перезапишет другую и исполняться на самом деле будет только одна функция, т.к. другой нет и в помине (она перезаписана). Какая функция будет перезаписана, это зависит от среды (см. выше).function onOpen(e){
onOpen1(e);
onOpen2(e);
}
function onOpen1(e){
...
}
function onOpen2(e){
...
}
/**
* Open the url in a new tab
* @param {string} url
*/
function openUrlInBrowser_(url) {
const tmp = HtmlService.createTemplateFromFile('app');
tmp.url = url;
const htmlOutput = tmp.evaluate();
SpreadsheetApp.getUi().showModelessDialog(htmlOutput, 'Opening url ...');
}
app.html
в проекте/**
* Open the url in a new tab
* @param {string} url
*/
function openUrlInBrowser_(url) {
const tmp = HtmlService.createTemplateFromFile('app');
tmp.url = url;
const htmlOutput = tmp.evaluate();
SpreadsheetApp.getUi().showModelessDialog(htmlOutput, 'Opening url ...');
}
const values = s.getRange(1, col1, s.getLastRow(), col1).getValues();
const count = values.filter(
(row, i, arr) => arr[i + 1] && compareAsDate_(row[0], arr[i + 1][0])
);
console.log(count);
/**
*
* @param {any} a
* @param {any} b
*/
function compareAsDate_(a, b) {
return (
a && b && a.getTime && b.getTime && a.toDateString() === b.toDateString()
);
}
~/.cache/google-chrome/Default/Cache