Google Sheet脚本自动计算倒计时

时间:2016-02-01 12:12:17

标签: google-apps-script google-sheets

我几十年没有编码了,而且我正在寻找一种方法来自动化我现在的#倒计时"电子表格。我目前以一种丑陋,容易出错和迂回的方式做事,一个非常小的脚本应该能够让它变得更好。

目标:

- 在单元格

中输入以小时为单位的持续时间(通常为0到1,000之间) - 下面一个单元格,可以计算剩余的小时数。

现状:

我已将表单设置为每小时自动重新计算,这很好 然后进行4个单元设置,在多个列上重复以跟踪多个计时器:

  • 第一个单元格(B2)是输入单元格,以小时为单位输入

  • 第二个单元格(B3)=现在()+ B2 / 24,计算由B2

  • 生成的预期完成日期
  • 第三个单元格(B4)包含B3值的硬拷贝,以便重新计算不会改变那些"坚定的预期完成情况"日期。我每次修改B2时都要将+ pastevalue从B3复制到B4,这是该设置的主要问题

  • 第4个单元格(B5)=(int(B4)-int(now()))* 24 +小时(B4)-hour(now())并且是我注意的运行倒计时。不得不使用int()而不是day()否则我会在开始和完成日期不是同一个月时遇到错误。

我喜欢什么:

- 摆脱2个中间单元格和它们之间的繁琐+容易出错的手动复制粘贴值。

- 一个自动触发脚本,使用可能

的公式直接用倒计时填充B5(实际上,这将改为B3)  (int(B2 + $ datetime_of_B2_modification) - int(now())* 24 + hour(B2 + $ datetime_of_B2_modification) - 小时(现在))。

B2是对B2值的直接引用,$ datetime_of_B2_modification是每次我修改B2时计算的值,并且仅在那时(不是在重新表单时,而不是当我将鼠标悬停在B2上但不是't = t时)实际上修改它)然后被编码成B5的公式; now()是gSheet的实际函数,它现在返回日期时间。

- 理想情况下,自动触发器脚本会自动创建一个单元格下面一个单元格,我输入小时数,即我不必为电子表格中的每一列创建不同的脚本,它会创建公式"下面有一个单元格,而不是固定单元格。

我几十年前的技能生锈了,我一直在努力开始,但我无处可去。如果有人能够神奇地鞭打那个剧本,我将非常感激!

最好的问候,Olivier

考虑到这一点,自动化复制+粘贴值步骤的脚本不会改变其他任何东西将是一个不错的第一步。除去2个额外的行并不是那么重要,尽管它会很好。

第一个回答后编辑:我需要的东西与下面的内容相符; ??线条是我知道错误的线条

function onEdit(e)() {
  if(!e) return;

  var book = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = book.getActiveSheet()
  var sourcecell = book.getActiveCell();

//check the edited cell is a valid source cell

??  var sourcecelladdress = right(getA1Notation(sourcecell),2)  // need to get result such as: 'A1" or 'B1'...
  if ('B2C2D2B8C8D8'.indexOf(sourcecelladress) =-1) return;

// check the cell has actually been modified
  if (e.value = e.oldValue) return; 

//OK, so we're in a valid source cell, and it HAS been modified
// now let's build the formula string

  var sourcevalue = sourcecell.getValue()
  var enddate = sourcevalue/24 + now()
  var enddateday = int (endate) * 24
  var endatetime = hour (enddate)
??  var countdownformula = '=' + (enddateday + enddatehour) + '- (int(now())*24) - hour(now())'


//and now let's put it in the destination cell

??  var destcell = sourcecell + ????? (one row down from active cell)
??  destcell.setformula(countdownformula)
}

1 个答案:

答案 0 :(得分:0)

下面的代码没有经过优化,有效,或者必然是处理它的最佳方式。以下演示了您所说的一些功能,并提出了解决问题的多种方法。

function onEdit(e){
  // if we did not receive the event data, it is likely 
  // no event occured. This should only happen if we 
  // call it directly.
  // So... if (no event object) get out;
  if(!e) return;


  // Look up the spreadsheet and and actual 
  // sheet we are goign to be interacting with
  var book = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = book.getSheetByName('Sheet1')

  // get the "Working Range" of cells
  var range = book.getRange('B2');

  // determine if its the range we are interested in
  var target = range.getA1Notation();
  var change = e.range.getA1Notation();
  if(range.getA1Notation() == e.range.getA1Notation()){

    // double check that the value actually changed
    if(e.value != e.oldValue){
      // IT CHANGED!!
      book.toast('Timer setting change detected: ' + e.oldValue + ' -> ' + e.value);

      // Change some formulas using relative notiation
      range = book.getRange('B4');
      range.setFormulaR1C1('=R[-1]C[0]');
      range.setValues(range.getValues());

      // Apply the future time to a formula in the spreadsheet
      range = book.getRange('B5');
      range.setFormula('=floor((B4-now())*24)');
      // copy and paste the value calculated by the formula
      range.setValue(range.getValue());

      //** Hardcoded alternative
      //** I would actually suggest not doing i this way and instead just hiding row 4

      // Calculate future time 
      // (this is broken because date math is annoying)
      var future = new Date(); // get NOW
      future.setHours(future.getHours() + e.value); //Add the specified hours to the current hours
      future = (future.getTime() / 86400000.0); // convert the time to fractional days
      future = future + 25569; //adjust the days for different start epochs

      // set the formula
      range = book.getRange('B6');
      range.setFormula('=floor((' + future + '-now())*24)');
    }
  }
}

我知道至少B6计算不正确,但几乎正确。我将它留给读者来修复日期数学部分。

GoogleAppsScript使用javascript作为其基础语言,并使用一些自定义库来处理各种自定义内容(如电子表格)。

您可能会发现一些有用的参考资料: