【问题标题】:Google Apps Script group rows dynamicallyGoogle Apps 脚本动态分组行
【发布时间】:2023-02-10 21:19:26
【问题描述】:

我想根据每天更改的一组行及其长度(组的深度)自动在 google 工作表上对行进行分组。 如果您看到下面的图片,我希望将 A 列中所有带有 * 的行组合在一起。

由此 :

为此:

这是我的代码,我首先删除以前存在的组,找到所有“组标题”并将它们放在名为索引的列表中,然后我尝试使用(索引,l)对行进行分组。然而,唯一创建的组是在第 4 行和第 5 行之间。

function GroupRows() {


var spreadsheet = SpreadsheetApp.getActive();
  var sheet = spreadsheet.getSheetByName('Roadmap Live')
  
  var range = sheet.getDataRange()
  var source = sheet.getDataRange().getDisplayValues()
  var vs = range.getValues()
  var index = []

  // remove groups before creating new ones

  source.forEach((r,i)=> {
    let d = sheet.getRowGroupDepth(i+1)
    if (d>=1){
      sheet.getRowGroup(i+1,d).remove()
    }
  })

  //Find rows to group

  for (var i = 1; i<source.length; i++){
    if (source[i][0] == "-"){
      // Logger.log(source[i][0])
      index.push(i+1) //this collects all the rows that has * in them
      }
      }
  Logger.log(index)


  //Group rows

  for(var i = 0;i<index.length-1;i++){
       var rangetomodify = sheet.getRange(index[i],1)
       var l = index[i+1]-index[i]-1 
       var k = index[i]
      rangetomodify.shiftRowGroupDepth(1)
      sheet.getRowGroup(index,l)
      }

}

我想一定有一些我应该使用的地图功能,但我不确定如何实现它?

【问题讨论】:

    标签: google-apps-script google-sheets


    【解决方案1】:

    我相信你的目标如下。

    • 当“A”列的值为* 时,您想对行进行分组。

    在您的脚本中,sheet.getRowGroup(index, l)index 似乎是一个数组。所以,我认为那里发生了错误。而且,在您的脚本中,似乎未检查 * 的值。我想你现在的问题However the only group created is between lines 4 and 5. 的原因可能是因为这个。

    在这种情况下,下面的示例脚本怎么样?

    示例脚本 1:

    function GroupRows() {
      const sheetName = "Roadmap Live"; // This is from your script.
      const spreadsheet = SpreadsheetApp.getActive();
      const sheet = spreadsheet.getSheetByName(sheetName);
      const lastRow = sheet.getLastRow();
      const values = sheet.getRange("A4:A" + lastRow).getDisplayValues();
      for (let i = 4; i <= lastRow; i++) {
        const d = sheet.getRowGroupDepth(i);
        if (d > 0) sheet.getRowGroup(i, d).remove();
      }
      values.forEach(([a], i) => {
        if (a == "*") {
          sheet.getRange(i + 4, 1).shiftRowGroupDepth(1);
        }
      });
      sheet.collapseAllRowGroups();
    }
    
    • 运行此脚本时,“A”列具有* 的行被分组。

    示例脚本 2:

    我认为在运行上述脚本的当前阶段,过程成本可能有点高。因此,作为另一种方法,为了降低流程成本,我想建议使用 Sheets API。示例脚本如下。

    在这种情况下,please enable Sheets API at Advanced Google services

    function sample2() {
      const sheetName = "Roadmap Live"; // This is from your script.
      const ss = SpreadsheetApp.getActive();
      const sheet = ss.getSheetByName(sheetName);
      const ssId = ss.getId();
      const sheetId = sheet.getSheetId();
      sheet.expandAllRowGroups();
      const n = Sheets.Spreadsheets.get(ssId, { ranges: [sheetName] }).sheets[0].rowGroups.reduce((n, { depth }) => n < depth ? depth : n, 0);
      const requests1 = Array(n).fill("").map(_ => ({ deleteDimensionGroup: { range: { sheetId, dimension: "ROWS" } } }));
      const values = sheet.getRange("A4:A" + sheet.getLastRow()).getDisplayValues();
      const requests2 = values.flatMap(([a], i) => a == "*" ? { addDimensionGroup: { range: { sheetId, startIndex: i + 3, endIndex: i + 4, dimension: "ROWS" } } } : []);
      Sheets.Spreadsheets.batchUpdate({ requests: [...requests1, ...requests2] }, ssId);
      sheet.collapseAllRowGroups();
    }
    
    • 运行此脚本时,运行与上述脚本相同的结果,进程成本较低。

    参考:

    【讨论】:

      猜你喜欢
      • 2018-11-16
      • 2020-06-21
      • 1970-01-01
      • 2023-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多