Задать вопрос
  • Как в spreadsheets задать фиксированную высоту ячейки?

    oshliaer
    @oshliaer Куратор тега Google Sheets
    Google Products Expert
    Никак. Многострочные ячейки будут отображаться по высоте количества строк в их.
    Ответ написан
    Комментировать
  • Как правильно использовать 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 drive?

    oshliaer
    @oshliaer
    Google Products Expert
    В идеальном случае, когда все сделано правильно, пользователь должен был предоставить ссылку на папку, которую вы можете добавить к себе на Диск или загрузить как zip-архив.

    Я предпочитаю в данном случае rclone.org:
    rclone copy drive:SharedFolder /tmp/SharedFolder

    Другой способ - получить прямые ссылки на загрузку оригинального файла. Например, используя Gogole Apps Script #пример

    5a16addc560ef766126864.png

    1. Скопируйте файл
    2. Добавьте свои URL в колонку A
    3. Вызовите пользовательское меню. Будет заполнена колонка D


    Далее можно кликать список или добавить его в менеджер загрузок, или сохранить в файл для wget/curl
    Ответ написан
    Комментировать
  • Как организовать сбор изменения цен в Гугл таблице?

    oshliaer
    @oshliaer Куратор тега Google Sheets
    Google Products Expert
    Можно использовать Google Apps Script

    Самый простой способ
    Запустите триггер основанный на времени для функции myF

    function myF(){
      var data = get_();
      Logger.log(data);
      append_(data);
    }
    
    function get_(){
      var sheet = SpreadsheetApp.openById("986327f36403948feb4a")
        .getSheetByName("Sheet1");
      return sheet.getDataRange().getValues().slice(sheet.getFrozenRows());
    }
    
    function append_(data){
      var d = new Date();
      var values = data.map(function(row){
        row.unshift(this.d);
        return row;
      }, {d:d});
      var sheet = SpreadsheetApp.openById("579e832d1ced2a2cc76c")
        .getSheetByName("Sheet2");
      sheet.getRange(sheet.getLastRow() + 1, 1, values.length, values[0].length).setValues(values);
    }


    Правильный способ

    Вам необходимо реализовать функцию, которая будет получать данные с сайта, преобразовывать их в табличный вид data и добавлять в Таблицу append_(data). Добавить эту функцию в триггер основанный на времени.
    Ответ написан
    Комментировать
  • Как в 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 комментария
  • Как в Google sheets пропускать строку, если ЛОЖЬ?

    oshliaer
    @oshliaer Куратор тега Google Sheets
    Google Products Expert
    Я бы предпочел для этой задачи QUERY. VLOOKUP хорош, но как-то он ни к селу ни к городу в данном случае.

    5a0eaf8d354c4705112266.png

    Пример Таблицы https://docs.google.com/spreadsheets/d/1NvXvZbXXcD...

    Сама формула
    =QUERY('Данные'!A:K;"select D, E, F, H, I where C='Белградская'")

    Формула в контексте задачи
    =QUERY(K:U;"select N, O, P, R, Q where M='Белградская'")


    Другим вариантом может быть формула FILTER. Сказать по правде, она более "универсальна"
    =FILTER({'Данные'!D2:F\'Данные'!H2:I};'Данные'!C2:C="Белградская")


    5a11a5023b426818811811.png
    Ответ написан
  • Как передать группу значений 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 Sheets
    Google Products Expert
    Один из вариантов решения задачи был в Сообществе Диска

    Формула минимальной цены
    =FILTER('данные'!A1:E14;MMULT(('данные'!A1:A14=TRANSPOSE('данные'!A1:A14))*('данные'!B1:B14>TRANSPOSE('данные'!B1:B14));SIGN(ROW('данные'!B1:B14)))=0)
    Ответ написан
  • Как в гугл-таблице автоматически выделять цветом текст?

    oshliaer
    @oshliaer Куратор тега Google Sheets
    Google Products Expert
    Эта опция не реализована. Вы можете следить за развитием на треккере Google Apps Script Handle parts of cell content programmatically
    Ответ написан
    Комментировать
  • Как привязать рисунок к ячейке?

    oshliaer
    @oshliaer Куратор тега Google Sheets
    Google Products Expert
    Эта опция не доступна для программирования.

    Эта опция доступна с 2022 года. См. класс CellImage

    Просто пример

    /**
     * @param {globalThis.SpreadsheetApp.Range} cell
     * @param {string} imageUrl
     * @param {string} altTitle
     * @param {string} altDescription
     * @returns {void}
     */
    function insertCellImage(cell, imageUrl, altTitle = '', altDescription = '') {
      const image = SpreadsheetApp.newCellImage()
        .setSourceUrl(imageUrl)
        .setAltTextTitle(altTitle)
        .setAltTextDescription(altDescription)
        .build();
      cell.setValue(image);
    }
    Ответ написан
    Комментировать
  • Как можно создать ячейку-счетчик времени в Гугл Таблицах?

    oshliaer
    @oshliaer Куратор тега Google Sheets
    Google Products Expert
    Вы можете использовать формулы NOW() и TODAY(). Например, дата погашения в ячейке
    B5
    тогда, чтобы получить дни просрочки достаточно вставить формулу
    =TODAY()-B5
    Чуть сложнее, когда дата не наступила, ничего не выводим
    =IF(TODAY()-B5>0;TODAY()-B5;"")

    Пример
    59f398e017818277881969.png
    Ответ написан
    Комментировать
  • Как в Таблицах окрашивать ячейку если её значение кратно 8?

    oshliaer
    @oshliaer Куратор тега Google Sheets
    Google Products Expert
    Для диапазона
    A6:A
    пользовательская формула
    =AND(NOT(ISBLANK($A6));MOD(SUM($D6:$AB6);8)=0)

    59f39353d1ec9007358712.png
    Ответ написан
  • Как отобразить в Таблице текст со страницы?

    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...
    Ответ написан
    Комментировать
  • Можно ли создавать свои формулы в Googl Spreadsheets?

    oshliaer
    @oshliaer Куратор тега Google Sheets
    Google Products Expert
    Да, можно использовать Google Apps Script для создания так называемых пользовательских функций. Обратите внимание, что в них нельзя использовать формулы из табличного редактора. Т.е. вместо ARRAYFORMULA необходимо будет обойти весь массив в цикле и т.п.

    https://developers.google.com/apps-script/guides/s...
    Ответ написан
    Комментировать
  • Почему "После списка аргументов отсутствует закрывающая круглая скобка (")"). (строка 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.

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

    Только качественный и проверенный контент
    Ответ написан