根据缩进或内容动态对单元格进行分组

问题描述 投票:0回答:1

我的会计软件将最新数据导出到电子表格中,其中包含大量数据,如果不进行分组就很难分析。

我想根据与上面的行的相似性对行进行分组(或者可能基于缩进,但这可能更困难)。

例如,有一个折扣和促销部分,其中有多个子项目(有时可能会添加一个项目,因此在下面的示例中,在某个随机点可能有 4 行子内容,而不是 3 行)。底部是该部分的总计。

总计行始终具有相同的标题,并在前面附加“总计”一词。

    Discounts & promotions
        Discounts & promotions - Facebook (via Shopify)
        Discounts & promotions - Shopify - name
        Discounts & promotions - Shopify - name - gift card giveaways
    Total Discounts & promotions

这里是一些示例数据的链接。

是否有一个脚本可以遍历整个工作表并按逻辑对各个部分进行分组 - 如果该行与另一行具有相同的确切内容+前面的“总计”一词,则将它们分组。

(首先我需要脚本来删除所有组 - 这是有效的,最后我需要脚本来折叠所有组,这也是有效的)

这是我尝试过的代码。电子表格中的数据没有发生任何变化。

function removeAllGroups1() {
  const ss = SpreadsheetApp.getActive();
  const sh = ss.getSheetByName("Daily");
  const rg = sh.getDataRange();
  const vs = rg.getValues();
  vs.forEach((r, i) => {
    let d = sh.getRowGroupDepth(i + 1);
    if (d >= 1) {
      sh.getRowGroup(i + 1, d).remove()
    }
  });
}

function groupRows() {
  const sheet = SpreadsheetApp.getActiveSheet();
  const range = sheet.getRange("A1:A" + sheet.getLastRow());
  const values = range.getValues();

  let previousValue = "";
  let groupStartRow = 1;

  for (let i = 0; i < values.length; i++) {
    const currentValue = values[i][0];

    // Check if the current value is a "Total" version of the previous value
    if (currentValue.startsWith("Total ") && currentValue.substring(6) === previousValue) {
      // Group the current row with the previous row
      sheet.getRange(i + 1, 1).shiftRowGroupDepth(1);
    } else {
      // Reset the group start row
      groupStartRow = i + 1;
    }

    previousValue = currentValue;
  }
}

function collapse() {
 const ss = SpreadsheetApp.getActive();
  const sh = ss.getSheetByName('Daily');
   let lastRow = sh.getDataRange().getLastRow();
  
  for (let row = 1; row < lastRow; row++) {
    let depth = sh.getRowGroupDepth(row);
    if (depth < 1) continue;
    sh.getRowGroup(row, depth).collapse();
  }
}
google-sheets google-apps-script
1个回答
0
投票

使用

Array.findIndex()
,如下所示:

function groupRows(keyRange = SpreadsheetApp.getActive().getRange('Daily!A5:A')) {
  const sheet = keyRange.getSheet();
  removeAllGroups_(sheet);
  const rowStart = keyRange.getRow();
  const keys = keyRange.offset(0, 0, sheet.getLastRow() - rowStart + 1).getDisplayValues().flat().map(k => k.trim());
  const groups = [];
  keys.forEach((key, startIndex) => {
    const endIndex = keys.findIndex(k => k === `Total ${key}`);
    if (endIndex !== -1) groups.push([rowStart + startIndex + 1, endIndex - startIndex]);
  });
  groups.forEach(([start, numRows]) => sheet.getRange(start, 1, numRows).shiftRowGroupDepth(1).collapseGroups());
}

function removeAllGroups_(sheet) {
  sheet.getDataRange().getValues().forEach((_, index) => {
    const depth = sheet.getRowGroupDepth(index + 1);
    if (depth) sheet.getRowGroup(index + 1, depth).remove();
  });
}

参见 Array.findIndex()

© www.soinside.com 2019 - 2024. All rights reserved.