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

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Вероятнее всего вы удаляете чужие файлы из чужой папки. Выводите в лог то, что выдает ошибку

    try {
      Drive.Files.trash(file.getId());
    } catch (err) {
      console.log(err.message, file.getName());
    }


    Или исключите файлы, которые вы не можете удалять

    let files = DriveApp.getFolderById(tempFolderId)
      .searchFiles('"me" in owners and title != "nothing"');
    Ответ написан
    Комментировать
  • Как подсчитать долю без промежуточной колонки?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    6089a3d8e7bd2069729294.png

    Ну, наверное, это MMULT результатов MMULT

    =INDEX(
      MMULT(
        N(ARRAY_CONSTRAIN(C2:Z/(MMULT(TRANSPOSE(ROW(C2:Z)^0);N(C2:Z)));
        MATCH(2;1/(B2:B<>"");1);
        MATCH(2;1/(C1:1<>"");1)));
        SEQUENCE(MATCH(2;1/(C1:1<>"");1);1)^0)/MATCH(2;1/(C1:1<>"");1)
    )


    Пример и полезные ссылки в Таблице.

    Техника MATCH(2;1/(B2:B<>"");1) может быть избыточна в том смысле, что это поиск последнего действительного значения для обрезки. Если вы будете содержать последовательности заголовков событий и игроков без пробелов, то действительно следующее

    =INDEX(
      MMULT(
        N(ARRAY_CONSTRAIN(C2:Z/(MMULT(TRANSPOSE(ROW(C2:Z)^0);N(C2:Z)));
        COUNTA(B2:B);
        COUNTA(C1:1)));
        SEQUENCE(COUNTA(C1:1);1)^0)/COUNTA(C1:1)
    )


    Диаграмма на скрине приведена неслучайно. Она показывает, что общий вес расчета равен 100%, как проверка.

    С скриптом не стал заморачиваться, но, доверяя Григорий Боев, думаю, что пользовательская функция при должной проработке будет более гибкой. Выбор зависит от конечной цели и циклов проработки результатов и будущих улучшений Таблицы.
    Ответ написан
    Комментировать
  • Как обработать ответ url.fetch, который приходит в UTF-8 without BOM?

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

    В данном случае вы получаете текст, а сервис API гарантирует, что тело ответа в формате JSON (тоже текст!). Чтобы представить форматированные данные в виде ресурса языка программирования (для JS - это объекты корневого предка) достаточно распарсить этот текст.

    if(respons.getResponseCode()){
      const data = JSON.parse(respons.getContentText());
      console.log(data.info);
    }


    Как дополнение. Стоит отметить, что парсинг внешнего текста является исключительной операцией, поэтому при ошибке парсинга, чтобы гарантировать порядок выполнения кода, среда (то что выполняет JS) выбросит исключение.

    > JSON.parse('rewt{')
    < VM240:1 Uncaught SyntaxError: Unexpected token r in JSON at position 0
        at JSON.parse (<anonymous>)
        at <anonymous>:1:6


    Ответ написан
    Комментировать
  • Как запустить скрипт с телефона?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    На данный момент универсальный запуск дополненией в различных приложениях для устройств реализован для Gmail и Календаря.

    К примеру, мое дополнение работает как в браузере так и в приложении Gmail на Android601b66f6b307b246403865.gif

    Поэтому построить интерфейс для Таблиц пока нельзя.
    Ответ написан
  • Как вставить картинку непосредственно в ячейку Таблицы?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Решение на данный момент

    function insertImageToCell() {
      const image = SpreadsheetApp
        .newCellImage()
        .setSourceUrl('https://upload.wikimedia.org/wikipedia/commons/5/50/Smile_Image.png')
        .build();
      SpreadsheetApp.getActiveRange()
        .setValue(image);
    }

    Предыдущий ответ

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

    Функция вставки
    /**
     * Insert a single image to the cell. A1 is default
     *
     * @param {GoogleAppsScript.Spreadsheet.Sheet} sheet
     * @param {GoogleAppsScript.Base.Blob} blob
     * @param {number} row
     * @param {number} column
     */
    function insertImageBlobToCell_(sheet, blob, row = 1, column = 1) {
      const sheetName = sheet.getName();
      const parentId = sheet.getParent().getId();
      return DocsServiceApp.openBySpreadsheetId(parentId)
        .getSheetByName(sheetName)
        .insertImage([{ blob, range: { row, column } }]);
    }


    Пример вызова
    /**
     * Insert an image blob to the cell
     */
    function userActionRun() {
      const sheet = SpreadsheetApp.getActiveSheet();
      const blob = UrlFetchApp.fetch(
        'https://contributor.pw/img/post/sheets/sheets_mmult-some-uses-cases_01.png'
      ).getBlob();
      insertImageBlobToCell_(sheet, blob);
    }


    Результат
    601a1d24dca43655873570.png

    Не забудьте добавить библиотеку
    108j6x_ZX544wEhGkgddFYM6Ie09edDqXaFwnW3RVFQCLHw_mEueqUHTW
    в свой проект. Пример манифеста в сниппете
    Ответ написан
    4 комментария
  • Можно ли получить почту, с которой человек прошел опрос в Гугл Форме?

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

    Что в общем-то честно, т.к. пользователю нужно представиться системе. А представление системе несет с собой некоторую степень ответственности. Форма-то не ваша, а Гугла.
    Ответ написан
    1 комментарий
  • Почему некорректно работает doGet, если логиниться под другим доменом?

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

    Обратитесь к администратору Google Workspace, с доменом которого возникли проблемы.
    Ответ написан
    5 комментариев
  • Как из строки даты и строки времени получить формат Date?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Даты и время в Таблицах просто складываются. Самое выгодное в данной ситуации - иметь колонку с суммой между "dd.MM.yyyy" и "HH:mm:ss".

    Для получения валидного объекта Date буде достаточно из итоговой ячейки взять значение.

    const dateTimeStart = sheets.getRange('C1').getValue();

    Откуда у вас возьмется dateTimeEnd - только вам известно, но в итоге, полученный dateTimeStart подходит для передачи в качестве значений аргументов в методы CalendarApp.
    Ответ написан
    Комментировать
  • Установка даты в соседний столбец по флажку true?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Добавьте скрипт к вашей Таблице

    /**
     *
     */
    function onEdit(e) {
      const sheetName = 'Sheet6'; // Имя листа, который отслеживается
      const colToStamp = 7; // Номер колонки для даты
    
      if (e && e.range && e.range.getRow() > 9 && e.range.getColumn() == 6) {
        const sheet = e.range.getSheet();
        if (sheet.getName() == sheetName) {
          const writeVal =
            e.value == true || e.value == 'TRUE' || e.value == 'ИСТИНА'
              ? new Date()
              : '';
          sheet.getRange(e.range.rowStart, colToStamp).setValue(writeVal);
          SpreadsheetApp.getActive().toast('Обновлено');
        }
      }
    }


    https://github.com/contributorpw/google-apps-scrip...

    Пример https://docs.google.com/spreadsheets/d/1LZi-bTd8-P...
    Ответ написан
    Комментировать
  • Как ежедневно автоматически сохранять значение ячейки в Google Таблицах?

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

    Добавьте код в проект к Таблице

    /**
     *
     */
    function createTrigger() {
      ScriptApp.getProjectTriggers().forEach(
        (trigger) =>
          trigger.getHandlerFunction() === 'saveData' &&
          trigger.getEventType() === ScriptApp.EventType.CLOCK &&
          (ScriptApp.deleteTrigger(trigger) ||
            console.info(`Tirgger ${trigger.getUniqueId()} was deleted`))
      );
      // every minutes for testing
      // ScriptApp.newTrigger('saveData').timeBased().everyMinutes(1).create();
      // at 9 o'clock every days
      ScriptApp.newTrigger('saveData').timeBased().atHour(9).everyDays(1).create();
    }
    
    /**
     *
     */
    function saveData() {
      const book = SpreadsheetApp.openById(
        '1FUSSiDQoXyvKXfzYydoUUfcCGYq_TskpRiwfb28_1Z0'
      );
      const sheet = book.getSheetByName('Лист1');
      const value = sheet.getRange('A1').getValue();
      book.getSheetByName('Лист2').appendRow([new Date(), value]);
      console.info(`saveData was called successful`);
    }


    Не забудьте поменять ID Таблицы 1FUSSiDQoXyvKXfzYydoUUfcCGYq_TskpRiwfb28_1Z0 на ваш.

    Таблица должна содержать два листа: "Лист1" и "Лист2". Программа с 9 до 10 утра один раз читает значение из ячейки Лист1!A1 и добавляет новую строку на Лист2.

    Вызовите из редактора функцию createTrigger один раз.

    Пример Таблицы с кодом https://docs.google.com/spreadsheets/d/1FUSSiDQoXy...

    На картинке красным пометил то, что нужно нажимать. Синим - нужно изменить перед первым запуском.
    5fe4bd91d80c7094551103.png
    Ответ написан
  • Как разнести данные по ячейкам из вложенного списка?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    5fc011e6b5fea796277110.png

    Вам нужен процесс сплющивания объектов. Погуглите термин "flatten".

    Для текущей спецификации Google Apps Script можно попробовать использовать следующий код

    /**
     * @see https://gist.github.com/penguinboy/762197#gistcomment-3448642
     */
    function flatten(object, path = null, separator = '.') {
      return Object.keys(object).reduce((acc, key) => {
        const value = object[key];
        const newPath = Array.isArray(object)
          ? `${path ? path : ''}[${key}]`
          : [path, key].filter(Boolean).join(separator);
        const isObject = [
          typeof value === 'object',
          value !== null,
          !(value instanceof Date),
          !(value instanceof RegExp),
          !(Array.isArray(value) && value.length === 0),
        ].every(Boolean);
    
        return isObject
          ? { ...acc, ...flatten(value, newPath, separator) }
          : { ...acc, [newPath]: value };
      }, {});
    }


    Тогда ваш код можно запустить вот так

    /**
     *
     */
    function myFunction() {
      const response = {
        result: {
          items: [
            {
              product_id: 253611,
              offer_id: 'УТ-00007992',
              stock: {
                coming: 0,
                present: 100,
                reserved: 23,
              },
            },
            {
              product_id: 253616,
              offer_id: 'УТ-00007043',
              stock: {
                coming: 0,
                present: 23231,
                reserved: 1,
              },
            },
          ],
          total: 20,
        },
      };
      const arr = response['result']['items'];
    
      const data = [];
    
      arr.forEach((el) => data.push(Object.values(flatten(el))));
    
      SpreadsheetApp.getActive()
        .getSheetByName('имя')
        .getRange(1, 1, data.length, data[0].length)
        .setValues(data);
    }
    Ответ написан
    1 комментарий
  • Как реализовать поиск по номеру строки в Google Таблице?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Доступны горячие клавиши

    1. [ALT]+[/]
    2. Напечатать go to range (по-русски может быть другая фраза)
    3. В появившемся окне ввести имя диапазона, например, A5 или 5:5


    5efc12274ad9e343919018.png

    Вы можете включить F5 как клавишу для этого. Перейдите в настройки клавиш и выберите расширенный режим

    5efc12c291f16030276273.png
    Ответ написан
    Комментировать
  • Как правильно вставить массив в строку Таблицы?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Должно быть

    const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Data");
    Ответ написан
    Комментировать
  • Когда следует создавать функции?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Пример заметного количества функций https://github.com/contributorpw/lodashgs/blob/mas... Время работы скрипта растет минимально. Многие пользуются. Дело не в размере. Тем более, что скрипты хорошенько сжимаются перед исполнением. И вот этот файл https://github.com/contributorpw/alasqlgs/blob/mas... (не открывать при медленной сети) работает нормально даже в качестве пользовательской функции, а там, на секундочку, всего полминуты времени исполнения.

    Вы привели в примере SpreadsheetApp.flush(). Этот метод останавливает все расчеты и пересчитывает все, что находится у вас в Таблице. Вероятно, из-за него у вас и проблемы.

    Судя по предыдущим вашим вопросам, вы усиливаете работу интерфейса, давите на впечатление. Ну, так в браузере оно будет работать так как будет работать, и заставить это всё работать быстрее не получится.

    Совет. Откажитесь от
    Всё выделяется сразу. Теперь видно с каким диапазоном работаю. Намного более понятно что попадает в значения диапазона.

    , потому что это все ерунда, и никому не надо смотреть на экран, чтобы понимать, что там работает, а что нет. Пользователю нужно знать три вещи:
    1. Еще не считало
    2. Еще считает
    3. Уже посчитало

    Остальное для него мрак и туман, а вы тратите на них время.
    Ответ написан
    7 комментариев
  • Как увидеть переменную при отладке?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Скорее всего все в порядке. Обновите страницу редактора

    5eedaf3cc2116451844474.png
    Ответ написан
    3 комментария
  • Как вычислить значение искомой ячейки с помощью ЕСЛИ() или какой-либо другой функции, которая переберет весь диапазон массива?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Можно попробовать решить это с помощью выборки с конкатенацией

    =ARRAYFORMULA(IFERROR(VLOOKUP(
        A2:A&C2:C;
        {
          UNIQUE(A2:A&C2:C)\
          REGEXREPLACE(TRIM(TRANSPOSE(QUERY(
            IF(TRANSPOSE(UNIQUE(A2:A&C2:C))=A2:A&C2:C;B2:B & ", ";"");;ROWS(A2:A))
          ));"(\s*,)+$";"")
        };
        2;
      );""))


    Выводит напротив даты и товара список магазинов, в которые в эту дату поступал этот товар.

    5eeda7e7f1296059711169.png

    Также можно построить карту поступлений

    5eeda80750fd0108903866.png

    Довольно удобный отчет, если добавить к нему фильтры по товарам, датам и магазинам.

    Пример в Таблице https://docs.google.com/spreadsheets/d/15eAJ-R1i8A...
    Ответ написан
    2 комментария
  • Как выделить диапазон в таблице?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Попробуйте использовать flush

    function (){
      ... < proc > ...
      ActivateRange();
      SpreadsheetApp.flush();
      ... < proc > ...
    }
    Ответ написан
    1 комментарий
  • Почему может не работать new Date() в Google Script?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Решение кроется в сообщении об ошибке.

    Автор нам приводит 4 строки кода, а в ошибке указатель ссылается на 14 строку.

    По все видимости, достаточно было обновить страницу браузера с проектом или сбросить кеш браузера, для отображения фактического кода.

    Объект Date тут ни при чем.
    Ответ написан
  • Как изменить привязанный к Google таблице скрипт извне?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Это можно сделать через Script API



    Есть куча тонкостей, которые связывает история разработки сервиса, поэтому, если у вас есть в среде nodejs, то я бы рекомендовал использовать cli для проектов Google Apps Script @google/clasp.
    Ответ написан
    1 комментарий
  • Где можно посмотреть побольше примеров использования jQuery совместно с google apps script?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Между этими техниками нет прямой связи.

    JQuery вы можете использовать только в клиентском исполнении интерфейсов. Конкретно для Таблиц: в диалоговых окнах и боковой панели.

    Любые примеры будут актуальны. Данные вы все равно будете передавать через клиентский API.
    Ответ написан
    Комментировать