Удалить все сгруппированные строки / столбцы в электронной таблице - PullRequest
0 голосов
/ 24 сентября 2018

У меня есть Google Sheet, который выполняет динамическую группировку с помощью скрипта.Я ищу функцию, которая снова избавляется от всех этих групп в листе.

Аналогично expandAllColumnGroups, я хотел бы иметь функцию с именемremoveAllColumnGroups - но, похоже, такой функции нет.

Мой нынешний подход очень медленный и громоздкий.Я провел некоторое исследование, но даже не смог найти способ получить все columnGroups или хотя бы идентификаторы start-column на листе, поэтому я перебираю каждый столбец и буквально пытаюсь удалитьгруппа, если она есть, так как невозможно определить, выходит ли группа.К сожалению, для примерно 90 колонок это занимает целую вечность (минуты, правда) ...

  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sh = ss.getActiveSheet();

  //remove all column-groups
  var group = null;
  var maxCol = sh.getMaxColumns();
  for(var c = 1; c <= maxCol; c++) {
    try {
      group = sh.getColumnGroup(c, 1); // Try to get group
      group.remove(); // Remove the group
    } catch (e) {
      //Logger.log("No Group at ColIndex "+c);
    }
  }

Любые идеи будут по-настоящему оценены.Заранее спасибо!

1 Ответ

0 голосов
/ 24 сентября 2018

Расширение моего комментария по поводу использования REST API Google Sheets для доступа и изменения групп строк / столбцов:

Группы строк / столбцов - это метаданные, связанные с ресурсом Sheet, и поэтому могут бытьполучены для всех листов в рабочей книге с одним HTTP-запросом к spreadsheets.get, с соответствующей fields спецификацией:

GET https://sheets.googleapis.com/v4/spreadsheets/{YOUR_SPREADSHEET_ID}?fields=sheets(columnGroups%2Cproperties(sheetId%2Ctitle)%2CrowGroups)&key={YOUR_API_KEY}

Демонстрационная ссылка

Приведенный выше запрос возвращает объект со свойством sheets, представляющим собой массив объектов (по 1 на лист в электронной таблице), имеющих 3 свойства: rowGroups, columnGroups и properties.Свойства группы - это массивы объектов DimensionGroup, в то время как объект properties содержит gridId / sheetId листа, который необходим для идентификации листа в различных запросах API, и его имя (что может быть полезнодля вашей собственной логики скрипта).

Чтобы удалить каждую группу строк / столбцов, вам нужно выдать столько DeleteDimensionGroupRequest с, сколько максимум depth вернулось в запросе.групп.Если вы не укажете индексы DimensionRange в своем запросе, это будет интерпретировано как весь диапазон электронной таблицы (все строки / все столбцы, в зависимости от направления).

Пример запроса (требуется проверка подлинности OAuth, а не только ключ API):

POST https://sheets.googleapis.com/v4/spreadsheets/{YOUR SPREADSHEET ID}:batchUpdate?fields=replies%2FdeleteDimensionGroup

{
  "requests": [
    {
      "deleteDimensionGroup": {
        "range": {
          "sheetId": "{SHEET 1 ID}",
          "dimension": "COLUMNS"
        }
      }
    },
    {
      "deleteDimensionGroup": {
        "range": {
          "sheetId": "{SHEET 2 ID}"
          "dimension": "COLUMNS",
        }
      }
    },
    ...
  ]
}

Демонстрационная ссылка

Каждый запрос на удаление имеет ответный ответ и этот ответ будет очень похож на первоначальный ответ, который вы получили для групп строк / столбцов из исходного запроса.Если вы заранее знали gridIds, вы можете отказаться от первоначального запроса и использовать цикл while для продолжения отправки запросов на удаление, пока ответ содержит группу измерений.


Чтобы использовать эти методы со сценарием Google Apps, вы должныможно использовать UrlFetchApp с необработанными URL-ресурсами или воспользоваться доступной «расширенной службой» клиентской библиотекой Sheets (которая должна быть сначала включена).Оба метода требуют, чтобы вы включили использование Sheets API на странице вашего сценария Google Cloud Platform .

Пример использования включенной клиентской библиотеки Sheets:

function removeAllGroups() {
  const wb = SpreadsheetApp.getActive(),
        wbId = wb.getId();
  const initial = Sheets.Spreadsheets.get(wbId, {
    fields: "sheets(columnGroups,properties(sheetId,title),rowGroups)"
  });

  // Determine the maximum depth of row & column groups on each sheet in the workbook.
  const maxDepths = {row: {}, col: {}};
  initial.sheets.forEach(function (s) {
    // if (s.properties.title ... (could write logic to do this only for certain sheets)
    var sId = s.properties.sheetId;
    if (s.columnGroups && s.columnGroups.length)
      maxDepths.col[sId] = s.columnGroups.reduce(dgMaxDepth_, 0);
    if (s.rowGroups && s.rowGroups.length)
      maxDepths.row[sId] = s.rowGroups.reduce(dgMaxDepth_, 0);
  });

  // Add all delete requests to an array
  const rqs = [];
  for (var rqType in maxDepths) {
    for (var sheetId in maxDepths[rqType]) {
      addDeleteDGRequests_(rqs, rqType, sheetId, maxDepths[rqType][sheetId]);
    }
  }

  // Send all requests.
  if (rqs.length) {
    const replies = Sheets.Spreadsheets.batchUpdate({requests: rqs}, wbId);
    console.log({message: "Batch response", response: replies});
  }
}

// Callback for Array#reduce
function dgMaxDepth_(val, dg, i, allDGs) {
  return Math.max(val, dg.depth);
}

function addDeleteDGRequests_(requests, rqType, sheetId, num) {
  const dim = rqType === "col" ? "COLUMNS" : "ROWS";
  while (num > 0) {
    var rq = {
      deleteDimensionGroup: {
        range: { sheetId: sheetId,
                 dimension: dim }
      }
    };
    requests.push(rq);
    --num;
  }
}

Ресурсы:

...