Порой возникает необходимость заполнения документов данными клиента. Иногда этих документов бывает слишком много. Да и заполнение представляет собой, чаще всего, простую подстановку ФИО в нужном месте документа.
Оказывается процесс заполнения документов можно автоматизировать и мало того можно поручить это самому клиенту.
Представим себе картину - клиент требует договор и счёт на оплату. А мы ему ссылку на google форму где ему необходимо заполнить данные, которые необходимы (включая адрес электронной почты). Скрипт, запущенный в таблицах с ответами, 'анализирует' полученные ответы, в заранее подготовленный шаблон, вставляет необходимые данные, шаблон преобразует в pdf и отправляет полученный файл на электронную почту клиента и на любой другой. И клиент доволен, и нам время не надо тратить на оформление документов. Шик, блеск, красота.
Дело за малым - остаётся создать форму с таблицей, создать шаблон и написать скрипт :) .
Попробуем создать генератор справок об оформлении подписки на мой блог.
1. Создаём форму, в которой нам будет интересны только Фамилия Имя Отчество и e-mail клиента.
2. Создаём таблицу с ответами
добавляем на странице с ответами два служебных столбца - "id" и "отправлено?"
Ссылка
Здесь DATA, NUMBER, ФИО_КЛИЕНТА - служебные поля, которые будут заменяться на данные клиента.
4. Открываем таблицу и пишем скрипт
function spravka() {
var ss=SpreadsheetApp.getActive();
var sheet=ss.getSheets()[0];
var lastR=sheet.getLastRow();
var clientData=sheet.getRange(lastR,1,1,3).getValues();
var data=new Date(clientData[0][0]);
var day=data.getDate(),month=data.getMonth()+1,year=data.getFullYear();
if (month<10){
month="0"+month;
}
var realdata=day+'.'+month+'.'+year;
var num=lastR-1;
var fio=clientData[0][2];
var mail=clientData[0][1];
var dirTemp=DriveApp.getFolderById('ID вашей директории для временных файлов')
var template=DriveApp.getFileById('ID вашего файла-шаблона').makeCopy('Справка',dirTemp).getId();
var docbody=DocumentApp.openById(template).getBody();
docbody.replaceText('DATA', realdata);
docbody.replaceText('NUMBER', num);
docbody.replaceText('ФИО_КЛИЕНТ', fio);
sheet.getRange(lastR, 4).setValue(template)
}
function getPdf(){
var ss=SpreadsheetApp.getActive();
var sheet=ss.getSheets()[0];
var dataRange=sheet.getDataRange().getValues();
for (var i=1;i<dataRange.length;i++){
if (dataRange[i][4]==""){
var filepdf=DriveApp.getFileById(dataRange[i][3]).getAs('application/pdf');
GmailApp.sendEmail(dataRange[i][1], 'Справка готова', 'Смотрите вложенный файл', {
attachments: [filepdf],
name: 'Блог "Изучаю google script"'
});
sheet.getRange(i+1, 5).setValue('☑')
DriveApp.getFileById(dataRange[i][3]).setTrashed(true);
}
}
}
Получилось 2 функции: spravka - собственно она и генерирует google документ из шаблона, и getPdf - преобразует google doc в pdf и отправляет на почту заполнившего человека. На функцию spravka ставим триггер на отправку формы, на getPdf ставим триггер на каждую минуту.
Почему функций 2? Какой-то глюк google - пока выполняется spravka, генерация pdf документа не происходит так как надо (не происходит замены полей в документе на данные клиента). Вторая функция обходит ответы, генерирует pdf и отправляет на адрес пользователя, заполнившего форму.
Что сейчас необходимо чтобы получить справку на Ваше имя? Заполнить форму, указав Ваш реальный e-mail.
Буду рад ответить на вопросы.
Почему функций 2? Какой-то глюк google - пока выполняется spravka, генерация pdf документа не происходит так как надо (не происходит замены полей в документе на данные клиента). Вторая функция обходит ответы, генерирует pdf и отправляет на адрес пользователя, заполнившего форму.
Что сейчас необходимо чтобы получить справку на Ваше имя? Заполнить форму, указав Ваш реальный e-mail.
Буду рад ответить на вопросы.
Здесь DATA, NUMBER, ФИО_КЛИЕНТА - служебные поля, которые будут заменяться на данные клиента.
ОтветитьУдалитьКак это реализиовать?
Здравствуйте.
УдалитьНе совсем понятен вопрос. В скрипте уже всё реализовано.
Здравствуйте!
ОтветитьУдалитьИспользовал ваш урок для попытки создания аналогичного по функционалу решения. Однако у меня не отправляется email, хотя и появляется файл во временной папке, а так же вижу в настройках триггеров выполнение по времени. Не подскажете в чем может быть проблема и куда смотреть.
Здравствуйте.
УдалитьДля отладки обычно запускаю функцию скрипта вручную, если есть ошибки то об этом будет сообщено.
Пробуйте, у Вас всё получится.
Еще появился вопросик. Как сделать так, что бы файлу присваивалось имя с учетом его NUMBER. Допустим Справка 1, Справка 2 и т.д. Для того чтобы файл не удалялся я так понимаю достаточно удалить строчку DriveApp.getFileById(dataRange[i][3]).setTrashed(true); И в догонку по поводу отправки файла. Можно ли его отправить не конвертируя в pdf?
УдалитьЗдравствуйте.
Удалить1. в строке var template=DriveApp.getFileById('ID вашего файла-шаблона').makeCopy('Справка',dirTemp).getId()
'Справка'+num
2. Да
3. Отправлять ссылку или doc? Если ссылка, то в письмо нужно добавить файл.getUrl(), могут появится сложности с доступом к файлу.
Большое спасибо за оперативную помощь!!!
УдалитьПо поводу отправки меня интересует отправка в формате googledocs.
Тогда можно не городить огород и формировать документ одной функцией, отправляя на e-mail только ссылку.
УдалитьВ начале, конечно, озаботиться чтобы доступ к каталогу, в который копируется файл, был открыт по ссылке.
Добрый день, Роман!
ОтветитьУдалитьА вы могли бы настроить под наши нужды ваш скрипт. Все аналогично, только полей больше.
Мы готовы заплатить за настройку. Мой скайп: live:9d4046936d84fc24
Добрый день. У меня создается файл в папке, но при попытке получить его функцией openByID пишет ошибку "Не удалось завершить выполнение за 33,368 сек. Документ недоступен. Повторите попытку позже". В чем может быть причина. Файл с таким ID в папке есть.
ОтветитьУдалитьДоброго дня.
УдалитьДаже не представляю какая у Вас может возникать ошибка. Хорошо бы посмотреть на пример таблицы со скриптом.
https://docs.google.com/spreadsheets/d/1AFrJOaQlFX_kDbLEquXZCZjZQ_fa89dZe37UeLEP3Lo/edit?usp=sharing
Удалитьfunction MakeOrder() {
var ss=SpreadsheetApp.getActive();
var sheet=ss.getSheets()[0];
var lastR=sheet.getLastRow();
var ID_ORDER_TEMPLATE = '1jsa0Gai8OV5X3TLfrn5QNXF89deuex2B';
var ID_TEMP_DIR = '1Cusi5_w7Qh7Ag8yCjIVPvoXwFYCoyOuK';
var clientData=sheet.getRange(lastR,1,1,14).getValues();
var FIO = clientData[0][1];
var DOG_NAME = clientData[0][2];
var BREED = clientData[0][3];
var SEX = clientData[0][4];
var BDATE = clientData[0][5];
var PEDIGREE = clientData[0][6];
var TATOO = clientData[0][7];
var LICENCE = clientData[0][8];
var PHONE = clientData[0][9];
var EMAIL = clientData[0][10];
var num=lastR-1;
var dirTemp=DriveApp.getFolderById(ID_TEMP_DIR);
var template=DriveApp.getFileById(ID_ORDER_TEMPLATE).makeCopy('Заявка '+DOG_NAME,dirTemp).getId();
var docbody=doc.DocumentApp.openById(template).getBody();
docbody.replaceText('FIO', FIO);
docbody.replaceText('DOG_NAME', DOG_NAME);
docbody.replaceText('BREED', BREED);
docbody.replaceText('SEX', SEX);
docbody.replaceText('BDATE', BDATE);
docbody.replaceText('PEDIGREE', PEDIGREE);
docbody.replaceText('TATOO', TATOO);
docbody.replaceText('LICENCE', LICENCE);
docbody.replaceText('PHONE', PHONE);
docbody.replaceText('EMAIL', EMAIL);
sheet.getRange(lastR, 14).setValue(template)
}
там небольшая ошибка.
Удалитьvar doc=DocumentApp.openById(template);
var docbody=doc.openById(template).getBody();
Разобрался. Документ был типа .docx, а не гугл документ.
Удалитьссылку не забудьте закрыть от любопытных глаз.
УдалитьЗдравствуйте!!!
ОтветитьУдалитьПодскажите пожалуйста, что я делаю не так?
https://drive.google.com/open?id=1mdzEOfJx0SKWE3HYxt1KeGwvkMO0dWLU2ngmipJCI4s
function spravka() {
var ss=SpreadsheetApp.getActive();
var sheet=ss.getSheets()[0];
var lastR=sheet.getLastRow();
var clientData=sheet.getRange(lastR,1,1,15).getValues();
var data=new Date(clientData[0][0]);
var day=data.getDate(),month=data.getMonth()+1,year=data.getFullYear();
if (month<10){
month="0"+month;
}
var realdata=day+'.'+month+'.'+year;
var num=lastR-1;
var pos=clientData[0][2];
var naz=clientData[0][3];
var fio=clientData[0][1];
var inn=clientData[0][4];
var org=clientData[0][5];
var sni=clientData[0][6];
var pasp=clientData[0][7];
var okv=clientData[0][8];
var adu=clientData[0][9];
var adp=clientData[1][0];
var adpp=clientData[1][1];
var sob=clientData[1][2];
var pho=clientData[1][3];
var mail=clientData[1][4];
var vid=clientData[1][5];
var dirTemp=DriveApp.getFolderById('1rVHL756s88HHLkMK3fXkrDD-LMCsmYS6')
var template=DriveApp.getFileById('12_9i7EEODiUPetQNGn0e_WGJr7GOBmMNa1HjoCbzE2s').makeCopy('Заявление',dirTemp).getId();
var docbody=DocumentApp.openById(template).getBody();
docbody.replaceText('DATA', realdata);
docbody.replaceText('NUMBER', num);
docbody.replaceText('ФИО_КЛИЕНТ', fio);
docbody.replaceText('ИНН_', inn);
docbody.replaceText('ОГРН_', org);
docbody.replaceText('ОКВЭД_', okv);
docbody.replaceText('Адрес_', adu);
docbody.replaceText('Адрес_П', adp);
docbody.replaceText('Должность_', pos);
docbody.replaceText('Телефон_', pho);
docbody.replaceText('ПОТЧА_', mail);
docbody.replaceText('ВИД_', vid);
docbody.replaceText('ПАСПОРТ_', pasp);
docbody.replaceText('СОБСТВЕННОСТЬ_', sob);
docbody.replaceText('НАЗВАНИЕ_', naz);
docbody.replaceText('СНИЛС_', sni);
docbody.replaceText('Адрес_П2', adpp);
sheet.getRange(lastR, 17).setValue(template)
}
function getPdf(){
var ss=SpreadsheetApp.getActive();
var sheet=ss.getSheets()[0];
var dataRange=sheet.getDataRange().getValues();
for (var i=1;i<dataRange.length;i++){
if (dataRange[i][17]==""){
var filepdf=DriveApp.getFileById(dataRange[i][14]).getAs('application/pdf');
GmailApp.sendEmail(dataRange[i][14], 'Заявление готово', 'Смотрите вложенный файл', {
attachments: [filepdf],
name: 'Заявление"'
});
sheet.getRange(i+1, 17).setValue('☑')
DriveApp.getFileById(dataRange[i][16]).setTrashed(true);
}
}
}
var adu=clientData[0][9];
Удалитьvar adp=clientData[0][10];
var adpp=clientData[0][11];
var sob=clientData[0][12];
И т.д.
Не решили проблему с тем что есть разделение на 2 функции? Пытаюсь это об ьединить в одну функцию применяя utilities.sleep(). Но все равно отправляется письмо с незамеченными данными в документе.
ОтветитьУдалитьИ Вам здравствуйте.
Удалитьищите метод saveAndClose()
https://developers.google.com/apps-script/reference/document/document#saveAndClose()
Спасибо! Все получилось отлично. Теперь могу создавать кучу таких скриптов!
УдалитьЗдравствуйте!
ОтветитьУдалитьПодскажите пожалуйста, скопировал скрипт прописал id. Данные с формы приходят а с крипт не срабатывает.
function spravka() {
var ss=SpreadsheetApp.getActive();
var sheet=ss.getSheets()[0];
var lastR=sheet.getLastRow();
var clientData=sheet.getRange(lastR,1,1,3).getValues();
var data=new Date(clientData[0][0]);
var day=data.getDate(),month=data.getMonth()+1,year=data.getFullYear();
if (month<10){
month="0"+month;
}
var realdata=day+'.'+month+'.'+year;
var num=lastR-1;
var fio=clientData[0][2];
var mail=clientData[0][1];
var dirTemp=DriveApp.getFolderById('1lQ_yxB2-0geID9eP6SEJNs45rdRRh31z')
var template=DriveApp.getFileById('1bgnklduXFtLufifjT0Gq6WHjKeZJhPwI6JNCB81Mb7c').makeCopy('Справка'+num,dirTemp).getId();
var docbody=DocumentApp.openById(template).getBody();
docbody.replaceText('DATA', realdata);
docbody.replaceText('NUMBER', num);
docbody.replaceText('ФИО_КЛИЕНТ', fio);
sheet.getRange(lastR, 4).setValue(template)
}
function getPdf(){
var ss=SpreadsheetApp.getActive();
var sheet=ss.getSheets()[0];
var dataRange=sheet.getDataRange().getValues();
for (var i=1;i<dataRange.length;i++){
if (dataRange[i][4]==""){
var filepdf=DriveApp.getFileById(dataRange[i][1]).getAs('application/pdf');
GmailApp.sendEmail(dataRange[i][1], 'Ваш документ', 'Смотрите вложенный файл', {
attachments: [filepdf],
name: 'Спасибо'
});
sheet.getRange(i+1, 5).setValue('☑')
DriveApp.getFileById(dataRange[i][3]).setTrashed(true);
}
}
}
Доброго.
УдалитьПрочитайте статью ещё раз и настройте триггеры на получение ответов из формы, и ежеминутной триггер.
Спасибо, настроил триггеры скрипт срабатывает, файл создается но pdf не отправляется.
УдалитьПишет:Элемент с заданным кодом не найден или у вас нет прав доступа к нему. (строка 57, файл Код)
var filepdf=DriveApp.getFileById(dataRange[i][1]).getAs('application/pdf');
Можете подсказать что делать?
Проверить, в первую очередь, чтобы в принимающем ответы листе не было пустых строчек до последней заполненной.
УдалитьПроверить чтобы в dataRange[i][n] вместо n стоял номер столбца в котором генерируется id файла -1.
Сейчас у Вас столбец номер 2, т.е. B.
Ура! Спасибо вам Роман! Сработало, в dataRenge не тот столбец был.
ОтветитьУдалитьА где брать id директории моих файлов????И как создать эту директорию
ОтветитьУдалитьДоброго.
УдалитьДиректория - папка на google диске.
Добрый вечер.У меня в таблице в полях id и отправлено ничего не выводится.Что делать.
ОтветитьУдалитьИ еще пдф файл не отсылается.
ОтветитьУдалитьДоброго.
УдалитьПрочитать статью ещё раз, обратив пристальное внимание на строку
На функцию spravka ставим триггер на отправку формы, на getPdf ставим триггер на каждую минуту.
Скорее всего, Вы забыли именно про триггеры.
Нет, о триггерах я не забыл
ОтветитьУдалитьТогда смотреть в выполнениях какую ошибку Вам выводит.
УдалитьНикаких ошибок не выводит.
УдалитьНа кофейной гуще не гадаю.)
УдалитьДоступ к таблице предоставьте, будет время - посмотрю.
Здравствуйте.
ОтветитьУдалитьСкажите, пожалуйста, а если надо сгенерить много справок одновременно? Как сделать так, чтобы скрипт генерил документы для выбранных строк (номеров строк)? Спасибо.
Здравствуйте.
УдалитьПо идее скрипт состоит из двух частей и вполне можно заставить его перебирать строки таблицы в цикле.
lastR указывает на последнюю строку, а можно указать, вместо getLastRow(), номер нужной строки.
Спасибо, буду пробовать написать цикл
УдалитьРоман, большое спасибо за кейс. Один вопрос - писали о триггере на 1 минуту, а по факту письмо получил через 5 минут. Что скажете по этому поводу?
ОтветитьУдалитьЗдравствуйте.
УдалитьВозможно, агент ФСБ, проверяющий вашу почту вышел покурить.)
А если серьёзно, возможны задержки во времени при отсылке почты. И это не секрет. Почта не является средством отправки мгновенных сообщений.
sheet.getRange(i+1, 5).setValue('☑')
ОтветитьУдалитьЭто последняя заполненная строка +1 (следующая строка?)
Почему айди документа тогда берется из предпоследней?
И вам доброго времени суток.
УдалитьНе понятен Ваш вопрос.
В скрипте берутся все строки, но письмо отправляется если в столбце 5 пусто.
Массивы в js нумеруются с ноля, в таблицах строки с номера 1, поэтому +1.
Приветствую! Спасибо за статью, использовал ваш пример для формирования анкеты из шаблона текстового документа.
ОтветитьУдалитьПодскажите, каким скриптом можно копировать последнюю созданную строку после отправки формы, в другую таблицу и вставлять в следующую пустую после последней строку? по сути нужно создать копию файла с ответами, но в эту копию данные будут заноситься ещё и вручную.
Доброго.
Удалитьсмотрите по направлению onFormSubmit(), openById(), setValues()
https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet-app
Спасибо! попробую
УдалитьВот так в итоге получилось выполнить задачу, выполняется при отправке формы. Спасибо ещё раз за статью
Удалитьfunction sync() {
var ss=SpreadsheetApp.getActive();
var sheet=ss.getSheets()[0];
var lastR=sheet.getLastRow();
var rowValues=sheet.getRange(lastR,1,1,23).getValues();
Logger.log(rowValues);
var destValues=[];
destValues.push(rowValues[0][0]);
destValues.push(rowValues[0][1]);
destValues.push(rowValues[0][2]);
destValues.push(rowValues[0][3]);
destValues.push(rowValues[0][4]);
destValues.push(rowValues[0][5]);
destValues.push(rowValues[0][6]);
destValues.push(rowValues[0][7]);
destValues.push(rowValues[0][8]);
destValues.push(rowValues[0][9]);
destValues.push(rowValues[0][10]);
destValues.push(rowValues[0][11]);
destValues.push(rowValues[0][12]);
destValues.push(rowValues[0][13]);
destValues.push(rowValues[0][14]);
destValues.push(rowValues[0][15]);
destValues.push(rowValues[0][16]);
destValues.push(rowValues[0][17]);
destValues.push(rowValues[0][18]);
destValues.push(rowValues[0][19]);
var dest=SpreadsheetApp.openById('id').getSheetByName("Лист1");
dest.getRange(dest.getLastRow()+1,1,1,20).setValues([destValues])
}
Такая простыня здесь совершенно ни к чему. Достаточно -
Удалитьfunction sync() {
var ss=SpreadsheetApp.getActive();
var sheet=ss.getSheets()[0];
var lastR=sheet.getLastRow();
var rowValues=sheet.getRange(lastR,1,1,20).getValues();
var dest=SpreadsheetApp.openById('id').getSheetByName("Лист1");
dest.getRange(dest.getLastRow()+1,1,1,20).setValues(rowValues)
}
Действительно) Спасибо, я в этом направлении и шел, но что то не сработало и стал искать примеры в сети, это меня с толку и сбило. Хотя сейчас вижу что на самом деле все логично и просто)
УдалитьСпасибо.
ОтветитьУдалитьДобрый день! Роман!
ОтветитьУдалитьРешил попробывать ваш скрипт, сделал все как в инструкции. Установил триггеры. Но столкнулся со следующей ошибкой: Exception: При вызове метода или свойства getFileById для объекта "DriveApp" произошла ошибка.
Сам файл во временной папке появляется. Столбец указан правильно в getFileById(dataRange[i][3]). Уже пол дня сижу, никак не могу решить эту проблему. Можете, что нибудь посоветовать пожалуйста?
Заранее спасибо
Доброго дня.Обратите внимание на наличие пустых строчек.
УдалитьТребуется консультация на платной основе по настройке Вашего скрипта. Моя телега - https://t.me/mismas_25
ОтветитьУдалитьДобрый день, а подскажите если не сложно. Скрипт есть, триггеры настроены, в папке документ появляется но: 1. вместо данные - NaNaNA (я так понимаю строки пустые в таблице), 2. не присваивается id в таблице, функции работают без ошибок (проверяла вручную, запускала отладчик). 3. на почтовый адрес не отправляется пдф (хотя в папке он есть). (((
ОтветитьУдалитьМожет я чего со столбцами напутала(((
(метка времени(1), имя(2), адрес эл почты(3), комментарий(4), id(5), отправлено(6))
function spravka() {
var ss=SpreadsheetApp.getActive();
var sheet=ss.getSheets()[0];
var lastR=sheet.getLastRow();
var clientData=sheet.getRange(lastR,1,1,6).getValues();
var data=new Date(clientData[0][0]);
var day=data.getDate(),month=data.getMonth()+1,year=data.getFullYear();
if (month<10){
month="0"+month;
}
var realdata=day+'.'+month+'.'+year;
var num=lastR-1;
var ima=clientData[0][1];
var mail=clientData[0][2];
var comm=clientData[0][3];
var dirTemp=DriveApp.getFolderById('id папки на гугл диске')
var template=DriveApp.getFileById('id файла шаблона в папке на гугл диске').makeCopy('Справка'+num,dirTemp).getId();
var docbody=DocumentApp.openById(template).getBody();
docbody.replaceText('DATA', realdata);
docbody.replaceText('NUMBER', num);
docbody.replaceText('ИМЯ', ima);
docbody.replaceText('КОММЕНТАРИЙ_', comm);
sheet.getRange(lastR, 6).setValue(template)
}
function getPdf(){
var ss=SpreadsheetApp.getActive();
var sheet=ss.getSheets()[0];
var dataRange=sheet.getDataRange().getValues();
for (var i=1;i<dataRange.length;i++){
if (dataRange[i][8]==""){
var filepdf=DriveApp.getFileById(dataRange[i][2]).getAs('application/pdf');
GmailApp.sendEmail(dataRange[i][2], 'Справка готова', 'Смотрите вложенный файл', {
attachments: [filepdf],
name: 'готово"'
});
sheet.getRange(i+1, 5).setValue('☑')
DriveApp.getFileById(dataRange[i][4]).setTrashed(true);
}
}
}
Доброго дня.
Удалить1. Проверьте столбец с датами - принудительно установите формат в дату.
2. Берётся лист таблицы который первый по списку - вполне может быть что данные попадают в другой лист. Или, как вариант, вы используете формулы в листе с ответами и id документа прописывается в самый низ листа таблицы
3. Не отправляется потому что см. п.2. Если id документа нет, то и отправлять нечего.
доброго дня, все поправила. Скрипт по заполнению формы срабатывает. все красиво - спасибо. id генерируется. Но функция getPDF ругается вот так:
ОтветитьУдалитьОшибка
Exception: Unexpected error while getting the method or property getFileById on object DriveApp.
getPdf
@ код 84
вот на эту строку
var filepdf=DriveApp.getFileById(dataRange[i][13]).getAs('application/pdf');
может у меня чего со столбцами не так
сам скрипт
function getPdf(){
var ss=SpreadsheetApp.getActive();
var sheet=ss.getSheets()[0];
var dataRange=sheet.getDataRange().getValues();
for (var i=1;i<dataRange.length;i++){
if (dataRange[i][13]==""){
var filepdf=DriveApp.getFileById(dataRange[i][13]).getAs('application/pdf');
GmailApp.sendEmail(dataRange[i][1], 'Талон готов', 'Смотрите вложенный файл', {
attachments: [filepdf],
name: 'Гарантийник 2021'
});
sheet.getRange(i+1, 15).setValue('отправлено на e-mail')
DriveApp.getFileById(dataRange[i][13]).setTrashed(true);
В таблице столбцы:
отметка времени (A), эл почта (B), ....id (N), отправлено (O)...
и когда ставлю триггер ежеминутно, то каждую минуту приходит сообщение о том, что триггер не исполнен)))))) спасибо.
Доброго.
УдалитьВ каком по счёту столбце генерируется id?
столбец 14 (N)
ОтветитьУдалитьif (dataRange[i][13]==""){
Удалить...
...
}
означает что то что внутри выполняется если id пустое. Вы точно этого хотите?
Ой Роман, не совсем я понимаю,))))))) я не сильный специалист по этому делу)))) насколько я вас поняла, если id пустое - то ничего выполняться и не должно.
ОтветитьУдалитьЕсли id сгенерирован - то шаблон PDF - отправляется адресату.
Вместо == поставьте != , тогда будет выполняться если id есть в таблице.
УдалитьРОМАН!!! Благодарю вас за ваш труд. Все отлично получается. В столбце где генерируется id (где он сгененирован) доки пришли на почтЫ ))) адресатам. Спасибо большое.
ОтветитьУдалитьЕще не все))))) скажите как правильно прописать вот, что: если в столбце (отправлено 15(O)) уже стоит отметка об отправке, то повторно этот файл на e-mail не отправлять.
ОтветитьУдалитьА то у меня получается, что отправка формы происходит с одного адреса (например 5 раз заполнили форму, и указали один эл. адрес), и после выполнения функции getPDF - на этот адрес приходит не последний созданный шаблон, а все 5 штук (а потом 6, а потом 7 и т.д.), каждый раз при заполнении формы)))))
В статье используется 2 функции:
Удалить1 - обрабатывает ответы приходящие из формы. Формирует копию шаблона с внесёнными данными.
2 - формирует ещё необработанные шаблоны, проверяя стоит ли знак в определённой ячейке.После отправки файла ставит тот самый знак ☑ в нужной ячейке.
Советую ещё раз прочитать статью и понять как это происходит.)
Итак))))) получается, что функция spravka формирует документ из шаблона, присваивает id документу, ставит этотм id в столбец 14-1=13 по счету. Функция getPDF формирует файл пдф и отсылает его, с условием, что в столбце 15-1=14 пусто. Значит вот тут if (dataRange[i][13]==""){, должен стоять столбец значка (14), если в нем пусто , то выполняется условие по отправке файла. var filepdf=DriveApp.getFileById(dataRange[i][13]).getAs('application/pdf'); а вот тут должен быть столбец с id (14-1=13). Правильно ли я вас поняла?
ОтветитьУдалитьПри таком моем понимании))))
ОтветитьУдалитьвыдает ошибку
Exception: Unexpected error while getting the method or property getFileById on object DriveApp.
getPdf
@ код 84
по
var filepdf=DriveApp.getFileById(dataRange[i][13]).getAs('application/pdf');
этой строке((((((((((
Удалите строки где в столбце с id пусто или не id.
УдалитьСпасибо Роман. Все получилось. Пришлось только забороть/добавить часовой пояс)))))) иначе давало в шаблоне Американское время, а это на день раньше)))))))))))
ОтветитьУдалитьДобрый день Роман. В таблице есть ссылка в строке на скан(pdf,jpg). Возможно ли отправить в письме с pdf еще и этот скан ?
ОтветитьУдалитьДоброго.
УдалитьНемного непонятно о какой таблице речь.
Например в таблицу с ответами добавить колонку где будет храниться ссылка на pdf или jpg (например: какие то фото данные).
ОтветитьУдалитьКак при отправке email с документом "справка" также отправить этот файл(pdf)
Доброго.
УдалитьС помощью UrlfetchApp.fetch получать файл, забирать blob, добавлять к письму. Так же как берётся blob справки в коде и добавляется.
Можно.
Добрый вечер, Роман! Подскажите пожалуйста, возможно ли подставлять фамилию и инициалы в название документа, если в таблице фамилия, имя и отчество прописаны полностью (в отдельных ячейках)? И можно ли использовать формулы в таблице каким-либо образом или в этом случае id всегда будут прописываться в последнюю строку? Буду очень благодарна за подсказку!
ОтветитьУдалитьДоброго дня.
УдалитьДля использования ФИО в названии документа, их нужно из таблицы взять как обычный текст и использовать метод substring(0,2) для получения только первой буквы для имени и отчества.
Лучше не смешивать формулы и скрипты, либо делать это с большой осторожностью. Данные из таблицы куда складываются ответы из формы можно импортировать на другой лист и там уже применять формулы.
Спасибо Вам большое, Роман! Вытащила инициалы с помощью substring
УдалитьРоман, а возможно сделать такое без использования гугл-формы? Чтобы в таблице данные заносил администратор и они выгружались в договор? И возможно ли у вас заказать подобную настройку?
ОтветитьУдалитьРоман, буду признателен, если найдете время ответить на пару глупых вопросов. Мой телеграмм: https://t.me/pashurin
ОтветитьУдалитьДоброго вечера. Здесь, в блоге можно задавать глупые вопросы.)
УдалитьКаждый третий день на предприятии сотрудники проходят тест на ковид. (За два года у нас уже 5 человек переболело, но все от сторонних источников). Соответственно каждому отсылают (Email, мессенджер) справку (без справки не пустят на объект). Вот это и делает скрипт.
ОтветитьУдалитьА теперь глупый вопрос:
"var day=data.getDate(),month=data.getMonth()+1,year=data.getFullYear();" в декабре будет 12+1=13? Поясните, пожалуйста, подробно
И, да, триггер(как направление, о чем прочесть желающим):
after(durationMilliseconds)
// Creates a trigger that runs 10 minutes later
ScriptApp.newTrigger("myFunction")
.timeBased()
.after(10 * 60 * 1000)
.create();
И, конечно, спасибо автору.
Доброго.
УдалитьВ javascript getMonth возвращает номер месяца, для января 0, февраля 1......декабря 11. +1 нужен только для того чтобы перевести номер месяца на человеческий.
Программная установка триггера вещь хорошая, но как уже отвечал в одном из комментариев лучше использовать saveAndClose() для того чтобы объединить два триггера в один и отправлять файлы сразу после получения ответа формы.
Добрый день! Подскажете, в чем проблема?
ОтветитьУдалитьПри компиляции GS
var docBody = DocumentApp.openById(template).getBody();
выдает
Exception: Вам не разрешено вызывать пользователя DocumentApp.openById. Необходимые разрешения: https://www.googleapis.com/auth/documents. (строка 41, файл Код)СведенияЗакрыть
Доброго дня.
УдалитьСкорее всего скопировали мой код в старый какой то свой проект в котором вручную прописаны права. Попробуйте создать новую форму с новой таблицей.
Нет, набирал сам))) Проблема с правами доступа к диску была. Спасибо, разобрался!
УдалитьРоман, добрый день !
ОтветитьУдалитьЭто Гугл таблица, которая заполняется Гугл формой.
A B C D E
07.04.2022 15:20:44 ООО "Хорошее" Санкт-Петербург, Цветочная, д. 1, лит.Б Иванов И.А. ivanovia@mail.ru
//Переменная e-mail адреса Абонента
var emab = abonentData[0][4];
docBody.replaceText('email', emab);//4 e-mail адрес Абонента
При выполнении скрипт в документ подставляет
ivanovia@20ail.ru вместо ivanovia@mail.ru
Что это может быть?
Заранее спасибо.
Доброго дня. Искать среди других строчек ivanovia@20ail.ru.
УдалитьУвы нет других таких строчек (((
УдалитьСкорее всего в коде меняете слово mail на 20ail? m заменяете на 20? Ещё может быть что после @ стоит пробел в ответе.
УдалитьРазобрался! Спасибо! Дело было в названиях переменных - длина и совпадение )
УдалитьРоман, добрый день !
ОтветитьУдалитьПодскажите пожалуйста, что я делаю не так?
Создал всё как описано, форма есть, шаблон есть, таблица со скриптом на месте, триггеры выставлены, при заполнении формы в таблицу вписываются данные, создается документ, но он не преобразуется в pdf, на почту приходит письмо без вложения с текстом "[object Object]". Может что-то упустил.
Доброго дня. Значит что-то упускаете из виду. Проверьте ещё раз код.
УдалитьЗдравствуйте. Как решить такую проблему что при вводе неверного адреса почты или ввода адреса на русском языке ничего не отправляется и далее все ответы, которые получены через гугл форму не отправляются?
ОтветитьУдалитьДоброго дня. Удалить строку вручную.
УдалитьНа худой конец помещать отправку в try catch.
УдалитьРоман, здравствуйте! Отличный пример автоматизации. Ваша открытость и желание помогать другим вызывают уважение. Вы молодец! Прекрасная работа! Мы столкнулись с похожей задачей по формированию заявок из данных в таблице. Хотели бы обратиться к Вам за помощью в создании скрипта. Будем рады сотрудничеству: +79035892695. Еще раз спасибо за Ваш труд!
ОтветитьУдалитьРоман, добрый день!
ОтветитьУдалитьПодскажите, возможно написать такую же формулу только на перенос данных с гугл таблице в другую гугл таблицу, с нужного листа в другой нужный лист. Так же не очень понимаю как эти все действия сгенерировать на работу с участием импровизированной иконки с макросом. Как пример: есть исходная таблица, в которую периодически вносятся какие то данные, строки в первой коленке определены флажком. Вот при выборе определенной строки флажком, нажать на иконку с макросом запустить функцию заполнения данных из строк в тело шаблона другой Гугл таблицы.
Подскажите, такое вообще возможно?
Пока что не понимаю о чём Вы спрашиваете. Может сможете, для начала, более детально обратиться по электронке igro83@gmail.com
УдалитьЗдравствуйте, Роман.
ОтветитьУдалитьПомогите, пожалуйста. Что не так?
При выполнении выдает ошибку
Ошибка
Exception: The document is inaccessible. Please try again later.
строка -
var docbody=DocumentApp.openById(template).getBody();
сам скрипт:
function dogovor() {
var ss=SpreadsheetApp.getActive();
var sheet=ss.getSheets()[0];
var lastR=sheet.getLastRow();
var clientData=sheet.getRange(lastR,1,1,20).getValues();
var data=new Date(clientData[0][0]);
var day=data.getDate(),month=data.getMonth()+1,year=data.getFullYear();
if (month<10){
month="0"+month;
}
var realdata=day+'.'+month+'.'+year;
var num=lastR-1;
var IMIEPROJEKTANT=clientData[0][2];
var IMIEKLIENT=clientData[0][3];
var PASSPORTSERIA=clientData[0][6];
var PASSPORTNOMER=clientData[0][7];
var NUMERPESEL=clientData[0][8];
var ADRESKLIENT=clientData[0][4];
var ADRESDOSTAVKA=clientData[0][5];
var KONTAKTTEL=clientData[0][9];
var KONTAKTMAIL=clientData[0][10];
var CENABRUTTO=clientData[0][11];
var CENASLOWNIE=clientData[0][12];
var CENAPREDOPLATA=clientData[0][13];
var CENA1SLOWNIE=clientData[0][14];
var CENAOSTATOK=clientData[0][15];
var CENA2SLOWNIE=clientData[0][16];
var CENAMONTAZ=clientData[0][17];
var CENA3SLOWNIE=clientData[0][18];
var dirTemp=DriveApp.getFolderById('1YWvAzCSDxXCgullPage5uqNW8BrBnGJa')
var template=DriveApp.getFileById('1uoa-u8CiDgvtEjVz7EJjqTokhDt2VZ40').makeCopy('ДОГОВОР'+ '_'+ num + '-ZK24' ,dirTemp).getId();
var docbody=DocumentApp.openById(template).getBody();
docbody.replaceText('DATA', data);
docbody.replaceText('NUMBER', num);
docbody.replaceText('IMIEPROJEKTANT', IMIEPROJEKTANT);
docbody.replaceText('IMIEKLIENT', IMIEKLIENT);
docbody.replaceText('PASSPORTSERIA', PASSPORTSERIA);
docbody.replaceText('PASSPORTNOMER', PASSPORTNOMER);
docbody.replaceText('NUMERPESEL', NUMERPESEL);
docbody.replaceText('ADRESKLIENT', ADRESKLIENT);
docbody.replaceText('ADRESDOSTAVKA', ADRESDOSTAVKA);
docbody.replaceText('KONTAKTTEL', KONTAKTTEL);
docbody.replaceText('KONTAKTMAIL', KONTAKTMAIL);
docbody.replaceText('CENABRUTTO', CENABRUTTO);
docbody.replaceText('CENASLOWNIE', CENASLOWNIE);
docbody.replaceText('CENAPREDOPLATA', CENAPREDOPLATA);
docbody.replaceText('CENA1SLOWNIE', CENA1SLOWNIE);
docbody.replaceText('CENAOSTATOK', CENAOSTATOK);
docbody.replaceText('CENA2SLOWNIE', CENA2SLOWNIE);
docbody.replaceText('CENA3SLOWNIE', CENA3SLOWNIE);
sheet.getRange(lastR, 21).setValue(template)
}
function getPdf(){
var ss=SpreadsheetApp.getActive();
var sheet=ss.getSheets()[0];
var dataRange=sheet.getDataRange().getValues();
for (var i=1;i<dataRange.length;i++){
if (dataRange[i][21]==""){
var filepdf=DriveApp.getFileById(dataRange[i][20]).getAs('application/pdf');
GmailApp.sendEmail(dataRange[i][1], 'ДОГОВОР во вложении' , {
attachments: [filepdf],
name: 'ДОГОВОР'
});
sheet.getRange(i+1, 22).setValue('☑')
/*DriveApp.getFileById(dataRange[i][3]).setTrashed(true);*/
}
}
}
Доброго дня. Скорее всего, вы используете документ Word в качестве шаблона.
УдалитьРоман Добрый день, скажите пжл у меня что то типо этого создано(из шаблона формируется копия, подставляются значения из таблицы, новый файл сохраняется в папке!Все хорошо, имя тоже всегда новое, соответствует номеру договора,но нужно чтобы этот договор открывался после его формирования, как дописать скрипт, нигде не могу найти?подскажите если не сложно!думаю там не сложно, просто не хватает знаний!спасибо
ОтветитьУдалитьЗдравствуйте, решил протестировать способ и сделал всё по инструкции, однако при нажатии на кнопку в Гугл-форме "Отправить" в таблице автоматически не присваивается id и не отправляется на емайл сформированная справка, но если перейти в Гугл-таблицу (связана с гугл-формой) и выполнить макросы - выбрав spravka, то в ячейке столбца id появляется сгенерированное id сформированной готовой справки, точно также приходится нажимать на макрос getPdf и только после этого сформированная справка в pdf успешно направляется на e-mail.
ОтветитьУдалитьПодскажите пожалуйста, как автоматизировать процесс, чтобы при нажатии после заполнения Гугл-формы при нажатии на кнопку "Отправить" автоматически бы сформированная справка отправилась бы на е-майл (который в поле прописывается как в примере данной публикации)? Т.е. чтобы автоматизировался процесс и не надо было вручную в гугл-таблице выполнять маркрос выбивая spravka и потом ещё getPdf.
А, всё, решён вопрос, забыли тригеры создать. Теперь всё отлично автоматически отправляется. Спасибо автору за публикацию.
УдалитьАвтор публикации, опубликуйте какие-либо реквизиты, чтобы донат закинуть за такой полезный скрипт.
УдалитьА как сделать, чтобы приходил на е-майл файл в формате .docx или .doc? Лучше конечно .docx, а не .doc, а то моментами .pdf файл не совсем нужен.
ОтветитьУдалитьПытаемся как-то сделать, но скринт при попытке направить на е-майл пишет, что
"Exception: Преобразование из формата application/vnd.google-apps.document в формат application/msword не поддерживается."
Пишут тут по ссылке
https://translated.turbopages.org/proxy_u/en-ru.ru.3bb52a70-6660f8ed-08f5717d-74722d776562/https/stackoverflow.com/questions/77752561/how-to-convert-docx-files-to-google-docs-with-apps-script-2024-drive-api-v3
что это можно через конвертацию, но замудрённо.
Вообщем, попробую по данному вопросу связаться напрямую с автором данной публикации с просьбой помочь платно, а то pdf не совсем нужен на е-майл и в идеале бы нужен именно .docx, а не .doc, но .doc тоже сойдёт если невозможно реализовать .docx.