• Как сделать COUNTIF по условию соседнего столбца?

    oshliaer
    @oshliaer Куратор тега Google Sheets
    Google Products Expert
    Вероятнее всего вам нужна формула COUNTIFS()
    Например,
    =COUNTIFS(A2:A9,"=Яндекс.Такси",B2:B9,"=Стоимость")

    Пример Таблицы с полями выбора

    2ff795ba82e44844a2e99880c6ea9ee5.png
    Ответ написан
    1 комментарий
  • Можно ли загружать фаилы с сервера на Google drive с их api без OAuth 2.0?

    oshliaer
    @oshliaer
    Google Products Expert
    AlexStolman,
    Authorizing Your App with Google Drive
    All requests to the Google Drive API must be authorized by an authenticated user. Google Drive uses the OAuth 2.0 protocol for authenticating a Google account and authorizing access to user data. You can also use OAuth 2.0 or Google+ Sign-in to provide a "sign-in with Google" authentication method for your app #REF

    Поэтому выход только один PHP Quickstart.
    Простым вариантом может быть поиск приложения или расширения (как это в PHP?) вашего фреймворка (или у вас все от руки?) для работы с Диском.

    С уважением.
    Ответ написан
    Комментировать
  • Можно ли полностью расшарить Google Drive?

    oshliaer
    @oshliaer
    Google Products Expert
    Алексей Савчук,
    • Если речь идет об обычном частном аккаунте, то нет. Как вариант можно написать скрипт, который будет добавлять (не перемещать) в заданную папку все что видит и назначать права.
    • В Google Apps for Work администратор домена имеет такие привилегии.

    С уважением.
    Ответ написан
    Комментировать
  • Как отправить данные javaScript - ом в гугл таблицы?

    oshliaer
    @oshliaer Куратор тега Google Sheets
    Google Products Expert
    1. Ваша функция на сервере Google Apps Script ничего не возвращает.
    2. Ваш сервер на Google Apps Script ожидает GET-запрос.

    Код сервера
    function doPost(e){
      var response = {};
      try {
        var sheet = SpreadsheetApp.openById('1iZazQ8YSMa6b9WFKTHJ99WooEC48nH9IF1x9fh6dQ9Y');
        sheet.appendRow([new Date(), JSON.stringify(e)]);
        response = {'result': 'OK'};
      } catch(err) {
        response = {'error': 'error'};
      } finally {    
        return ContentService.createTextOutput(JSON.stringify(response)).setMimeType(ContentService.MimeType.JSON);
      }
    }


    С уважением.
    Ответ написан
    Комментировать
  • Как сделать выпадающий список с добавлением новых элементов?

    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 комментарий
  • Как сделать вложенный цикл в google spreadsheet?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Ни при каких обстоятельствах не дразните систему setValue(), да еще и во вложенном цикле. Запись происходит не на ваш ПК, а на сервер. Кому понравится, когда его так дергают?

    Чтобы работало даже с "черновиками", т.е. до 50 000 строк на лист, сначала берите ВСЕ данные, потом формируйте ГОТОВЫЙ массив, потом делайте setValue().

    Примерно так:
    function writeData(){
      //Не факт, что поможет, но вдруг
      SpreadsheetApp.flush();
      
      //Далее как у всех
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      
      var resultSheet = ss.getSheetByName("Result");
      var agentsSheet = ss.getSheetByName("Buyers");
      var productsSheet = ss.getSheetByName("Products");
      
      var aV = agentsSheet.getDataRange().getValues();
      var pV = productsSheet.getDataRange().getValues();
      
      //срезать шапку
      aV.shift();
      //  pV.shift();
      
      var res = [];
      
      for(var i = 0; i< aV.length; i++)
      {
        res.push([].concat([aV[i][0]], pV[0]));    
        for(var j = 1; j < pV.length; j++){      
          res.push([].concat([''], pV[j]));      
        }
      }
      
      res = res.slice(0, 50000);
      resultSheet.getDataRange().clear(); 
      resultSheet.getRange(1, 1, res.length, res[0].length).setValues(res);
    }
    Ответ написан
    1 комментарий
  • Как связать или внедрить данные в Google Docs?

    oshliaer
    @oshliaer Куратор тега Google Sheets
    Google Products Expert
    Технически это возможно с большими оговорками.

    Во-первых, не сравнивайте сервисы Google с настольным приложением, это позволит более трезво взглянуть на вещи.
    Во-вторых, встроенных средств не существует. И, если еще раз прочитать "во-первых", они и не нужны.
    В-третьих, можно извернуться и программно добавлять значения в Документ, но это довольно хлопотно. В конце-концов в Google Apps Script есть некий класс Class Range, который, все же, пока болтается без дела.

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

    Обновление от 2019-01-23
    Существует возможность "привязать" Таблицу к Документу. Необходимо выделить диапазон Таблицы, скопировать в буфер и вставить в Документ. Пример https://vk.com/wall-174824632_8
    Ответ написан
    Комментировать
  • Какая формула вернет название Листа в ячейку?

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

    Можно создать собственную функцию на основе Google Apps Script.
    Code.gs
    function sheetName() {
      return SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getName();
    }
    
    function sheetsName() {
      return SpreadsheetApp.getActiveSpreadsheet().getSheets().map(function(s){return s.getName()});
    }

    В Таблице необходимо указать формулу для получения имени активного листа
    =sheetName(E5:E13)
    Для получения списка всех листов
    =sheetsName(E5:E13)
    где E5:E13 особый, обязательно активный, т.е. зависящий от ввода пользователя, диапазон. Без изменения этого диапазона, толку от функции будет мало.
    Внимание, функции времени (TODAY(), NOW()) нельзя передавать как аргументы.

    Пример Таблицы со скриптом goo.gl/w97FNi

    P.S.: Чтобы исключить гнев и любую неверную интерпретацию, скажу, что этот скрипт стал возможен после публикования вопроса и первых комментариев к этому посту. Пруф https://code.google.com/p/google-apps-script-issue...
    Ответ написан
    Комментировать
  • Система бронирования (резервирования) товаров (заказов) Google spread sheet. Примеры?

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

    Вот небольшой пример https://youtu.be/9WK1FM2_tDc Таблица https://goo.gl/4u23t7 (необходимо сделать копию)

    Суть в том, чтобы вести запись только в одном листе "История". На "Складе" остатки отображаются через формулу:
    =QUERY('История'!B:E;"select B, C, sum(D) where E=true group by B, C")

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

    Пояснения к коду. Серверная часть нуждается в LockService, чтобы разрешить очередь записи.
    Можно сделать форму просмотра заказов, с возможностью помечать FALSE в "Истории". Может быть даже "Редактировать", но лучше по-моему, делать копию и записывать новый заказ, помечая прежний как FALSE. Также необходимо продумать регламент, т.к. Таблицы "нерезиновые" и необходимо максимально часто переносить остатки.

    Пояснения к концепту. Ваше представление, которое приведено выше, вряд ли подойдет для реализации в Таблицах, уже только потому, что никаких идентификаторов строк, и тем более связей между Таблицами, не существует. Я предлагаю вообще ничего не удалять. Лучше делать "перенос остатков" и прочих параметров в новые Таблицы (или наоборот), чтобы иметь более полноценную картину действий.

    Пожалуйста, измените теги в топике на Google script и Spreadsheets. При текущем теге ответ на вопрос должен быть примерно таким https://www.google.com/enterprise/marketplace/sear...
    Ответ написан
  • Как построить диаграмму (график) для не смежных ячеек в Google таблицах?

    oshliaer
    @oshliaer
    Google Products Expert
    Здравствуйте.

    Используйте раздел "Функции" основной "Настройки" - опция "показывать 0"
    20de821d52bd49be80aa41f6a4e164ad.gif

    Пожалуйста, присылайте ссылки на примеры goo.gl/ZLO06Q, иначе, не всегда просто понять, что вы желаете получить. Примечательно, что Таблицы не занимают места на Диске Google.
    Ответ написан
    4 комментария
  • Как получить доступ к таблицам google spreadsheets?

    oshliaer
    @oshliaer Куратор тега Google Sheets
    Google Products Expert
    Пример, как это можно решить через Google Apps Script. В качестве получателя XMLHttpRequest.

    Суть способа в опубликованном файле скрипта Как получить доступ к таблицам google spreadsheets?. Он

    1. Получает запрос POST
    2. Берет данные из Таблицы, владельцем которой является другой пользователь. Уровень доступа "Для всех в Интернет".
    3. Возвращает ответ.


    Хостинг страниц на Диске Google больше не работает. Необходимо загрузить страницу на свой хостинг.
    Ответ написан
    2 комментария
  • Как вызвать формулу импорта с сайта с Jsp?

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

    Это называется что-то типа "browser on server".
    По идее, мы должны заставить сервер, загрузить к себе страницу, вызвать все клиентские процедуры, взять контекст и разобрать его, выдать результат в сеть.
    Проблемы:
    • Где взять/запустить/выпросить/настроить сервер обычным смертным?
    • Что!?

    Идея:
    • Организовать часть автоматизации на рабочем месте.
    • Публиковать данные, ака "выдать результат в сеть", на Диске Google.

    По шагам:
    1. Необходимо скачать и распаковать phantomjs.org/download.html Пусть папка с файлом phantomjs.exe называется
      'C:\phantomjs\bin'
    2. Необходимо скачать файл parse_jsp_to_file.js Сохраните его туда же, где лежит файл phantomjs.exe
    3. Необходимо установить Диск для Mac/PC
    4. Необходимо настроить паку на диске для общего доступа (Видно всем в Интернет). Назовем ее FOLDER.
    5. Необходимо, чтобы папка FOLDER синхронизировалась в Диск для Mac/PC. Пусть ее путь будет
      'C:\Диск Google\FOLDER'
    6. Открыть файл parse_jsp_to_file.js текстовым редактором и изменить строку
      var folder = 'C:\\_\\Google Drive\\temp (main)\\(public)\\';

      на строку
      var folder = 'C:\\Диск Google\\FOLDER\\';
      *следите за слэшами. Настройка указана для Windows
    7. Остается запустить командную строку и вставить туда
      'C:\phantomjs\bin\phantomjs.exe parse_jsp_to_file.js'

    8. Если в папке C:\Диск Google\FOLDER появился файл yyyy-mm-dd.xml, то можно идти дальше, иначе - ковырять и проверять.
    9. Необходимо получить ID папки FOLDER на Диске. Это самая длинная комбинация Цифр/Букв в адресе общего доступа.
    10. Необходимо взять формулу IMPORTXML() из файла goo.gl/GUpaf2
    11. Необходимо заменить в этой формуле ID на свой.
    12. Все.

    У меня работает как часы.
    Проблемы:
    • Я не добавлял обработчики исключений.
    • JS файл должен быть в кодировке UTF-8
    • Я добавил BAT файл для своей настройки. Но у меня C:\phantomjs\bin находится в переменных среды.

    Что в итоге:
    • BAT можно настроить на запуск каждый день.
    • Файлы записываются по одному на каждый день.
    • В Таблицах появляется возможность отследить дату изменения контекста.

    P.S.:
    Для множества ссылок, необходимо просто использовать другой скрипт simple_cycle.js. Ему необходимо существование файла file.txt, где описаны параметры, которые должны формировать URL для запроса.
    Результат на листе "Пример с несколькими файлами" goo.gl/GUpaf2.
    Ответ написан
    3 комментария
  • Как получить ссылку на изображение из Google диска по id?

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

    Берут сомнения меня, что CAJA, даже в режиме IFRAME, предоставляет нам DOM-документ. Все же, с большой вероятностью, это некий фарш LIKE_DOM = CAJA(DOM);

    Поэтому инструкция, чтобы в нее не передавали, не будет "responsive":
    document.getElementByTagName('img').src = data.image;

    Но, это же DOM, в конце концов! Создаем элемент, вместо изменения атрибута:
    index.html
    <div>
    	<input type="button" onclick="showImage()" value="Click Me!" />
    	<div id="app"></div>
    </div>
    <script>
    	function showImage() {
    		google.script.run.withSuccessHandler(doStuff).withFailureHandler(function serverFailureHandler(e) {
    			console.log(JSON.stringify(e))
    		}).getImageId();
    	};
    	function doStuff(id) {
    		var img = document.createElement('img');
    		img.src = 'https://drive.google.com/uc?export=download&id=' + id;
    		document.getElementById('app').appendChild(img);
    	};
    </script>

    Code.gs
    function doGet(e){
      return HtmlService.createHtmlOutputFromFile('index');
    }
    function getImageId(){
      return '0BzStSAirQJ2oREZGYnM5MjBUZTQ';
    }

    Заметьте, нет никакой необходимости вызывать DriveApp. Он вам понадобится, только если изображение будет не в общем доступе. Тогда вам придется брать Blob, кодировать его в base64 и передавать слепок. Размер слепка не может превышать 10Мб.

    И еще я заметил у вас
    <?!= include('JavaScript'); ?>
    Не забудьте, что шаблоны не исполняют асинхронного кода Load data asynchronously, not in templates, поэтому, создавая нечто объемное, постарайтесь выдать HTML как можно быстрее:
    function doGet(e){
      return HtmlService.createHtmlOutputFromFile('index');
    }
    Ответ написан
    Комментировать
  • Как сгенерить md5 строку на Google Script?

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

    Мне кажется, что у вас неполные представления о методах Google Apps Script, алгоритмах хэширования и системах исчисления.

    Во-первых, computeDigest возвращает массив Byte[], что он и должен делать.
    Во-вторых, вам просто его надо "преобразовать в 16-ричную хэш строку", как сказано выше.

    Попробуйте сделать так:

    function test(){
      Logger.log(toMD5('56'));
    }
    const toMD5 = function(charset, toByte) {
      charset = charset || Utilities.Charset.UTF_8;
      var digest = Utilities.computeDigest(Utilities.DigestAlgorithm.MD5, this, charset);
      if(toByte) return digest;
      var __ = '';
      for (i = 0; i < digest.length; i++) {
        var byte = digest[i];
        if (byte < 0) byte += 256;
        var bStr = byte.toString(16);
        if (bStr.length == 1) bStr = '0' + bStr;
        __ += bStr;
      }
      return __;
    }
    Ответ написан
    Комментировать
  • Как настроить взаимодействие Google Apps и Яндекс.Маркет API?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Основное требование от Яндекс для доступа к API Маркета - это наличие "Партнерского API"- или
    "Контентного API"- ключа доступа в виде oauth_login. Этакий ключ-в-ключе. Рассуждения на тему необходимости, полагаю, неуместны.

    API Маркета
    • Партнерский API Для магазинов, которые размещают товары на Яндекс.Маркете, а также для рекламных агентств.
    • Контентный API Для разработчиков, которым нужны данные о товарах с Маркета: описания моделей, фотографии, отзывы.

    Следует точно определиться с целью задачи. Не знаю, дает ли Яндекс добро на использование данных в масштабах "личного хочу", поэтому, не имея магазина, придется создавать приложение "для всех".

    Опишу вкратце, как использовать API Маркет в Google Apps Script:
    1. Вы должны быть уверены, что у вас есть ваш oauth_login (см. выше)
    2. Пройдите Авторизацию. Для этого ваше приложение должно использовать следующие из возможностей Google Apps Script: HtmlService как опубликованное приложение, HtmlService как возврат StateTokenBuilder, если вы создаете Add-On. Для получения токена и отправки запросов POST (или запросов GET от лица приложения) используйте URLFetch
    3. Следуйте инструкциям Яндекс по Ограничениям для запросов

    Могу добавить только то, что описание API Яндекс и ВКонтакте на данный момент, как мне кажется, являются самыми внятными и, вероятно, прямолинейными. От чего вероятность возникновения ошибок минимальна.

    С уважением.
    Ответ написан
    Комментировать
  • Как правильно переписать формулу Excel для анализа отфильтрованных строк под таблицы Google Docs?

    oshliaer
    @oshliaer Куратор тега Google Sheets
    Google Products Expert
    В Таблицах Google "Фильтр" не соответствует функции "Фильтр" в MS EXCEL. Необходимо изменить техпроцесс.
    Ответ написан
    Комментировать
  • Google Apps и SSO

    oshliaer
    @oshliaer
    Google Products Expert
    Для всех, кто интересуется. Это довольно просто, если настроить.

    Интересно, возможно ли закрыть топик 3х летней давности?
    Ответ написан
    Комментировать
  • Как вернуть старый интерфейс Google Chrome?

    oshliaer
    @oshliaer
    Google Products Expert
    Форсированно включаем new profile management system Mac, Windows, Linux, Chrome OS, Android, чтобы было, не отказываться же от "плюшек".
    Форсированно выключаем the new avatar menu Mac, Windows, Linux, чтобы "все вернулось назад".

    gdriveru.blogspot.com/2015/01/google-chrome-new-pr...
    Ответ написан
    2 комментария
  • Как в гугл таблице сделать формулу поиска двух образцов текста?

    oshliaer
    @oshliaer Куратор тега Google Sheets
    Google Products Expert
    Используйте регулярные выражения для сложных операций со строками.
    Для одной ячейки
    =REGEXMATCH(T(A1),"7777|9999")
    Для диапазона
    =ARRAYFORMULA(REGEXMATCH(T(A1:A12),"7777|9999"))
    Если заранее известно, что в диапазоне только текст, то формулу T() можно опустить.

    Пример Как в гугл таблице сделать формулу поиска двух обр...

    Тест регулярного выражения (ссылка)
    4c0deb3728b24ab9a94a6123eb1956ef.png
    Ответ написан
    Комментировать