我几十年没有编码了,而且我正在寻找一种方法来自动化我现在的#倒计时"电子表格。我目前以一种丑陋,容易出错和迂回的方式做事,一个非常小的脚本应该能够让它变得更好。
目标:
- 在单元格中输入以小时为单位的持续时间(通常为0到1,000之间) - 下面一个单元格,可以计算剩余的小时数。
现状:
我已将表单设置为每小时自动重新计算,这很好 然后进行4个单元设置,在多个列上重复以跟踪多个计时器:
我喜欢什么:
- 摆脱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)
}
答案 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作为其基础语言,并使用一些自定义库来处理各种自定义内容(如电子表格)。
您可能会发现一些有用的参考资料: