• Почему не отображается пользовательское меню на мобильном устройстве?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Пользовательское меню доступно только для интерфейса браузерной версии Таблиц.

    Новые дополнения на Card-based еще не доступны для мобильной версии. Эта технология реализована только в Gmail.
    Ответ написан
    Комментировать
  • Как в ячейку поместить и вариант значения, и формулу ЕСЛИ?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Формулой такое не решить, но скриптами сделать это довольно просто

    function update() {
      const book = SpreadsheetApp.getActive();
      const sheet = book.getSheetByName('Пример');
      sheet.getRange('A2:A')
        .setValues(sheet.getRange('A2:C').getValues()
          .map(([kladovshik, _, externalSource]) =>
            [externalSource === 'Продан' ? externalSource : kladovshik]));
    }


    Результат

    63008390c4a76391026305.png

    Вы можете установить триггер по времени на каждые 5 минут, и данные будут обновляться, как вам надо.

    Пример в Таблице https://docs.google.com/spreadsheets/d/1HAIFneepN_...
    Ответ написан
    Комментировать
  • Как определить значение из списка на основе содержимого строки?

    oshliaer
    @oshliaer Куратор тега Google Sheets
    Google Products Expert
    Простое решение через IF

    =IF(LEFT(A2;2)="CJ";8;IF(LEFT(A2;2)="RJ";15;IF(LEFT(A2;2)="EJ";37;"?")))


    63004f97bf6c7169499227.png

    Эффективное решение

    =ARRAYFORMULA(VLOOKUP(LEFT(A2:A16;2);H2:I4;2;))

    63004fded70b6681961940.png

    Пример в Таблице https://docs.google.com/spreadsheets/d/1aflIYNxAPy...
    Ответ написан
    2 комментария
  • Как обратится к элементам json?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Вроде, все нормально
    const datainfo = JSON.parse(response);
    datainfo.suggestions.forEach(suggestion => console.log(suggestion.value));


    Если надо вставить на лист Sheet1, то
    const datainfo = JSON.parse(response);
    const values = datainfo.suggestions.map(suggestion => [suggestion.value]);
    book.getSheetByName('Sheet1').clearContent()
      .getRange(1, 1, values.length, values[0].length).setValues(values);
    Ответ написан
    Комментировать
  • Как распарсить JSON и записать в Таблицу?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Вам необходимо сделать следующее

    const content = response.getContentText();
    const data = JSON.parse(content);


    Далее, работать как с объектом, например

    const values = data.rows.map(item => [item.name, item.code]);
    sheet.getRange(1,1,values.length, values[0].length).setValues(values);
    Ответ написан
    Комментировать
  • Как посчитать возвращаемость клиентов?

    oshliaer
    @oshliaer Куратор тега Google Sheets
    Google Products Expert
    Судя по описанию, это довольно просто сделать. Можно даже формулами, но и для скриптов алгоритм будет тот же:

    1. Необходимо сгруппировать данные по заданным признакам. Это или циклы или QUERY
    2. Далее в каждой группе произвести подсчет.
    3. На основе результатов подсчета сделать вывод


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


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

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

    Это легко сделать с помощью формул и условного форматирования

    62f49b7647052737399426.png

    В формуле мы просто сравниваем две строки:

    =ARRAYFORMULA(
      VLOOKUP(DAY(TODAY());A3:K33;{2\3\4\5\6\7\8\9\10\11};)-
      VLOOKUP(DAY(TODAY())-1;A3:K33;{2\3\4\5\6\7\8\9\10\11};)
    )


    Условное форматирование просто закрашивает цвет текста в цвет фона, чтобы создать ощущение полной заливки

    62f49ccdea97d872092265.png
    Ответ написан
    Комментировать
  • Как на 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
    Ответ написан
    Комментировать
  • Почему неправильно прибавляет процент?

    oshliaer
    @oshliaer Куратор тега Google Sheets
    Google Products Expert
    Потому что так не считают проценты.

    Основное правило
    Проценты и числа - это разные типы данных. Их можно связать через умножение, как действие определения долей, потому что процент является формой десятичной дроби.


    При сложении вы получаете конкатенацию строк, как основное действие приведения типов
    62f4088bee023255767681.png

    А вам нужно определить, что вы складываете. Например, число и долю от этого числа
    62f408becbb80522544650.png
    Ответ написан
    Комментировать
  • Несколько 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 Products Expert
    Есть три выхода, которые реализуют два подхода, основанные на одной функции.

    Функция
    1. это подписка на API https://developers.google.com/admin-sdk/reports/v1...


    Подходы
    1. Использовать собственное решение
    2. Использовать чужое решение


    Выходы
    1. Написать собственную программу. Для простой реализации подойдет Google Apps Script. Достаточно разобраться с данными, которые требуется получить.
    2. Использовать стороннюю программу https://workspace.google.com/marketplace/app/fores... (это пример, не реклама)
    3. Заказать себе собственное решение
    Ответ написан
  • Как объединить текст из ячеек, которые содержат строки с курсивом?

    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
    Ответ написан
  • Как сделать сумму по столбцам VLOOKUP и ARRAYFORMULA?

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

    ============= Обновлено 2022-08-03 ==========

    Решение для бесконечных диапазонов

    =ARRAYFORMULA(VLOOKUP(
      R5:R;
      QUERY(
        SPLIT(FLATTEN(A5:A & "|" & B5:D);"|");
        "select Col1, sum(Col2) group by Col1");
      2;
    ))


    62ea7f416fade657975949.png

    ============= ==========

    Можно использовать формулу построчной суммы

    ={A4:A7\{"Сумма";INDEX(
      {TRANSPOSE(QUERY(
        {TRANSPOSE(B5:E7)};
        "select " & "sum(Col" & JOIN("), sum(Col"; SEQUENCE(1;ROWS(A5:A7);1;1)) & ")";
        0))}
      ;;2
    )}}


    К сожалению, она требует конечных диапазонов, но настройка несложная.
    62e933ad8368a574615109.png

    Только вычисления, без формирования заголовков результата, данные отсортированы как в исходнике

    ={INDEX(
      {TRANSPOSE(QUERY(
        {TRANSPOSE(B5:E7)};
        "select " & "sum(Col" & JOIN("), sum(Col"; SEQUENCE(1;ROWS(A5:A7);1;1)) & ")";
        0))}
      ;;2
    )}

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

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

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

    Но ряд существенных ограничений Таблиц не выделяют их среди других конкурентных решений. Например, Таблицы - это чужой сервис, поэтому вы зависите от доступа к этому сервису, лицензия Таблиц предполагает их использование "как есть", т.е. вам не гарантируют постоянство вычислений и хранения данных. А еще это бесплатный сервис, поэтому частые программные обращения бота к данным могут быть ограничены (хотя, это конечно, маловероятно). И еще, самым близким программным интерфейсом для Таблиц являются скрипты Google Apps Script, не уверен, что их так просто подключить к торговому терминалу. Т.о. придется использовать торговый терминал или что там еще для доступа к Таблице. В этом случае очевидно считать использование базы данных куда более оправданным. Даже локальный файл Excel подойдет лучше.

    В итоге, программу торговли можно писать хоть на салфетке, другое дело, является ли использование такого носителя оправданным.

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

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

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