Ответы пользователя по тегу Google Apps Script
  • Как сделать что бы при ставке чисел убирались лишние символы в гугл док?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Если данные заполняются оператором, то скорей всего, ему потребуется инструмент для нормализации данных. Это может быть как локальная программа, например, расширение браузера, так и дополнение к самим Таблицам.

    Пример работы дополнения.
    Пользователь открывает боковое меню, которое остается открытым весь период работы
    5aba02ef6e9b3253891467.png

    Добавляет значение из буфера в верхнее поле, получает результат в нижнем поле. Возможно заполнение буфера новым значением автоматически
    5aba03516b237273893919.png
    Ответ написан
    Комментировать
  • Превышено максимальное время выполнения Google Script, как решить?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Ваш же вопрос тут Максимальное время выполнения скрипта Google Script

    К тому же не ведете переписку по другим вопросам.

    Вы не можете преодолеть пердел исполнения в 6 минут. Для того, чтобы получить результаты поиска при повторном запуске скрипта, вы должны сохранить во внешнем хранилище значение токена, который действет неделю.

    if (continuationToken == null) {
      var files = DriveApp.getFiles();
    } else {
      var files = DriveApp.continueFileIterator(continuationToken);
    }
    где continuationToken заранее получен и извлечен из внешнего хранилища.
    
    if(files.hasNext()){
      var continuationToken = files.getContinuationToken();

    Для автоматического перезапуска скрипта вы должны создавать триггеры времени.

    Чтобы представить всю масштабность задачи, можете взглянуть на готовое приложение для копирования Диска ericyd/gdrive-copy

    Также существует несколько сниппетов и библиотек, которые позволяют "продлить" исполнение тем же методом, который я описал выше.
    Ответ написан
    Комментировать
  • Как сделать, чтобы функция срабатывала, когда значение ячейки в таблице меняется формулой?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Виктор Фамильевич, никак. Это особенность среды исполнения.

    Но у вас нет причин искать вызова триггера при таких условиях. Что-то же меняет это значение? Подпишитесь на изменение этого "что-то же" или дублируйте их.
    Ответ написан
    Комментировать
  • Где ошибка в коде Google Script для экспорта в txt?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Замените
    var values = SpreadSheets.getRange(i, c).getValue();

    на
    var values = SpreadSheets.getRange(i, c).getValues();


    Но я бы так не делал. Диск - сложная экосистема датчиков и инициирующих событий. Возможно, вы могли бы несколько углубиться в изучение и постичь дзен событийной модели, авось, что-то будет работать более плавно и без сбоев, и реально онлайн.
    Ответ написан
    Комментировать
  • Как правильно использовать LockService в Google Apps Script?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Метод waitLock вызывает исключение, обрабатывайте его.

    var lock = LockService.getPublicLock();
    try {
      lock.waitLock(30000);
      return success();
    } catch (err) {
      Logger.log('Could not obtain lock after 30 seconds.');
      return failure();
    }


    Для неразрывности функции используйте tryLock. Этот метод заворачивает результат блокировки в булево значение:
    var lock = LockService.getPublicLock();
    var success = lock.tryLock(30000);
    if (!success) {
      Logger.log('Could not obtain lock after 30 seconds.');
    }
    Ответ написан
    Комментировать
  • Как в Google Apps Script отличить запуск ф-ии по триггеру своего и чужого аккаунта?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Возможно, вы уже читали статью "Эффективный пользователь против Активного", на основании которой ваш вопрос можно считать риторическим. Если у вас, конечно, gmail аккаунт, а не G Suite.

    Подтверждая ваши слова, вам необходимо создать один standalone скрипт. Позволить каждому пользователю зарегистрировать триггер - каждый сам себе. При такой настройке, во время срабатывания скрипта для каждого владельца скрипта в Active User будет его email, иначе пусто.

    Но тут существует подводный камень. Это не всегда работает. В какой-то момент Google раскрыл для владельцев (не G Suite) адреса Effective Users. Это было неприятно. Представьте, я даю вам доступ по ссылке, вы открываете Таблицу, а мой триггер onOpen уже знает, кто вы есть (ну, как минимум ваш адрес электронной почты). Что было делать - отрубить и не давать.

    Как можно решать вашу проблему? Нет эффективных методов решения этой задачи. Они либо громоздкие, либо слишком мутные, чтобы оставаться в рабочем состоянии долгое время.

    Я одно время использовал монитор почты, но пользователю необходимо подписаться на изменения в Таблице. Может быть в новом API есть возможность подписать пользователя автоматически?
    Ответ написан
    3 комментария
  • Как передать группу значений checkbox в форме?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    [Ljava.lang.Object;@556935f1 - это массив. Таблицы не поддерживают сложные типы. Попробуйте привести массив к строке.
    Вместо form['checkbox_name[]']
    можно form['checkbox_name[]'].join(', ')
    или JSON.stringify(form['checkbox_name[]'])
    как вариант предыдущего
    JSON.stringify(form['checkbox_name[]'], null, '  ')
    Ответ написан
    1 комментарий
  • Как отобразить в Таблице текст со страницы?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Никак.

    Такой возможности нет, потому что, скорей всего, контент на странице состоит из компонентов, которые требуют работы браузера, а в Таблицах такой возможности нет.

    Можете попробовать сами любую функцию импорта или скрипт
    UrlFetchApp.fetch('https://www.pochta.ru/tracking#RG886664219CN').getContentText();


    С уважением.
    Ответ написан
  • Как скачать файл средствами google apps script?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Вариантов загрузки может быть несколько. Как и способов создания файла. Из вопроса не ясно, как создается файл, каие требования предъявляются к загрузке, какой интерфейс используется.
    Предположим, что:
    1. Файл создается в момент загрузки
    2. Файл сохраняется на Диске
    3. Файл загружается через основной интерфейс приложения Таблицы Google

    Основной идеей экспорта/скачивания файлов из Диска является получение ссылки на ресурс
    var file = DriveApp.createFile(fileName, content, 'text/html');
    var downloadUrl = file.getDownloadUrl();

    Теперь достаточно создать событие на стороне клиента, котрое вызовет загрузку. Вариантов может быть несколько. Вот один из них:
    // Создаем окно на клиенте и запускаем
    var a = window.document.createElement('a');
    a.href = downloadUrl;
    a.text = 'Download';
    document.body.appendChild(a);
    a.click();

    В данном месте самое сложное - поставить пользователю интерфейс для реализации загрузки. Это может быть и письмо, и нотификация, и все, что угодно, что может нажимать ссылки.

    Другим вариантом может быть поставка блока данных через Client-side API. Принцип останется прежним, изменится только формат передаваемых данных. С сервера Blob, на клиенте загрузка локального Blob-ресурса.

    Полный код и ссылка на рабочее приложение https://gitlab.com/google-apps-script-russian/zagr...
    Ответ написан
    Комментировать
  • Почему "После списка аргументов отсутствует закрывающая круглая скобка (")"). (строка 2, файл Код)"?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Скорей всего проблема в использовании символа ";". В языке Google Apps Script он используется как разделитель команд интерпретатору. Вы не можете их использовать в таком контексте.
    Ответ написан
    Комментировать
  • Как разрешить Google Apps Script отправлять email для любого пользователя Spreadsheet?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Описания недостаточно, код не видно, хотя, можно уже предполагать, где скрывается ошибка. Разделите понятия:

    Судя по описанию, User-B прошел авторизацию, а остальные пользователи нет. Заставьте этих пользователей пройти авторизацию, и у них появится разрешение на запуск функций.

    Как заставить пользователей авторизоваться - это проблема разработчика, а не Google. Но, не имея в техническом плане серьезных противоречий, этот подход сложен для понимания практического. Примеры приложений, код которых может быть одинаков до запятой.
    • Отправить присьмо при изменении. Простой триггер onEdit(). Может отпрвлять только то, кто прошел авторизацию.
    • Отправить присьмо при изменении. Устанавливаемый триггер. Триггер установлен кем-то одним. Может отпрвлять только то, кто прошел авторизацию, т.е. один. Письма будут приходить согласно условию в коде.
    • Отправить присьмо при изменении. Устанавливаемый триггер. Триггер установлен каждым умником, кто залез в код. Может отпрвлять только тот, кто прошел авторизацию. Письма будут приходить согласно условию в коде умноженное на количество умников, потому что это будет один и тот же код, срабатываемый для каждого триггера в каждом аккаунте.

    Разрабатывая клиент-серверное приложение, вам необходимо заботиться о многопользовательском доступе. Необходимо разработать процесс и порядок доступа, и только после этого разбираться, как это реализовать. Например,
    • Каждый пользователь сам себе будет отправлять письма? Зачем и нах!?
    • Каждый пользователь будет отправлять письма на заданный адрес?
    • Письма будет отправлять только один аккаунт всем участникам подписки, группе, редакторам и т.д.?
    • Письма будет отправлять только один аккаунт, тому кто совершил изменения? Для аккаунтов googlemail.com это недоступно.

    Лично мне было бы неприятно, что кто-то требует от меня отпрвлять непонятно куда и зачем какие-то письма, выжирая и так скудную квоту.

    Пересмотрите свое приложение. Какие цели оно преследует? Чего вы уже добились? Так ли это работает? Приведите пример кода и суть приложения.
    Ответ написан
    1 комментарий
  • Метод getFilesByName() не находит файлы, если в имени с кириллицей присутствуют буквы в верхнем регистре?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Как раз сейчас описываю этот баг. Поставьте звездочку тут.

    Используйте менее точный поиск с дополнительной обработкой результатов. И сервис DriveApp и сервис Drive умеют в строке запроса обрабатывать директиву title contains. См. Search for Files. На данный момент, 2017-08-13, используется API v2, и для поиска в данном случае - это принципиально. Следующий код вернет то, что вы ожидаете:
    function getFileByName(name) { 
      var files = DriveApp.searchFiles(Utilities.formatString('title contains "%s" and trashed=false', name));
      var result = undefined;
      while(files.hasNext()){
        var file = files.next();
        if(file.getName() === name){
          result = file;
          break;
        }
      }
      return result;
    }
    Ответ написан
  • Как связать 2 Google Form между собой?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Задача нетривиальная. Даже не знаю, стоит ли ее решать через Google Apps Script.

    Положим, что есть две Формы. Во-первых, необходимо место под генерацию промокодов. А это должна быть Таблица. Во-вторых, при использовании промокода необходимо выяснить его валидность. А, ну далее продолжать не стоит - Формы неинтерактивны. Форма - это интерфейс сбора информации. Интерфейс - это совокупность средств, методов и правил взаимодействия, в котором нет возможности обратной связи. У разработчика нет доступа к реализации таких методов как загрузка Формы, проверка данных на стороне клиента и пр. Т.е. разработчик не в состоянии реализовать интерфейс Форм.
    Ему доступен интерфейс хранилища Форм. Т.е. разработчик может обратиться по адресу к Форме, получить ее данные, изменить ее свойства.

    Только качественный и проверенный контент
    Ответ написан
  • Как настроить автоответчик писем на заполнение форм на разных языках?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    У вас этот код никогда не заработает нормально. Почитайте комментарии на приведенном вами ресурсе.

    Главная ошибка - это ссылка на активную Таблицу SpreadsheetApp.getActiveSpreadsheet(); В триггере OnFormSubmit не может быть активной Таблицы, потому что никакой пользователь ее не открыл. А если даже и открыл, то он может не быть регистратором триггера или его инициатором.

    Обработка ошибок
    Google Apps Script (речь о данном моменте времени развития языка) не имеет развитых методов отладки. Поэтому обвяжите основной вызов:
    /**
    * В Таблице должен быть лист "Лог".
    * Чтобы лист существовал всегда
    * https://github.com/oshliaer/google-apps-script-snippets#get-a-sheet-by-name
    **/
    function handler(e) {
      try {
        sendFormByEmail(getNewEmailMessage(e));
      } catch(err) {
        e.source.getSheetByName('Лог').appendRow([new Date(), err.message, err.stack]);
      }
    }

    Отлично, теперь все, что упало в рантайме, будет вам известно.

    Текущая Таблица/Лист
    Я приываю не только автора топика, но вообще всех: "Пожалуйста, не трогайте ActiveSpreadsheet, ActiveSheet и ActiveRange, т.к. это не VBA. Это #ВАЩЕ_НАФИГ_ДРУГАЯ_ВСЕЛЕННАЯ!". Обратите внимание на код выше e.source.getSheetByName(). Это все, что надо.
    А вот пример комутатора:
    /**
    * Определение языка на основе ответа
    **/
    function getNewEmailMessage(e) {
      var sheet = e.range.getSheet();
      var lang = 'EN';
      switch(sheet.getName()){
        case 'RU':
           return 'Ответ на русском';
           break;
        case 'EN':
           return 'Ответ на нерусском';
           break;
      }
      return 'Ответ на русском';
    }

    Осталось добавить аргументов и переписать sendFormByEmail согласно принимаемым параметрам.

    Триггер на несколько Форм

    Вместо заключения
    Только качественный и проверенный контент
    Ответ написан
    4 комментария
  • Почему не работает Get запрос в Google Apps Script через file_get_contents?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Виктор Фамильевич, для того, чтобы вызвать такой запрос, ваш сервер должен передать код аутентификации владельца или редактора проекта скрипта в заголовках. Это необходимо потому, что вызывается url разработчика для тестирования. Т.е. этот адрес нельзя использовать для нормальной работы.

    Самый простой способ вызвать корректно сервис - это опубликовать его. Ссылки очень легко отличаются по своим окончаниям:
    • /dev - адрес для тестирования
    • /exec - текщий адрес приложения


    Подробности Web Apps / Deploying a script as a web app
    Консультации по GS
    Ответ написан
    Комментировать
  • Удобоваримые ответы из google forms в spreadsheet, как правильно?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Не используйте "обработку формулой по триггеру" в данном случае. Вам просто необходим скрипт, который будет преобразовывать текущие данные в подходящие для отчета формы. Без примера сложно сказать, как именно необходимо разделить данные, но в общем случае это будет выглядеть как-то так https://productforums.google.com/forum/#!topic/doc... Там задача несколько сложнее чем у вас, рассчитываются веса вхождений для каждого ответа. Скопируйте Таблицу, в ней появится меню генерации отчета.

    Консультации https://google-apps-script-russian.gitlab.io/page/...
    Ответ написан
    Комментировать
  • Как работать в google script с защищенными листами google таблиц?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Вам нужны два скрипта:
    1. Сервер-приемник (запускается от имени владельца защищенного диапазона)
    2. Программа-инициатор (запускается от имени пользователя)


    Вам необходимо будет решить несколько проблем:
    • Определение подлинности программы-инициатора на сервере
    • Контроль команд на выполнение
    • Согласованная разработка и поддержка двух программ
    Ответ написан
    Комментировать
  • Как заставить работать скрипт дистанционно?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Рассмотрите две возможные проблемы:

    Во-первых. Прежде чем отправлять запрос, ваше приложение должно авторизоваться через и получить токен.
    This method requires authorization with an OAuth 2.0 token that includes at least one of the scopes listed in the Authorization section; script projects that do not require authorization cannot be executed through this API.


    Во-вторых: У вас 404 ошибка. Ресурс не найден. Проверьте коррекность адреса
    POST https://script.googleapis.com/v1/scripts/{scriptId}:run

    В данном случае {scriptId} - это уникальный номер самого скрипта, который находится в меню Файл - Свойства проекта - Ключ проекта

    Если вы не хотите авторизовываться, но вам очень надо отправить POST, попробуйте
    function doPost(e) {
      return ContentService.createTextOutput(JSON.stringify({status: 'ok'}))
        .setMimeType(ContentService.MimeType.JSON);
    }


    Но, тогда вам необходимо опубликовать скрипт как веб-приложение и разрешить доступ на выполнение для всех, даже анонимных пользователей.

    Добавлено

    Еще одной частой проблемой является необходимость вручную добавить в файл манифеста области видимости для скрипта, чтобы он мог иметь доступ к Script API.
    Ответ написан
    1 комментарий
  • Как сделать выпадающий список с добавлением новых элементов?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Здравствуйте,

    доступа к манипулированию IU нет. Добавят ли разработчики эту особенность неизвестно. Вопрос был поднят больше года назад на импортном форуме по Диску. Тогда из вариантов был сайдбар, но это неудобно.

    Идея larionov_n похожа на выстрел из пушки по воробьям. Почему бы тогда не использовать нормальную БД вместо кастрированного табличного процессора? Но, в то же время, могу сказать, что манипулирование Таблицей через внешнее приложение с AngularJS на фронте самое популярное в моих заказах. Т.е. на свой вопрос я найти ответа не могу.
    Ответ написан
    Комментировать
  • Как избежать timout в 6 минут при разработке дополнения?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Здравствуйте.

    Никак.
    Script runtime 6 min / execution и добавьте к ним Triggers total runtime 1 hr / day , а еще URL Fetch data received 50MB / day (хотя не понятно, что вы там такое втягиваете). Вам необходимо завести собственный сервер.

    Еще возможно, что страдает логика приложения.

    С уважением.
    Ответ написан
    1 комментарий