【问题标题】:Hide Sheets Based on a Cell Value根据单元格值隐藏工作表
【发布时间】:2019-02-22 21:44:40
【问题描述】:

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

非常感谢任何帮助。

【问题讨论】:

  • 欢迎来到 Stack Overflow。提供链接对于上下文很有用。但请在您的问题中包含源代码。谢谢!
  • @Shawn 你能分享一下电子表格吗?我很高兴能和你一起看到它。
  • @Jsmith - 这是表格docs.google.com/spreadsheets/d/…

标签: google-apps-script google-sheets visibility


【解决方案1】:

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

要从 Apps 脚本使用 Sheets REST API,您首先需要enable it,因为它是“advanced service”。

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 秒)。

【讨论】:

  • Sheets API 是 Sheets REST API。 REST 描述 API 类型。与 SOAP 等相比。
  • 如果您想查看,我可能输入了错误的脚本,因为它似乎没有为我过滤(我的经验不足可能是罪魁祸首)。 docs.google.com/spreadsheets/d/…
  • 简单触发器函数执行时,只能在 Stackdriver Logs / Execution Transcripts 中查看它们的错误。
【解决方案2】:

试试这个代码:

function onEdit(e)
{
  //filter the range
  if (e.range.getA1Notation() == "A2")
  {
    // get value of cell (yellow||green||...)
    onlySheet(e.value)
  }
}

function onlySheet(str)
{
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  //get all sheets
  var sheets = ss.getSheets();
  for (var i = 0; i < sheets.length; i++)
  {
    //get the sheet name
    var name = sheets[i].getName();
    // check if the sheet is not the "Menu" sheet
    if (name != "Menu")
    {
      // check if the name of the sheet contains the value of the cell, here str
      //if it does then show sheet if it doesn't hide sheet
      if (name.match(new RegExp(str, "gi")))
        sheets[i].showSheet();
      else
        sheets[i].hideSheet();
    }
  }
}

【讨论】:

    猜你喜欢
    • 2020-08-23
    • 1970-01-01
    • 2020-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-17
    相关资源
    最近更新 更多