性能问题:用于过滤行的Google脚本

时间:2015-10-21 16:13:33

标签: performance google-apps-script

以下函数用作基于特定列过滤器参数的表行(隐藏行)的过滤器。 执行速度非常慢,尽管该表总共有115条记录。

有关让它运行得更快的任何建议吗? 我可以关闭任何后台功能,例如Excel(屏幕更新,工作表计算)吗?

function filterOnDate(rowHeader, colFirst, colDate, typeFilter, valueFilter){
  /* Hides rows of table where a date column meets a year or a month criteria. Params:
  rowHeader: row number of table headers.
  colFirst: column number of first table column.
  colDate: column number of filter column (listing dates).
  typeFilter: two possible types: "month", "year". Are we filtering on date's month or year.
  valueFilter: filter value (i.e. month name or year number).
  */

  if (valueFilter===undefined){ return; }

  filterClearFilters(true); //Clear existing filters



 var sh = SpreadsheetApp.getActiveSpreadsheet();
 var ss = sh.getActiveSheet();
 var tableData = ss.getRange(rowHeader+1, colFirst,ss.getDataRange().getLastRow()-rowHeader, ss.getDataRange().getLastColumn()-colFirst);
 var numRows = tableData.getNumRows();
 var values = tableData.getValues();

 var months = ss.getRange("Months_Table").getValues();

  if (typeFilter=="year") {
    ss.getRange("Members_Filter_Month").clearContent();
  } else {
    ss.getRange("Members_Filter_Year").clearContent();
  } 

 for (var i=0; i <=numRows-1 ; i++){

   var row =values[i];
   var myValue = row[colDate-colFirst]; //Date value of current row in loop, on filtered column

   var bolHideRow = true;
   if (!myValue=='') {
     if (typeFilter="month" && months[myValue.getMonth()]==valueFilter){
       bolHideRow = false;
     }
     if (typeFilter="year" && myValue.getFullYear()==valueFilter){
       bolHideRow = false;
     }
   }
   if (bolHideRow) {
   ss.hideRows(i+rowHeader+1);
   }

 }
}

2 个答案:

答案 0 :(得分:2)

这很慢,因为在工作表上调用hideRows()等操作需要在引擎盖下进行API服务调用,每次最多可能需要几秒钟。没有什么可以做的加速API调用,最好的办法就是尽可能避免以这种方式对它们做很多动作。显示问题,例如您提到的Excel问题,这不是一个因素。

我看了几个选项。首先,您是否需要使用脚本执行此操作?这是你可以很容易地使用内置的表格过滤。 (参见“数据”菜单下的“过滤器”)。

如果由于某种原因绝对必须是脚本,您希望尝试尽可能减少服务调用。

如果您隐藏的行数多于显示的数量,则可以翻转逻辑,隐藏开头的所有行,然后只显示您需要的行。

如果系列中的多个行经常被隐藏在一起,您可以跟踪要隐藏的连续行,然后将它们隐藏在组中,而不是一次隐藏它们。

您可以将您感兴趣的行写入单独的工作表,而不是隐藏行。使用像“setValues()”这样的单个函数一次写出多个值只是一个API服务调用,因此它与在单行上调用hideRows()所花费的时间相同。

答案 1 :(得分:1)

当仅应用了选定数量的列时,我只通过删除应用了on的列上的过滤器就可以提高性能。

  sheet = SpreadsheetApp.getActiveSheet(); //for testing purpose only
  var filter = sheet.getFilter();
  if (filter !== null) {  // tests if there is a filter applied
    var range = filter.getRange(); // prevents exception in case the filter is not applied to all columns
    var firstColumn = range.getColumn();
    var lastColumn = range.getLastColumn();
    for (var i = firstColumn; i < lastColumn; i++) {
      if (filter.getColumnFilterCriteria(i) !== null) { // only remove filter on column if one exists.
        filter.removeColumnFilterCriteria(i); // this is expensive (slow) 
      };
    }