потом осуществлять последующую обработку
{ }
или с помощью скриптов.QUERY
не поддерживает ее. Поэтому необходимо строить массив уже готовых значений и работать с ним. Например, добавить "шт." в текущий массив=QUERY(
{'ТЕСТ'!A7:P\ARRAYFORMULA('ТЕСТ'!F7:F & " шт.")};
"Select Col3,Col1,Col2,Col17 Where Col1 like '%' or Col3 like '%'";
)
format
=QUERY('ТЕСТ'!A7:P;"Select C,A,B,F Where A like '%' or C like '%' format F'#.00 шт.'")
function onEdit() {
run2();
}
function run2() {
/* Remove dash */
var sheet = SpreadsheetApp.getActiveSheet();
if (sheet.getName() === 'Журнал вода данных') return;
var archive = SpreadsheetApp.getActive().getSheetByName('Журнал вода данных');
var action = function(values, i, i2) {
var data = values.slice(i, i + i2);
archive
.getRange(archive.getLastRow() + 1, 1, data.length, data[0].length)
.setValues(data);
};
var condition = function(values, i) {
var row = values[i];
return (
i > 0 && row[0] !== '' && row[1] !== '' && row[3] !== '' && row[5] !== ''
);
};
deleteRowsByConditional_(sheet, condition, action);
}
function deleteRowsByConditional_(sheet, condition, action) {
sheet
.getDataRange()
.getValues()
.forEach(
function(_, i, arr) {
var j = arr.length - i - 1;
if (this.condition.apply(null, [arr, j])) {
this.isContinue++;
if (j > 0) return;
}
if (this.isContinue > 0) {
var prevPos = j + 1; // It's reversed
if (action) action(arr, prevPos, this.isContinue);
this.sheet.deleteRows(prevPos + 1, this.isContinue);
this.isContinue = 0;
return;
}
return;
},
{ sheet: sheet, condition: condition, isContinue: 0 }
);
}
run2()
к меню.doPost(e)
передается запрос от внешнего источника только тогда, когда ваш сервис опубликован и отправлен запрос POST.doPost
из редактора кода. MailApp.sendEmail({
...
body: 'https://drive...',
...
});
var file = DriveApp.getFilesByName('test123.pdf');
if (file.hasNext()) {
MailApp.sendEmail(emailAddress, subject, message, {
attachments: [file.next().getAs(MimeType.PDF)],
name: 'Automatic Emailer Script'
}
function sendEmail() {
var sheet = SpreadsheetApp.getActiveSheet();
var activeRange = sheet.getActiveRange();
var data = sheet
.getRange(
activeRange.getRow(),
1,
activeRange.getLastRow() - activeRange.getRow() + 1,
6
)
.getValues();
data.forEach(function(row) {
var file = DriveApp.getFilesByName(row[5]);
if (file.hasNext()) {
var namesender = row[0];
var emailAddress = row[1];
var hiddencopy = row[2];
var subject = row[3];
var message = row[5];
var information = row[4];
var emailQuotaRemaining = MailApp.getRemainingDailyQuota();
Logger.log('Remaining email quota: ' + emailQuotaRemaining);
MailApp.sendEmail({
to: emailAddress,
bcc: hiddencopy,
replyTo: 'supportmp@test.ru',
name: namesender,
subject: subject + ' ' + information,
htmlBody: message + ' ' + https,
attachments: [file.next().getAs(MimeType.PDF)],
});
} else {
Logger.log('Файл для отправки не найден');
}
});
}
anchor
полученный объект "anchor": "{\"type\":\"workbook-range\",\"uid\":0,\"range\":\"2121905705\"}"
Где-то была конвертилка range
в A1-нотацию, но можно и погуглить“”«»
Unlike most other types of Apps Scripts, custom functions never ask users to authorize access to personal data. Consequently, they can only call services that do not have access to personal data, specifically the following:
Supported services Notes Cache Works, but not particularly useful in custom functions HTML Can generate HTML, but cannot display it (rarely useful) JDBC Language Lock Works, but not particularly useful in custom functions Maps Can calculate directions, but not display maps Properties Spreadsheet Read only (can use most get*()
methods, but notset*()
).
Cannot open other spreadsheets (SpreadsheetApp.openById()
orSpreadsheetApp.openByUrl()
).URL Fetch Utilities XML