Google表格:如何让我的自定义功能自动刷新?

时间:2014-05-01 20:55:17

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

我为自己编写了一个Google Sheet应用程序,其中包括顾问处理项目的时间表。我编写了一个自定义函数,显示日历中的摘要信息;例如:

Tubb, Ernest|Project 1
Tubb, Ernest|Project 2
Perkins, Carl|Project 1

我编写了这个函数,因为我使用的FILTER()函数混乱是不可理解的;并且执行相同操作所需的javascript相对简单。

然而,我发现,当基础数据发生变化时,我的函数写入的单元格 NOT 重新计算它们与FILTER()函数的相同方式。如何编写某种类型的监听器,使基础数据发生变化时刷新我的函数输出?我是否必须手动使用onEdit()函数?

这是我的功能:

// Global Constants - these will change each quarter based on the calendar structure.
var CALENDAR_QUARTER_START = "F"
var CALENDAR_QUARTER_END = "CS"

// Generate a nice 2-column display of Consultant and Project(s) they are scheduled on,
// based on the consultant names and calendar codes in the Calendar tab.
// "billable" parameter specifies the return of only uppercase activities (true) or all activities (false)
function fortifyConsultantsAndProjects( billable ){

  // Resolve arguments
  var billable = arguments[0];
  if (arguments[0] == undefined) billable = true;

  var calendar = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Calendar");
  var consultants = calendar.getRange( "A8:A" ).getValues();

  var ret = [];
  var row = 0;
  for ( var i=0; i<consultants.length; i++ ){
    var consultant = consultants[i].toString();
    var projects = fortifyGetProjectsForConsultant( consultant, billable );
    for (var j=0; j < projects.length; j++ ) {
      ret.push( [] );
      ret[row][0] = consultant;
      ret[row][1] = projects[j];
      row++;
    }
  }
  return ret;
}

function fortifyGetProjectsForConsultant( consultant, billable ){

  // Resolve arguments
  var consultant = arguments[0];
  if (arguments[0] == undefined) consultant = "Held, Doug";
  var billable = arguments[1];
  if (arguments[1] == undefined) billable = true;

  // Get the range of consultants defined in Column A of Calendar tab.
  var calendar = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Calendar");
  var consultants = calendar.getRange( "A8:A" ).getValues();

  // Identify which Calendar row contains the specified consultant's schedule.
  var row;
  for ( var i=0; i< consultants.length; i++){
    //Browser.msgBox( "compare " + consultant + " and " + consultants[i] );
    if ( consultants[i].toString() == consultant ){
      row = i+8;
      break;
    }
  }

  // Obtain all the consultant's schedulings. Contains many duplicates, so sort.
  var projects = calendar.getRange( CALENDAR_QUARTER_START + row + ":" + CALENDAR_QUARTER_END + row + "" ).getValues()[0].sort();

  // Iterate through the sorted project codes, removing duplicates and blanks
  var ret = [];
  var row = 0;
  var prev = "";
  for ( var i = 0; i< projects.length; i++ ){
    var temp = projects[i].toString();
    if (temp != "" && temp != prev ){

      // Resolve whether to return each row based on project billability (uppercase)
      if ( temp.toUpperCase() == temp || billable == false ){
        ret[row] = temp;
        row++;
      }
      prev = temp;

    }
  }
  return ret;
}

1 个答案:

答案 0 :(得分:1)

好吧,因为没有人回答,我会解释我是如何解决这个问题的。

不是零参数函数参数列表,而是接收所有范围(例如,日历!A8:A,您在此处看到硬编码的范围)。然后,只要参数范围中的数据发生变化,就会再次调用该函数。这有时会在Google表格中造成某种运行时错误 - 在更新时,我有时会得到&#34;文档不可用&#34;以及重新加载表格的说明。

当接收范围作为参数时,该数据按值接收为单元值的二维数组 - 与从Range.getValues()返回的数组相同。