首页 > 解决方案 > 根据单元格值隐藏工作表

问题描述

我对学习应用程序脚本很陌生,并且查看/尝试编辑脚本,但我没有得到我想要的结果。我有一个标题为“菜单”的工作表,我希望用户从单元格 A2 中的三个不同的下拉选项(例如蓝色、黄色、绿色)中进行选择。然后我想根据选择隐藏不同的工作表。因此,如果用户选择“蓝色”,我只希望以“蓝色”一词开头的工作表可见+“菜单”工作表,其余的隐藏。黄色和绿色也一样。请注意,每种颜色有 13 张纸。

对此的任何帮助都非常感谢。

标签: google-apps-scriptgoogle-sheetsvisibility

解决方案


这是@JSmith 答案的替代实现,使用Sheets REST API 更有效地隐藏和取消隐藏大量工作表。

要使用 Apps Script 中的 Sheets REST API,您首先需要启用它,因为它是一项“高级服务”。

Sheets API 方法使您能够使用 JavaScript 表示的数据,而不是需要反复与电子表格服务交互(例如检查每个工作表的名称)。此外,批处理 API 调用作为一个操作处理,因此所有可见性更改都会同时反映而电子表格服务showSheet()hideSheet()方法在每次调用后刷新到浏览器。

var MENUSHEET = "Menu";
function onEdit(e) {
  if (!e) return; // No running this from the Script Editor.
  const edited = e.range,
        sheet = edited.getSheet();
  if (sheet.getName() === MENUSHEET && edited.getA1Notation() === "A2")
    hideUnselected_(e.source, e.value);
}

function hideUnselected_(wb, choice) {
  // Get all the sheets' gridids, titles, and hidden state:
  const initial = Sheets.Spreadsheets.get(wb.getId(), {
      fields: "sheets(properties(hidden,sheetId,title)),spreadsheetId"
  });
  // Prefixing the choice with `^` ensures "Red" will match "Reddish Balloons" but not "Sacred Texts"
  const pattern = new RegExp("^" + choice, "i");

  // Construct the batch request.
  const rqs = [];
  initial.sheets.forEach(function (s) {
    // s is a simple object, not an object of type `Sheet` with class methods
    // Create the basic request for this sheet, e.g. what to modify and which sheet we are referencing.
    var rq = { fields: "hidden", properties: {sheetId: s.properties.sheetId} };
    // The menu sheet and any sheet name that matches the pattern should be visible
    if (s.properties.title === MENUSHEET || pattern.test(s.properties.title))
      rq.properties.hidden = false;
    else
      rq.properties.hidden = true;
    // Only send the request if it would do something.
    if ((!!s.properties.hidden) !== (!!rq.properties.hidden))
      rqs.push( { updateSheetProperties: rq } );
  });
  if (rqs.length) {
    // Visibility changes will fail if they would hide the last visible sheet, even if a later request in the batch
    // would make one visible. Thus, sort the requests such that unhiding comes first.
    rqs.sort(function (a, b) { return a.updateSheetProperties.properties.hidden - b.updateSheetProperties.properties.hidden; });
    Sheets.Spreadsheets.batchUpdate({requests: rqs}, initial.spreadsheetId);
  }
}

在使用 Google 的各种 REST API 时,需要熟悉大量资源:

在包含 54 张工作表的工作簿中进行了一些测试,其中我使用 Sheets API 应用了一些更改,并使用 @JSmith 的代码来恢复更改,结果表明 API 方法的速度大约快了 15 倍,使用console.time&测量console.timeEnd。API 更改耗时 0.4 到 1.1 秒(平均 1 秒),而电子表格服务方法耗时 15 到 42 秒(平均 20 秒)。


推荐阅读