在 Google 表格中对具有多个小节的一列进行排序

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

我正在尝试对谷歌表格中的一些数据进行排序,这些数据在一列中对齐,但具有多个小节,这些小节应该彼此独立排序。

由于小节数量较多,我不想对每个小节进行单独排序,那么有没有更好的方法呢? 尽管每个部分开头的另一列中有一个附带的部分编号,但各小节的长度没有模式/标准。可以根据需要对数据进行重新格式化,以对各小节进行排序。 我希望所附的示例视觉效果可以帮助您了解我的目标。

Google 表格页面显示当前数据和所需结果的示例。当前数据有 2 列,一列是空的,除了在每个小节开始处计数的数字之外,另一列包含每个节中的相关数据。期望的结果是每个小节内数据列中的数据按升序排序,但小节之间的数据尚未以任何方式排序:

我首先尝试使用谷歌表格中内置的高级排序选项,尽管这没有提供正确对小节进行排序的选项。

我考虑编写一个自定义函数来执行该任务,但从自定义函数访问大量单元格似乎很棘手,并且官方文档没有帮助阐明如何实现这一点。

我还考虑了一个循环宏,它访问节号的行号以了解在哪里排序,但不幸的是,我遇到了与自定义函数相同的问题,即无法轻松访问有问题的数据,尽管我确实认为这可能更有效?

我还认为重新排列数据以使其更容易排序可能很有用。

如有任何帮助,我们将不胜感激!

google-sheets google-apps-script
1个回答
0
投票

根据您的情况,以下两种模式怎么样?在这些模式中,假设节列和数据列是“B”和“C”并且存在第一个标题行。请注意这一点。

如果与您的实际情况不同,请根据您的情况修改

const range = sheet.getRange("B2:C" + sheet.getLastRow());
的范围。

模式1:

在此模式中,“C”列的值通过数组中 Javascript 的排序方法进行排序。在这种情况下,仅对值进行排序,而不对单元格格式进行排序。但是,加工成本比模式2要低。

function sample1() {
  const sheetName = "Sheet1"; // Please set the sheet name.

  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
  const range = sheet.getRange("B2:C" + sheet.getLastRow());
  const { values } = range.getValues().reduce((o, [b, c], i, a) => {
    o.temp.push(c);
    if (i > 0 && b.toString()) {
      const t = o.temp.pop();
      o.values.push(o.temp);
      o.temp = [t];
    } else if (i == a.length - 1) {
      o.values.push(o.temp);
    }
    return o;
  }, { temp: [], values: [] });
  const res = values.flatMap(e => e.sort((a, b) => a - b).map(f => [f]));
  range.offset(0, 1, res.length, 1).setValues(res);
}

运行此脚本时,“C”列将按“B”列的值排序。

模式2:

在此模式中,“C”列的值通过 Class Range 的排序方法进行排序。在这种情况下,单元格格式也会排序。

function sample2() {
  const sheetName = "Sheet1"; // Please set the sheet name.

  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
  const range = sheet.getRange("B2:C" + sheet.getLastRow());
  const { values } = range.getValues().reduce((o, [b], i, a) => {
    o.temp.push(`C${i + 2}`);
    if (i > 0 && b.toString()) {
      const t = o.temp.pop();
      o.values.push(`${o.temp[0]}:${o.temp.pop()}`);
      o.temp = [t];
    } else if (i == a.length - 1) {
      o.values.push(`${o.temp[0]}:${o.temp.pop()}`);
    }
    return o;
  }, { temp: [], values: [] });
  sheet.getRangeList(values).getRanges().forEach(r => r.sort(3));
}

运行此脚本时,“C”列将按“B”列的值排序。

注:

  • 当我使用您的显示情况测试这些模式时,我确认没有发生错误并且已完成正确的排序。因此,请根据您问题中的显示情况测试我的脚本。请注意这一点。

参考资料:

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