Google 表格应用程序脚本:根据自定义顺序自动对选项卡进行排序

Google Sheets App Script: Automatically sort tabs based on custom order

我们使用 Google 张音乐会制作。 模板选项卡用作给定音乐会的模板。 ALL SHOWS 选项卡用作摘要。 每次计划新的音乐会时,我们都会复制 TEMPLATE 并根据音乐会日期(例如 01/01、04/12)为其命名,然后我们将其沿着标签栏移动到适当的位置。

中间的音乐会标签是月份标签(例如一月、二月)

在对 App Script 进行了一些调整后,我想知道是否有人对 我如何根据自定义顺序在选项卡栏上自动对新创建的音乐会选项卡进行排序.

我们的自定义排序顺序如下所示:

非常感谢您的宝贵时间!

R

要排序,请使用 moveActiSheet(请参阅参考资料)。

这里的目的是用每个选项卡的名称和日期构建一个数组,如下所示

  • 2022-MM-dd 选项卡为 xx/yy
  • 2022-MM-00 作为 MMMM 的选项卡
  • z 对于其他人

并根据每行的第二个值排序

尝试

function reOrderTabs() {
  var ss = SpreadsheetApp.getActiveSpreadsheet()
  const tabs = ss.getSheets().map(sh => sh.getName())
  const monthes = listOfMonthes()
  var list = []
  tabs.forEach(t => {
    try {
      if (monthes.indexOf(t) == -1) {
        list.push([t, '2022-' + t.split('/')[1] + '-' + t.split('/')[0]])
      }
      else {
        list.push([
          t,
          Utilities.formatDate(new Date('2022/' + (monthes.indexOf(t) + 1) + '/' + 15), Session.getScriptTimeZone(), "yyyy-MM") + '-00'
        ])
      }
    }
    catch (e) { list.push([t, 'z']) }
  })
  list = list.sort(function (a, b) {
    return ('' + a[1]).localeCompare(b[1]);
  })
  list.forEach((t, i) => { 
    ss.setActiveSheet(ss.getSheetByName(t[0]));
    ss.moveActiveSheet(i + 1)
  })
}

function listOfMonthes() {
  return [...Array.from(Array(12).keys(), x => Utilities.formatDate(new Date(2022, x, 15), Session.getScriptTimeZone(), "MMMM").toUpperCase())]
}

参考资料

moveActiveSheet

forEach

sort

...array

建议

要对 sheet 选项卡进行排序,在 Apps 脚本中执行此操作的唯一方法是使用其 moveActiveSheet() method. What I have done on my sample script below is that I gathered all the current tabs information into an array, sorted them out based on your custom sort order using a combination of .forEach, .map, .filter & .sort 方法,然后重新排列它们。

示例脚本 [更新]

function main() {
  const sheet = SpreadsheetApp.getActive();
  const months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
  var res = [];
  var mainDates = [];

  //This will sort the sheet tabs by month name and date in ascending order ⤵
  sheet.getSheets().map((data, i) => {
    return (months.join(' ').toUpperCase().includes(data.getName())) ?
      [(parseInt(months.map((element, index) => { if (element.toUpperCase() == data.getName()) return index }).join('')) + 1), data.getName(), (i + 1)] :
      (/^[a-zA-Z]+$/.test(data.getName().replace(/\s+/g, ''))) ? res.unshift(['', data.getName(), '']) : mainDates.push([indetifyDate(data.getName(), months), data.getName(), (i + 1)])
  }).
    filter(x => { return x.length > 1 ? x : null }).sort(function (a, b) { return a[0] - b[0] }).
    forEach(month => {
      res.push(month);
      mainDates.sort(function (a, b) { return a[1].slice(0, 2) - b[1].slice(0, 2) }).
        forEach(data => { return data[0] == month[0] ? res.push(data.join(',').split(',')) : null })
    });
  for (var x in res) res[x][1] == "HOLIDAYS" ? res.push(res.splice(x, 1)[0]) : 0;console.log(res)
  arrangeTabs(res, sheet);
}

//This function will assign an indetifier for each tab that is in date form (e.g. 01/01) for sorting⤵
function indetifyDate(data, months) {
  var curDate = new Date(data.split('/')[1] + "/" + data.split('/')[0]).getMonth() + 1;
  return months.map((_, index) => { if ((index + 1) == curDate) return (index + 1) }).filter(x => x).join('');
}

//This function will move sheets tabs based on their order from process above ⤵
function arrangeTabs(res, sheet) {
  res.forEach((data, pos) => {
    sheet.setActiveSheet(sheet.getSheetByName(data[1]))
    sheet.moveActiveSheet((pos + 1));
  })
}
  1. 脚本将获取所有选项卡名称(在原始位置)并将它们放入数组中
  2. 然后,它将遍历数组并使用第一个三元条件过滤具有每月名称(例如 JANUARY)的选项卡
  3. 然后下一个三元条件将过滤 non-date 格式并将 unshift 它们位于 res 数组变量的开头以及 [=12= 中的其余选项卡] 格式将根据它们所属的月份进行进一步排序和过滤,然后再添加到 res 变量中。
  4. 最后,HOLIDAYS 选项卡将放在 res 数组变量的末尾
  5. 一旦 res 数组被相应地排列,函数 arrangeTabs 就会将它们排列在实际的点差上 sheet.

示范[​​=27=]
  • 在 运行 main 函数之后,选项卡按如下所示排序: