删除电子表格中所有分组的行/列
Remove all grouped rows / columns in a spreadsheet
我有一个 Google Sheet 可以使用脚本进行动态分组。我正在寻找一个函数,它可以再次删除 sheet 中的所有 Groups。
类似于expandAllColumnGroups
,我想要一个名为removeAllColumnGroups
的函数-但似乎没有这样的函数可用。
我目前的方法非常缓慢和繁琐。我做了很多研究,但甚至找不到一种方法来获取 sheet 中的所有 columnGroups
或至少是起始列 ID,因此我遍历每一列并逐字地 尝试 如果有一个组,则删除该组,因为无法判断是否有一个组退出。不幸的是,对于大约 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);
}
}
如有任何想法,我们将不胜感激。提前致谢!
扩展我的评论:使用 Google Sheets REST API 访问和修改 row/column 分组:
Row/Column 组是与 Sheet
资源关联的元数据,因此可以通过对 [=30= 的单个 HTTP 请求为工作簿中的所有 sheet 获取],使用适当的 fields
规范:
GET https://sheets.googleapis.com/v4/spreadsheets/{YOUR_SPREADSHEET_ID}?fields=sheets(columnGroups%2Cproperties(sheetId%2Ctitle)%2CrowGroups)&key={YOUR_API_KEY}
上面请求returns一个带有sheets
属性的对象,这是一个对象数组(每个sheet在spreadsheet ) 具有 3 个属性:rowGroups
、columnGroups
和 properties
。组属性是 DimensionGroup
对象的数组,而 properties
对象包含 sheet 的 gridId/sheetId,您需要用它来识别各种 sheet =82=] 请求及其名称(可能对您自己的脚本逻辑有用)。
要删除每个 row/column 组,您需要在请求中发出尽可能多的 DeleteDimensionGroupRequest
s to do so as the maximum depth
returned in your query's groups. If you do not specify the indices of the DimensionRange
,这被解释为传播的整个范围sheet(所有行/所有列,取决于方向)。
示例请求(需要 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",
}
}
},
...
]
}
每个删除请求都有一个 reply response,该响应将与您从初始查询中为 row/column 组获得的初始响应非常相似。如果您事先知道 gridId,则可以放弃初始查询并使用 while 循环在响应包含维度组时继续发送删除请求。
要将这些方法与 Google Apps 脚本一起使用,您可以将 UrlFetchApp
与原始 URL 资源一起使用,或者利用可用的 "advanced service" client library Sheets
(which must first be enabled). Both methods require you to enable use of the Sheets API from your script's Google Cloud Platform project 页面。
使用已启用客户端库的示例 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;
}
}
资源:
这是一个简单的解决方案。
function removeAllGroupsFromSheet() {
let sheet = SpreadsheetApp.getActiveSheet();
let lastRow = sheet.getDataRange().getLastRow();
for (let row = 1; row < lastRow; row++) {
let depth = sheet.getRowGroupDepth(row);
if (depth < 1) continue;
sheet.getRowGroup(row, depth).remove();
}
}
我有一个 Google Sheet 可以使用脚本进行动态分组。我正在寻找一个函数,它可以再次删除 sheet 中的所有 Groups。
类似于expandAllColumnGroups
,我想要一个名为removeAllColumnGroups
的函数-但似乎没有这样的函数可用。
我目前的方法非常缓慢和繁琐。我做了很多研究,但甚至找不到一种方法来获取 sheet 中的所有 columnGroups
或至少是起始列 ID,因此我遍历每一列并逐字地 尝试 如果有一个组,则删除该组,因为无法判断是否有一个组退出。不幸的是,对于大约 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);
}
}
如有任何想法,我们将不胜感激。提前致谢!
扩展我的评论:使用 Google Sheets REST API 访问和修改 row/column 分组:
Row/Column 组是与 Sheet
资源关联的元数据,因此可以通过对 [=30= 的单个 HTTP 请求为工作簿中的所有 sheet 获取],使用适当的 fields
规范:
GET https://sheets.googleapis.com/v4/spreadsheets/{YOUR_SPREADSHEET_ID}?fields=sheets(columnGroups%2Cproperties(sheetId%2Ctitle)%2CrowGroups)&key={YOUR_API_KEY}
上面请求returns一个带有sheets
属性的对象,这是一个对象数组(每个sheet在spreadsheet ) 具有 3 个属性:rowGroups
、columnGroups
和 properties
。组属性是 DimensionGroup
对象的数组,而 properties
对象包含 sheet 的 gridId/sheetId,您需要用它来识别各种 sheet =82=] 请求及其名称(可能对您自己的脚本逻辑有用)。
要删除每个 row/column 组,您需要在请求中发出尽可能多的 DeleteDimensionGroupRequest
s to do so as the maximum depth
returned in your query's groups. If you do not specify the indices of the DimensionRange
,这被解释为传播的整个范围sheet(所有行/所有列,取决于方向)。
示例请求(需要 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",
}
}
},
...
]
}
每个删除请求都有一个 reply response,该响应将与您从初始查询中为 row/column 组获得的初始响应非常相似。如果您事先知道 gridId,则可以放弃初始查询并使用 while 循环在响应包含维度组时继续发送删除请求。
要将这些方法与 Google Apps 脚本一起使用,您可以将 UrlFetchApp
与原始 URL 资源一起使用,或者利用可用的 "advanced service" client library Sheets
(which must first be enabled). Both methods require you to enable use of the Sheets API from your script's Google Cloud Platform project 页面。
使用已启用客户端库的示例 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;
}
}
资源:
这是一个简单的解决方案。
function removeAllGroupsFromSheet() {
let sheet = SpreadsheetApp.getActiveSheet();
let lastRow = sheet.getDataRange().getLastRow();
for (let row = 1; row < lastRow; row++) {
let depth = sheet.getRowGroupDepth(row);
if (depth < 1) continue;
sheet.getRowGroup(row, depth).remove();
}
}