如何强制新的Google电子表格刷新并重新计算?

时间:2014-04-20 01:11:25

标签: google-sheets

为此目的编写了一些代码,但是新的附加组件不再适用。

提前致谢, 易多

9 个答案:

答案 0 :(得分:31)

档案 - >电子表格设置 - > (标签)计算 - >重新计算(3个选项)
- 改变时 - 变化和每分钟
- 变化和每小时
这会影响NOW,TODAY,RAND和RANDBETWEEN的更新频率。

<强>但.. ..它只更新,如果函数参数(它们的范围,单元格)受到影响。

来自我的例子
我使用谷歌电子表格来查找一个人的年龄。我的生日日期格式为(dd.mm.yyyy) - &gt;这是瑞士的使用格式。

=ARRAYFORMULA(IF(ISTEXT(K4:K), IF(TODAY() - DATE(YEAR(TODAY()), MONTH(REGEXREPLACE(K4:K, "[.]", "/")), DAY(REGEXREPLACE(K4:K, "[.]", "/"))) > 0, YEAR(TODAY()) - YEAR(REGEXREPLACE(K4:K, "[.]", "/")) + 1, YEAR(TODAY()) - YEAR(REGEXREPLACE(K4:K, "[.]", "/"))), IF(LEN(K4:K) > 0, IF(TODAY() - DATE(YEAR(TODAY()), MONTH(K4:K), DAY(K4:K)) > 0, YEAR(TODAY()) - YEAR(K4:K) + 1, YEAR(TODAY()) - YEAR(K4:K)), "")))

我正在使用TODAY(),我进行了上述重新计算设置。 - &GT;但没有自动刷新。 :-(
如果我在函数查找范围内更改某个值,它只会更新。

所以我为此编写了一个Google脚本(工具 - &gt;脚本编辑器......)。

function onOpen() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheetMaster = ss.getSheetByName("Master"); 
  var sortRange = sheetMaster.getRange(firstRow, firstColumn, lastRow, lastColumn);  

  sortRange.getCell(1, 2).setValue(sortRange.getCell(1, 2).getValue());
}

您需要为firstRowfirstColumnlastRowlastColumn

设置数字

当电子表格打开时,脚本会激活,再将一个单元格的内容写入同一个单元格。这足以触发TODAY()函数。

在Edward Moffett上查找有关该链接的更多信息。 Force google sheet formula to recalculate

最好的问候,
克里斯托弗

答案 1 :(得分:7)

对我有用的是在第一列之前插入一列,并立即将其删除。 基本上,进行更改会影响工作表中的所有单元格,从而触发重新计算。

答案 2 :(得分:3)

现有的答案都不适合我,但这种方法可以。

问题

我看到很多单元格都说 #REF!。这些是我使用“复制到 > 现有工作表”从另一个 Google 工作表文档复制的工作表中的单元格。如果我在任何单元格中按 Enter,它会正确重新计算,但我不想对数百万个单元格这样做。

我的回答

我运行了这个 recalcSheet() 脚本。每个单元格几乎需要 0.5 秒,这很慢,但比手动修复每个单元格要快。

function recalcSheet(){  
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet()
  var sheet = spreadsheet.getSheetByName("put_your_sheet_name_here");  // https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet#getsheetbynamename
  // var range = sheet.getSelection().getActiveRange();
  // var range = sheet.getRange('A6:D6');
  var range = sheet.getDataRange();  
  recalcRange(range, spreadsheet);
}

function recalcRange(range, spreadsheet){
  // following structure of https://stackoverflow.com/a/52123839/470749
  Logger.log('Range: ' + range.getA1Notation());
  var numRows = range.getNumRows();
  var numCols = range.getNumColumns();
  var startRow = range.getRow();
  var startCol = range.getColumn();
  Logger.log('row: ' + startRow);
  Logger.log('col: ' + startCol);
  Logger.log('numRows: ' + numRows);
  Logger.log('numCols: ' + numCols);

  for (var r = 1; r <= numRows; r+=1) {
    for (var c = 1; c <= numCols; c+=1) {
      var originalFormula = range.getCell(r, c).getFormula(); // https://developers.google.com/apps-script/reference/spreadsheet/range#getFormula()
      Logger.log(`r,c ${r}, ${c}; originalFormula: ${originalFormula}`);
      if(originalFormula){
        range.getCell(r, c).setFormula('');
        //SpreadsheetApp.flush(); // https://webapps.stackexchange.com/a/35970/27487
        range.getCell(r, c).setFormula(originalFormula);
      }
    }
  }
  spreadsheet.toast('Each cell in the range has been recalculated.', "Finished!"); // https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet#toast(String)
}

答案 3 :(得分:2)

旧问题……尽管如此,只需在工作表中的某个位置添加一个复选框即可。选中或取消选中它会刷新单元格公式。

答案 4 :(得分:1)

快速但手动更新

NOW()TODAY()RAND()RANDBETWEEN()

在任何空白单元格上按退格← Del ,立即触发根据NOW()TODAY(),{{ 1}}或RAND()(照常在整个电子表格的所有表格中)。

(如果手边没有空单元格,则可以删除一个已填充的单元格,然后使用 Ctrl + z 撤消该操作。)

INDIRECT()的

不幸的是,默认情况下,不会像这样更新INDIRECT()。

您可以通过将范围粘贴到自身来更新此类公式的单元格范围:

  1. 选择范围
  2. Ctrl + c
  3. Ctrl + v

答案 5 :(得分:0)

当问题出在IF条件的重新计算中时,我添加AND(ISDATE(NOW());condition),以使该单元格被迫根据以下条件重新计算 如前所述,在“电子表格设置”的“计算”选项卡中设置了什么。

之所以可行,是因为NOW是受“计算”设置影响的函数之一,并且ISDATE(NOW())始终返回TRUE

例如,在我的一张工作表中,我具有以下条件,用于检查是否已创建名称存储在C1中的工作表:

=IF(ISREF(INDIRECT(C$1&"!A1")); TRUE; FALSE)

在这种情况下,C1="February"是这样,所以我希望在创建具有该名称的工作表时条件变为TRUE,但这种情况不会发生。为了强制更新,我更改了“计算”设置并使用:

=IF(AND( ISDATE(NOW()) ; ISREF(INDIRECT(C$1&"!A1")) ); TRUE; FALSE)

答案 6 :(得分:0)

插入“复选框”。每次您选中或取消选中该框,表格都会重新计算。如果将复选框的文本大小设置为2,将颜色几乎设置为黑色,并将单元格阴影设置为黑色,则它将成为一个重新计算的按钮。

答案 7 :(得分:0)

我相信接受的答案有一些主要问题(正如我在评论中提到的),所以我提出了一个更好的方法。无论公式是否包含任何 NOW()TODAY()RAND()RANDBETWEEN() 函数,此方法都适用于我。事实上,它也适用于自定义函数。

需要注意的一点是,这种方法使用了 setFormulas() 函数,需要用户确认。因此,不是仅在电子表格打开时更新所有值,下面的代码将创建一个名为“刷新”的新菜单,并带有一个“刷新数据”按钮。

无论何时按下此按钮,都将通过重新粘贴原始公式(不仅仅是值)来刷新所需的数据范围。**

只需将此代码添加到电子表格中的工具 -> 脚本编辑器

function onOpen() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var menuEntries = [];
  menuEntries.push({name: "Refresh Data", functionName: "refreshData"});

  ss.addMenu("Refresh", menuEntries);
}

function refreshData() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheets()[0]; 
  var myRange = sheet.getRange(1, 1, sheet.getLastRow(), sheet.getLastColumn());  

  myRange.setFormulas(myRange.getFormulas());
}

请注意,如果您只想刷新电子表格的一部分,请更改 getRange() 函数内的值,如 relevant documentation 中所述。

答案 8 :(得分:-1)

我知道您正在寻找自动刷新;也许有些人可能对快速修复手动按钮感到满意(例如上面建议的复选框)。我实际上偶然发现了与该复选框类似的解决方案:选择要刷新的单元格,然后按CTRL和“ +”键。似乎可以在Office 365 v16中工作;希望它对有需要的人有用。