• Как добавить колонку Google Sheet в определённое место (Python, gspread)?

    oshliaer
    @oshliaer Куратор тега Google Sheets
    Google Products Expert
    Используйте базовый API

    sht = gc.open_by_key(spreadsheetId)
    
    requests = []
    
    requests.append({
          "insertDimension": {
            "range": {
              "sheetId": sheetId,
              "dimension": "COLUMNS",
              "startIndex": 2,
              "endIndex": 4
            },
            "inheritFromBefore": True
          }
        })
    
    body = {
        'requests': requests
    }
    
    sht.batch_update(body)


    Запустить код "здесь и сейчас" можно по ссылке https://colab.research.google.com/drive/1IWmX5xuOE...

    Ответ написан
    Комментировать
  • Как создать новый лист и поменять его название в гугл таблице?

    oshliaer
    @oshliaer Куратор тега Google Sheets
    Google Products Expert
    Наверное, gspread является неплохим решением, но с появлением Sheets API v4, все стало немного проще.

    spreadsheetId=''
    new_sheet_title=''
    
    from googleapiclient.discovery import build
    service = build('sheets', 'v4')
    
    requests = []
    
    requests.append({
        'addSheet': {
            'properties': {
                'title': new_sheet_title
            }
        }
    })
    
    body = {
        'requests': requests
    }
    
    response = service.spreadsheets().batchUpdate(
      spreadsheetId=spreadsheetId,
      body=body).execute()


    Запустить код "здесь и сейчас" можно по ссылке https://colab.research.google.com/drive/1_IdQAxqk7...
    Ответ написан
    Комментировать
  • Реально ли на уровне dns сервера сослаться на файл на чужом хосте?

    oshliaer
    @oshliaer
    Google Products Expert
    Я думаю, что овчинка выделки не стоит.

    Прежде существовала такая функция, как Google Drive Host, которая автоматически хостила любой контент в публичной папке. Соответственно, заголовки они отдавали правильные, и браузер делал правильные вещи.

    Сейчас эта функция отключена, и сервер отдает уже другой Content-Disposition.

    Плюс, без ID соседнего файла вы не сможете подтянуть внешние файлы, даже если вам удастся подменить заголовки.
    Ответ написан
  • Как отключить обновление ячеек в гугл таблицах?

    oshliaer
    @oshliaer Куратор тега Google Sheets
    Google Products Expert
    Я думаю, что в данном случае, если вам не нужно постоянно обновлять данные, лучше воспользоваться скриптом, который сможет реализовать подобный функционал.
    Ответ написан
    Комментировать
  • Как отключить автозаполнения полей в гугл таблицах?

    oshliaer
    @oshliaer Куратор тега Google Sheets
    Google Products Expert
    Формула работает корректно - она находит все элементы удовлетворяющие условию. Вам необходимо получать только первый элемент массива. Например, вот так

    =IMPORTXML(
        "http://shop.marlin.com.ua/products/gidrokostyum-marlin-skiff-20-7-mm";
        "(//div[@class='mainTool']//p[1]//span[@class='prices'])[1]"
    )


    Рабочий пример https://docs.google.com/spreadsheets/d/1FH3QTXRRKH...
    Ответ написан
    Комментировать
  • Обратный отсчет в таблицах Google?

    oshliaer
    @oshliaer Куратор тега Google Sheets
    Google Products Expert
    5c48becdc4b69920432936.png

    Необходимы вводные параметры:
    1. Само число
    2. Дата, с которой начинать отсчет


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

    =B1+INT(B2)-INT((TODAY())), где В1 - заданное число, В2 - начальная дата.
    Тоже самое, но без приведения типов
    =B1+B2-TODAY()

    или одной формулой

    =8+INT(DATE(2019;1;21))-INT((TODAY())), 8 - заданное число, DATE(2019;1;21) - начальная дата
    Тоже самое, но без приведения типов
    =8+DATE(2019;1;21)-TODAY()

    Живой пример
    Ответ написан
    Комментировать
  • Как настроить отправку данных из таблицы в виде одной строки в другую закрытую таблицу?

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

    Замените myFunction на что-то вроде:
    function recordToMain(){
      // Берет диапазон 'Источник!B4:B8' активной Таблицы, т.о. это встроенный скрипт
      var data = SpreadsheetApp.getActive().getRange('Источник!B4:B8')
      .getValues().map(function(row){return row[0];});
      var url = 'https://script.google.com/macros/s/ZZZ/exec';
      var options = {
        method: 'POST',
        headers: {
          ContentType: 'application/json'
        },
        payload: JSON.stringify(data),
        muteHttpExceptions: true
      };
      UrlFetchApp.fetch(url, options); 
    };


    Так же создайте новый проект скриптов, в котором создайте функцию вроде:
    function doPost(e) {
      SpreadsheetApp.openById('YYY') // Должна существовать
      .getSheetByName('Приемник')    // Должен быть лист 'Приемник'
      .appendRow([new Date()].concat(JSON.parse(e.postData.contents)));
    }

    Когда вы опубликуете новый проект для всех от имени себя, то получите url_master для первой функции.
    Ответ написан
  • Как импортировать количество лайков на ютубе?

    oshliaer
    @oshliaer
    Google Products Expert
    Вариант с гашением ошибки

    =IFERROR(IMPORTXML("https://www.youtube.com/watch?v=EJVSx6CUFFc";
                       "(//*[contains(@class,'like-button-renderer-like-button')])[1]");0)


    Вариант с обработчиком ошибки

    =IF(
      ISNA(IMPORTXML("https://www.youtube.com/watch?v=EJVSx6CUFFc";
                     "(//*[contains(@class,'like-button-renderer-like-button')])[1]"));
      0;
      IMPORTXML("https://www.youtube.com/watch?v=EJVSx6CUFFc";
                "(//*[contains(@class,'like-button-renderer-like-button')])[1]")
    )
    Ответ написан
    Комментировать
  • Расширения docx.gdoc - как исправить расширение в Google Drive?

    oshliaer
    @oshliaer
    Google Products Expert
    Вам необходимо обратиться к справке по работе с Диском Google.

    Описание функционала находится в разделе Как загружать файлы и папки на Google Диск - Преоб....

    Необходимо в настройках аккаунта отключить опцию автоматического преобразования.

    Со списком поддерживаемых форматов файлов можно ознакомиться по ссылке Какие файлы можно хранить на Google Диске.

    А еще важно понимать, что файлы формата Диска Google не имеют представления, кроме мета ссылки, в локальном хранилище, поэтому получить их копию возможно только экспортом в любой удобный формат.

    Возможно, будет интересно Как работать с файлами Office.
    Ответ написан
  • Как редактировать книгу в разных форматах одновременно?

    oshliaer
    @oshliaer
    Google Products Expert
    Вам нужны специализированные программные комплексы, которые позволят создавать качественные копии в другом формате. Надеяться на волшебную кнопку в данном случае не стоит.
    Ответ написан
    Комментировать
  • Как определить e-mail текущего пользователя - от имени которого выполняется работа с Google Disk посредствам Google Drive API?

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

    Вам не надо знать имя пользователя, т.к. credential.json не используется в приложениях подобного рода. Спросите у пользователя авторизацию и вперед.

    В противном случае. Вы обязаны хранить информацию о вашем пользователе (конкретно email адрес) у себя в системе и надеяться, что он никаким хитрым задом вовремя не сможе поменять свой email на чужой.
    Ответ написан
    Комментировать
  • Загрузка картинок из google drive. Какой правильный путь?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Оба метода сопоставимы и не имеют никакой разницы в контексте инфраструктуры Гугл. Это все сервисы Диска и дергаете вы АПИ Диска. Которое само по себе не дойная корова. Не стоит расчитывать, что при частом запросе изображений вы не увидите отказа в доступе или отказа в соединении. Исполььзуйте Google Cloud Storage. Потратьте уже наконец $10 в год и получите цивильный, быстрый, надежный удобный доступ к сетевому шарингу.
    Ответ написан
  • Как изменить язык в Google Apps Script?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    5c0ffc9a09bee441507346.png
    Ответ написан
    Комментировать
  • Почему неправильно рассчитывается дата?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Ответ на этот вопрос дан на ruSO https://ru.stackoverflow.com/q/882107

    Основная идея в том, чтобы использовать базовые единицы расчета дат (миллисекунды), а не их производные (дни, часы, минуты).

    Хотелось бы добавить, что
    >  new String('Hello world!') == 'Hello world!'
    <· true
    >  new String('Hello world!') === 'Hello world!'
    <· false

    И в данном контексте создание объекта строки неуместно.
    Ответ написан
    Комментировать
  • Как получить значения всех ячеек в колонке?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    /**
     * @param {GoogleAppsScript.Spreadsheet.Sheet} sheet Лист Таблицы
     * @param {number} column Номер столбца
     * @param {number} [startRow] Пропускает количество строк сначала
     * @param {number} [numColums] Количество возвращаемых колонок
     * @returns {Object[][]} Массив значений
     * @see {@link https://toster.ru/q/549725}
     */
    var getValuesFromColumn = function(sheet, column, startRow, numColums) {
        startRow = startRow || 1;
        numColums = numColums || 1;
        var lastRow = sheet.getLastRow();
        return sheet
            .getRange(startRow, column, lastRow - startRow + 1, numColums)
            .getValues();
    };
    
    var arr = getValuesFromColumn(mainSheet, 3, 3, 2);
    Ответ написан
    Комментировать
  • Есть ли языки для описания технического задания по формирования сложных отчетов в табличной форме?

    oshliaer
    @oshliaer
    Google Products Expert
    Странное задание. Кажется немного неправдоподобным.

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

    # Контроль версий

    Всеволод Владимиров обязательно обратил бы внимание на последнюю фразу "уходит уйма времени на его изучение, трудно понять, что изменилось, что добавили". С большой вероятностью, у вас проблемы с таск/баг трекером. Его нет. Как нет и системы хранения заданий и версионирования решений. Следовательно, вы не можете проследить историю изменений и основные конструкционные нагрузки на формальные структуры и применяемые алгоритмы. Из этого следует, что при описании никто особо не использует

    # Структуры данных

    Описав рабочие структуры, вы бы имели краткие и емкие определения, которые можно было бы использовать в задании. Например, списки, деревья, временные таблицы, выборки, статические выборки, стеки, ссылки. К структурам данных всегда можно применить

    # Алгоритмы

    Чего проще, указать на схеме "срез последних"? Никогда не было остатков на "конец периода"? Уникальные. Поиск дубликатов. Поиск первого вхождения. Сортировка.

    # Классификация

    Необходимо постоянно производить классификацию отчетов и их структуризацию с применением хотя бы базовых таксономических принципов. Структуры и иерархии позволяют быстро производить поиск подобных, что в общем может само по себе уже являться решением проблемы, т.к. заменить условие не тоже самое, что создать запрос к БД заново.

    # Увеличения уровня абстракции

    После каждого (или каждой группы) цикла разработки отчета было бы не плохо увеличивать (стараться это делать) уровень абстракции описания проблемы. Ведь в конечном счете ваша цель в автоматизации. А что может быть приятнее, чем точный ответ на запрос: "Выгрузи самых активных клиентов каждого первого квартала за 10 лет".

    Получается, что лучший инструмент, опять карандаш.
    Ответ написан
    Комментировать
  • Google api: как прикрепить к письму файл из google-drive?

    oshliaer
    @oshliaer
    Google Products Expert
    Достаточно добавить ссылку на файл.

    from __future__ import print_function
    from googleapiclient.discovery import build
    from httplib2 import Http
    from oauth2client import file, client, tools
    from qs import CreateMessage, SendMessage
    
    SCOPES = 'https://www.googleapis.com/auth/gmail.send'
    
    def main():
        """Shows basic usage of the Gmail API.
        Lists the user's Gmail labels.
        """
        store = file.Storage('token.json')
        creds = store.get()
        if not creds or creds.invalid:
            flow = client.flow_from_clientsecrets('credentials.json', SCOPES)
            creds = tools.run_flow(flow, store)
        service = build('gmail', 'v1', http=creds.authorize(Http()))
    
        message = CreateMessage('xxx@gmail.com',
                                'yyy@inbox.ru',
                                'test',
                                'https://docs.google.com/spreadsheets/d/xxx/edit?usp=sharing')
        SendMessage(service, 'me', message=message)
    
    if __name__ == '__main__':
        main()


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

    oshliaer
    @oshliaer
    Google Products Expert
    Ознакомьтесь со следующей справочной информацией.
    Как сменить владельца файла или папки
    Как освободить или увеличить хранилище Google Диска

    Из нее следует, что передать права вы сможете только на файлы поддерживаемых форматов, т.н. "файлы формата Диска Гугл".
    Самый простой способ - это поместить все файлы в одну папку, выделить их и сменить владельца, при этом в текущем выделении не должно быть файлов других форматов и фалов не принадлежащих вам.

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

    Очень станно слышать, что организация использовала систему общего доступа без контроля прав. Это серьезное упущение.
    Ответ написан
    Комментировать
  • Как можно с помощью google apps script найти все ссылки в google document?

    oshliaer
    @oshliaer Куратор тега Google Apps Script
    Google Products Expert
    Основной принциип поиска ссылок и базовый код может быть таким
    /**
     * Get an array of all LinkUrls in the document. The function is
     * recursive, and if no element is provided, it will default to
     * the active document's Body element.
     *
     * @param {Element} element The document element to operate on. 
     * .
     * @returns {Array}         Array of objects, vis
     *                              {element,
     *                               startOffset,
     *                               endOffsetInclusive, 
     *                               url}
     */
    function getAllLinks(element) {
      var links = [];
      element = element || DocumentApp.getActiveDocument().getBody();
    
      if (element.getType() === DocumentApp.ElementType.TEXT) {
        var textObj = element.editAsText();
        var text = element.getText();
        var inUrl = false;
        for (var ch=0; ch < text.length; ch++) {
          var url = textObj.getLinkUrl(ch);
          if (url != null) {
            if (!inUrl) {
              // We are now!
              inUrl = true;
              var curUrl = {};
              curUrl.element = element;
              curUrl.url = String( url ); // grab a copy
              curUrl.startOffset = ch;
            }
            else {
              curUrl.endOffsetInclusive = ch;
            }          
          }
          else {
            if (inUrl) {
              // Not any more, we're not.
              inUrl = false;
              links.push(curUrl);  // add to links
              curUrl = {};
            }
          }
        }
      }
      else {
        var numChildren = element.getNumChildren();
        for (var i=0; i<numChildren; i++) {
          links = links.concat(getAllLinks(element.getChild(i)));
        }
      }
    
      return links;
    }


    Источник Get All Links in a Document
    Ответ написан
    Комментировать
  • Работа с Google docs и Google Forms?

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