Ответы пользователя по тегу Google Apps Script
  • Как изменить настройки таргетинга по локации пользователя в Google Ads Scripts?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Поддерживается только USER_INTEREST_AND_LIST

    62f4a31508273932761158.png
    Ответ написан
    Комментировать
  • Как запретить изменение данных в ячейке задним числом (днем)?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Я бы выбрал одно из двух, если ограничиться Таблицами:

    1. Запрограммировать Таблицу через Google Apps Script, чтобы защищенные диапазоны все время смещались до нужной даты
    2. Создать скрипт, который бы копировал отметки текущего дня в другую Таблицу, а остальное не трогал. Тут есть плюс, всегда можно сравнить, где мастер пытался "схитрить".


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

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Это легко сделать с помощью Google Apps Script.

    Пути решения:
    • Изучить Google Apps Script
    • Заказать решение. См. профиль


    Чтобы получить более внятный ответ, в следующий раз
    • Приводите пример данных в виде ТАБЛИЦЫ, без всяких там пояснительных записок и скриншотов
    • Не наглейте, показывайте, что вы уже пробовали сделать, иначе, см. инструкции выше.
    Ответ написан
  • Как на python в гугл таблицах отследить создание новой строки?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Вы должны определиться, что значит "на python"?
    1. событие происходит и должно вызвать ваш сервер (веб-хук)
    2. ваша программа (без причины) должна отреагировать на отправку Формы


    Веб-хук
    1. Поднимите сервер
    2. Определите эндпоинт для вызова
    3. Создайте простую функцию Google Apps Script, которая при отправке Формы будет дергать этот эндпоинт
    4. Установите в проекте скрипта триггер на отправку Формы для этой функции


    Скрипт

    function onFormSubmit(e){
      UrlFetchApp.fetch(endpoint, {
        payload: JSON.stringify(e)
      });
    }


    В данном случае вообще по барабану как вы со своим python будете парсить полученный объект. Данных там будет предостаточно.

    Безпричинная программа

    Очевидно, что работа без причины - признак ... неработающей программы.

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

    Пример получения данных можно найти тут же https://qna.habr.com/q/885673, https://qna.habr.com/search?q=python+google+sheets
    Ответ написан
    Комментировать
  • Несколько if в цикле for, как сделать приоритет для одного?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Комбинаций принятия решений может быть очень много. Вот пара советов:

    Используйте комбинированные проверки, например,
    if(col1 <> 0 && col2 === 1) {
    
    }


    Используйте выход из итерации цикла, если условие выполнено
    for(){
      if(){
        continue;
      }
    }


    Используйте прерывание цикла в нужный момент
    for(){
      if(){
        break;
      }
    }


    Используйте конструкцию else if для группировки проверок
    if(col1 <> 0) {
    
    } else if(col2 === 1) {
    
    }


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

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Если речь идет про Гугл Таблицы, то есть штатный метод из меню Данные - Очистить данные - Удалить повторы

    62f126a4d47d6634325189.png

    Вопрос про пример так и остался в воздухе.

    Положим, что есть данные
    62f5e48278178237948204.png

    Можно использовать скрипт

    /**
     * @param { globalThis.SpreadsheetApp.Range } range
     */
    function uniqByRow_(range, compact = false) {
      const mapper = compact ?
        row => {
          const uniq = [...new Set(row)];
          return row.map((_, i) => uniq[i] ?? '');
        } :
        row => row.map((cell, i) => row.indexOf(cell) === i ? cell : '');
      range.setValues(
        range.getValues().map(mapper));
    }
    
    function run() {
      const book = SpreadsheetApp.getActive();
      const range = book.getSheetByName('Данные').getDataRange();
      uniqByRow_(range, true);
    }


    Получим
    62f5e4afd08ef072268750.png

    А если вызвать uniqByRow_(range, false), то получим
    62f5e50e8ac2c297504373.png

    Пример в Таблице https://docs.google.com/spreadsheets/d/1Ywfr-cCfR5...
    Ответ написан
    2 комментария
  • Как объединить текст из ячеек, которые содержат строки с курсивом?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    К сожалению, простой версии в голову не приходит. Есть вот такой вариант

    function run() {
      const book = SpreadsheetApp.getActive();
      const range1 = book.getRange('Лист1!B4');
      const range2 = book.getRange('Лист1!B6');
    
      const joinRichTextValue = new JoinRichTextValue();
      joinRichTextValue.separator = { text: '\n' };
      joinRichTextValue.push(range1.getRichTextValue());
      joinRichTextValue.push(range2.getRichTextValue());
    
      const range = book.getRange('Лист1!B16');
      range.setRichTextValue(joinRichTextValue.build());
    }


    62e9497f2cecd535546867.png

    Обект JoinRichTextValue описан в проекте Таблицы https://docs.google.com/spreadsheets/d/11tjtnmr_F-...

    62e949ee26f49043643697.png
    Ответ написан
  • Настройка доступа при использовании макроса?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Вам необходимо от имени владельца зарегистрировать триггер (как я понимаю, это триггер на событие EDIT) и владельцу дать доступ на редактирование к другим Таблицам. Проблема будет решена.
    Ответ написан
    2 комментария
  • Как отключить превью у ссылки?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Такой возможности нет.

    Попробуйте отправить предложение по улучшению через меню помощи.
    Ответ написан
    Комментировать
  • Как скопировать вопрос вместе с картинкой программно?

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

    Вы можете использовать отдельный элемент Image для вставки картинки перед вопросом. Такой элемент можно скопировать или по крайней мере получить его Blob.
    Ответ написан
    Комментировать
  • Как по заданному диапазону удалять записи в ячейках на заданных листах?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Пример в Таблице https://docs.google.com/spreadsheets/d/1e6ZifmsvGk...

    Довольно простой код очищает заданные диапазоны в текущей Таблице:

    function cleanBook() {
      const sheetsForClean = [
        {
          rangeA1: 'Sheet2!E4:AI140'
        },
        {
          rangeA1: 'Sheet3!E4:AI140'
        },
        {
          rangeA1: 'Sheet4!E4:AI140'
        }
      ];
      const book = SpreadsheetApp.getActive();
      sheetsForClean.forEach(item => book.getRange(item.rangeA1).clearContent());
    }


    Необходимо заполнить массив настроек sheetsForClean и вызвать функцию. Можно вызвать и через макросы.
    Ответ написан
    1 комментарий
  • Как скопировать Таблицу из Google Sheets в Google Docs?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Может быть просто вставите связанные Таблицы? К сожалению, пока автоматизировать этот процесс нельзя, но сама связка работает и обновляется автоматически. Форматированеи сохраняется.

    Пример https://docs.google.com/document/d/1BNLG4f8Z_LSGch...

    Справка https://support.google.com/docs/answer/7009814?hl=...

    62d68e9a568a3296105785.png
    Ответ написан
    2 комментария
  • Как вставить значение после последней строки определенного столбца?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Пример в Таблице https://docs.google.com/spreadsheets/d/1ojcpidOxDV...

    Вот такая функция возвращает индекс последней заполненной строки

    function getLastRowIndexOfArray_(arr) {
      const index = arr.reverse().findIndex(row => row.join('') !== '');
      return arr.length - (index === -1 ? arr.length : index);
    }


    Вот так вы можете вставить значения, найдя этот индекс

    function run() {
      const book = SpreadsheetApp.getActiveSpreadsheet();
      const sheet = book.getSheetByName('Sheet4');
      const range = sheet.getRange('G:G');
      insertValueToEndOfRange_(range, [[22]]);
    }
    
    function insertValueToEndOfRange_(range, values) {
      const lastValueRow = getLastRowIndexOfArray_(range.getValues()) + 1;
      range.getSheet().getRange(lastValueRow, range.getColumn(), values.length, values[0].length)
        .setValues(values);
    }


    62d5745094ed3966057816.png
    Ответ написан
    Комментировать
  • Как в Google Forms добавить таймер?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Решение на скриптах https://qna.habr.com/q/490563

    function runTimerLimit() {
      const form = FormApp.getActiveForm();
      form.setAcceptingResponses(true);
      deleteTrigger();
      ScriptApp.newTrigger('disableAcceptingResponses')
        .timeBased()
        .after(40 * 60 * 1000)
        .create();
    }
    
    function disableAcceptingResponses() {
      const form = FormApp.getActiveForm();
      form.setAcceptingResponses(false);
    }
    Ответ написан
    Комментировать
  • Как задать ограничение времени для теста в google forms?

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

    function runTimerLimit() {
      const form = FormApp.getActiveForm();
      form.setAcceptingResponses(true);
      deleteTrigger();
      ScriptApp.newTrigger('disableAcceptingResponses')
        .timeBased()
        .after(40 * 60 * 1000)
        .create();
    }


    А вторая функция отключает доступ

    function disableAcceptingResponses() {
      const form = FormApp.getActiveForm();
      form.setAcceptingResponses(false);
    }


    Более сложный пример с запуском из меню и проверкой статуса https://docs.google.com/forms/d/14-TmwyasyNlVokvxf...

    62cd93ef0aba1534879301.png
    62cd94054b626957166396.png
    Ответ написан
    Комментировать
  • Как добавить в список по алфавиту строку?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Решение с примером тут https://t.me/google_spreadsheets_chat/251090

    function formSendAction() {
      const book = SpreadsheetApp.openById('1EbRQ1yV0upNFW11fuyfl3Bts7OTJ9rSAN2kiBekhzRg');
      const data = book.getSheetByName('Лист2').getDataRange()
        .getValues().slice(1)
        .map(row => row[1])
        .sort(stringCompare_)
        .reverse();
      const target = book.getSheetByName('Результат');
      const targetData = target.getDataRange()
        .getValues()
        .map(row => row[0]);
      const targetDataR = [...targetData].reverse();
      const firstIndexR = targetDataR.findIndex(fioTarget => fioTarget !== '');
      const firstIndex = targetData.findIndex(fioTarget => fioTarget !== '');
      const lastIndexR = targetDataR.length - firstIndex;
      data.forEach(fio => {
        if (!targetData.includes(fio)) {
          let index = targetDataR.findIndex(fioTarget => fioTarget !== '' && stringCompare_(fioTarget, fio) === -1);
          if (index === -1) {
            console.log(stringCompare_(targetData[firstIndex], fio), firstIndex, targetData[firstIndex], fio);
            if (stringCompare_(targetData[firstIndex], fio) === 1) {
              index = lastIndexR + 1;
            } else {
              index = firstIndexR - 2;
            }
          };
          index = targetDataR.length - index + 2;
          target.insertRowsBefore(index, 2);
          target.getRange(index, 1).setValue(fio);
          target.setRowHeights(index + 1, 1, 10);
        }
      });
    }
    
    function stringCompare_(a, b) {
      return String(a).toLocaleLowerCase() < String(b).toLocaleLowerCase() ? -1 :
        String(a).toLocaleLowerCase() > String(b).toLocaleLowerCase() ? 1 : 0;
    };
    Ответ написан
    Комментировать
  • Как решить ошибку "TypeError: Cannot read property 'getRange' of undefined"?

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

    SpreadsheetApp.openById()
    book.getSheetByName()
    sheet.getRange()

    и т.п.
    Ответ написан
    Комментировать
  • Как исправить ошибку "Exception: Сервису "Таблицы" недоступен документ ABCD1234"?

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

    Немного подробнее в комментарии https://qna.habr.com/q/983611#clarification_1227067
    Ответ написан
    Комментировать
  • Как достать значение параметра из ответа API?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Скорее всего, вам нужно сделать вот это
    const data = JSON.parse(response.getContentText());


    function myFunction() {
      const response = UrlFetchApp.fetch("https://suppliers-api.wildberries.ru/api/v2/stocks...", options);
      const data = JSON.parse(response.getContentText());
      console.log(data);
      /**
        {
         "stocks":[
            {
               "subject":"Брюки",
               "brand":"R.O.S.E.",
               "name":"Брюки",
               "size":"42",
               "barcode":"2036686215443",
               "article":"292022",
               "warehouseName":"Брест",
               "barcodes":[
                  "2036686215443"
               ],
               "stock":0,
               "warehouseId":198679,
               "id":145904543,
               "chrtId":145904543,
               "nmId":90612284
            }
         ],
         "total":1
        }
      */
      console.log(data.stocks[0]);
      /**
        {
            "subject":"Брюки",
            "brand":"R.O.S.E.",
            "name":"Брюки",
            "size":"42",
            "barcode":"2036686215443",
            "article":"292022",
            "warehouseName":"Брест",
            "barcodes":[
              "2036686215443"
            ],
            "stock":0,
            "warehouseId":198679,
            "id":145904543,
            "chrtId":145904543,
            "nmId":90612284
        }
       */
    }
    Ответ написан
    Комментировать
  • Как сделать так, чтобы копировалась ячейка при изменении ячейки?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Без конкретного примера Таблицы ваш вопрос звучит как задача. Вот прмиер скрипта, который решает подобную проблему https://qna.habr.com/q/1165910

    Единственное, что вам нужно, это добавить проверку, есть ли в строке упоминание бригады.

    Опять же, без нормального примера, вам придется все делать самому.
    Ответ написан
    7 комментариев