【问题标题】:How to skip hidden rows while iterating through Google Spreadsheet w/ Google Apps Script如何在使用 Google Apps 脚本遍历 Google 电子表格时跳过隐藏行
【发布时间】:2011-07-22 17:29:25
【问题描述】:

我有一个包含许多隐藏行的 Google 电子表格,我想在遍历电子表格中的行列表时跳过它们。

这主要是一个效率问题,因为我正在处理超过一半的行被隐藏并且不需要检查。

任何帮助将不胜感激。

【问题讨论】:

  • 好问题。该api具有隐藏和显示行的功能,但似乎没有任何查询显示/隐藏状态的功能。似乎是一个合理的增强请求。
  • 是的——这个也让我很烦。希望有解决方案
  • 我唯一的线索是,当你创建一个跨列的命名范围时,如果你查询该范围内的行数,你会得到非隐藏行的数量。然而,它仍然遍历所有行。这不仅奇怪,而且还破坏了遍历命名范围的“所有行”的代码......

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


【解决方案1】:

在 Apps 脚本中没有直接的方法来执行此操作,但如果您想为它加注星标,可以打开 feature request 以提供一种获取行的显示/隐藏状态的方法。

【讨论】:

  • 这个请求已经开放三年了,现在。今天,它获得了 89 颗星,是前 10 名中对表格 API 功能的最古老请求。
  • 没有了。请参阅下面的 Gravity Grave 答案。
【解决方案2】:

2018 年的新 API 可用于解决此问题:isRowHiddenByUser。另见isRowFilteredByUser

【讨论】:

  • 终于!太好了!
【解决方案3】:

使用SUBTOTAL 的解决方法。创建 2 列 A 和 B。A 必须始终有一个值,而 B 有一组公式。这 2 列如下所示:

A |           B
---------------------------
1 | =NOT(SUBTOTAL(103, A1))
1 | =NOT(SUBTOTAL(103, A2))
1 | =NOT(SUBTOTAL(103, A3))

SUBTOTAL 使用指定的聚合函数返回小计。第一个参数 103 定义了用于聚合的函数类型。第二个参数是应用函数的范围。

  • 3 表示COUNTA,统计范围内的值个数
  • +100 表示忽略范围内的隐藏单元格。

SUBTOTAL 的范围为 1 单元格的结果在隐藏单元格时为 0,在显示单元格时为 1。 NOT 反转它。

现在您可以使用脚本读取 B 列,以了解是否隐藏了一行。

这是转置的问题和答案:https://stackoverflow.com/a/27846180/1385429

【讨论】:

    【解决方案4】:

    问题跟踪器持有该请求since Aug 3, 2010,具有中等优先级和“已分类”状态。超过 3 年,GAS 团队没有任何解决方案的迹象。

    我的解决方法是使用一个特殊的前导字符来指示行/列的可见性状态,它是顶部标题行/列的单元格中的前导反引号 (`)。 如果在列标题中使用了合并的单元格,则 应该专门为该功能留一个空的顶行,直到 Google 工程师改进 API。 如果第一行/列单元格中有公式,同样适用。 这些专用行/列本身可以隐藏。

    开始使用此功能后,应从自定义菜单执行每个显示/隐藏列/行命令,否则由于缺少/过多的反引号,以编程方式遍历范围时会出现错误。

    例如要隐藏选定单元格的行,调用以下函数

    function hideSelectedRows() {
      var sheet = SpreadsheetApp.getActiveSheet();
      var range = SpreadsheetApp.getActiveRange();
    
      // hide rows and add a ` backtick to the header cell
      for (var row = range.getRow(); row <= range.getLastRow(); row++)
      {
        // add backtick only if it isn't there (that may happen when manually unhiding the rows)
        var cellHeader      = sheet.getRange(row, 1)
        var cellHeaderValue = cellHeader.getValue()    
        if ( !cellHeaderValue.match(/^`/) ) {
          cellHeader.setValue('`' + cellHeaderValue)
        }
    
        // hide rows of selected range
        sheet.hideRows( row );
      }
    }
    

    还有菜单

    SpreadsheetApp.getActiveSpreadsheet()
    .addMenu("Show/Hide", [
        { name : "Hide Selected Rows",    functionName : "hideSelectedRows"    },
        { name : "Hide Selected Columns", functionName : "hideSelectedColumns" },
        null,
        { name : "Hide Rows",             functionName : "hideRows"            },
        { name : "Hide Columns",          functionName : "hideColumns"         },
        null,
        { name : "Show Rows",             functionName : "showRows"            },
        { name : "Show Columns",          functionName : "showColumns"         },
        null,
        { name : "Show All Rows",         functionName : "unHideAllRows"       },
        { name : "Show All Columns",      functionName : "unHideAllColumns"    }
      ])
    

    一旦谷歌工程师找到时间改进 onChange 事件,就可以自动放置这些反引号。目前,changeType 仅限于EDIT, INSERT_ROW, INSERT_COLUMN, REMOVE_ROW, REMOVE_COLUMN, INSERT_GRID, REMOVE_GRID, OTHER,没有任何关于插入/删除行/列的详细信息。看起来 GAS 背后的团队很少。我希望他们能雇佣更多的程序员(khm khm)

    【讨论】:

    • 完整的脚本在哪里?我想试试
    【解决方案5】:

    至于解决方法,可以使用SUBTOTAL 函数,该函数可以返回垂直范围单元格的小计。

    语法是:

    SUBTOTAL(function_code, range1, [range2, ...])
    

    可以通过在其中添加 10(到个位数代码)来跳过任何这些代码的隐藏值。

    例如 102 表示 COUNT 跳过隐藏单元格,110 表示 VAR 这样做。

    相关:Google Spreadsheets sum only shown rows 在 Webapps SE

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-21
      相关资源
      最近更新 更多