【问题标题】:How to Force New Google Spreadsheets to refresh and recalculate?如何强制新的 Google 电子表格刷新和重新计算?
【发布时间】:2014-04-20 01:11:25
【问题描述】:

为此目的编写了一些代码,但随着新的插件它们不再适用。

【问题讨论】:

标签: google-sheets


【解决方案1】:

文件 -> 电子表格设置 ->(选项卡)计算 -> 重新计算(3 个选项)

  • 更改时
  • 每分钟都在变化
  • 每小时更改一次
    这会影响 NOW、TODAY、RAND 和 RANDBETWEEN 的更新频率。

但是.. .. 仅当函数的参数(它们的范围、单元格)受此影响时,它才会更新。

我的例子
我使用谷歌电子表格找出一个人的年龄。我有他的出生日期格式 (dd.mm.yyyy) -> 这是瑞士使用的格式。

=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(),并进行了上述重新计算设置。 -> 但不会自动刷新。 :-(
仅当我在函数正在查找的范围内更改某些值时,它才会更新。

因此我为此编写了一个 Google 脚本(工具 -> 脚本编辑器..)。

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() 函数。

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

【讨论】:

  • 这似乎是正确的答案,但即使我这样做,它也不会自动刷新。知道我在这里缺少什么吗?
  • 如果公式仅取决于自定义函数的结果,这将不起作用...如果有某种方法可以强制工作表一次性重新计算所有内容,那就太好了。
  • 我认为您可以将IF(ISTEXT(… 替换为IF(NOW()*ISTEXT(…,而不是使用脚本。 (这不会改变值,因为 NOW()* 的行为类似于 AND(TRUE;,因为隐式转换为布尔值。)
  • 这可能不起作用,原因如下:确保将工作表名称(此处为“Master”)替换为您自己的工作表名称;其次,getRange() 函数定义如下:getRange(row, column, numRows, numColumns) 所以不是 "lastRow, lastColumn" 它应该真正类似于 "numRows, numColumns"
  • 另外,小心使用setValues() - 它将使用原始输出值,并用这些值重写原始公式!!!请参阅我的答案以获得更好的方法。
【解决方案2】:

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

【讨论】:

【解决方案3】:

老问题......不过,只需在工作表的某处添加一个复选框即可。选中或取消选中它将刷新单元格公式。

【讨论】:

【解决方案4】:

快速,但手动


正在更新 NOW()TODAY()RAND()RANDBETWEEN() 公式

在任何空白单元格上按 Backspace ←Del 可立即触发重新计算公式,具体取决于 NOW()TODAY()RAND()RANDBETWEEN()(在整个电子表格的所有表格中,像往常一样)。

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

很遗憾,INDIRECT() 公式默认不会像这样更新。

更新INDIRECT() 公式

您可以通过将范围粘贴到自身上来更新INDIRECT() 公式的(范围)单元格:

  1. 选择单元格/范围
  2. Ctrl+C
  3. Ctrl+V

您可以在步骤 1 中使用 Ctrl+A 选择整个当前工作表。但对于大型工作表,其他 2 个操作可能需要几秒钟。 知道复制大范围的过程何时完成的技巧: 在复制您的范围之前复制一些单个单元格:丢失其虚线边框的单个单元格将是您的大副本完成的通知。

【讨论】:

    【解决方案5】:

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

    问题

    我看到很多单元格说#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)
    }
    

    【讨论】:

      【解决方案6】:

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

      【讨论】:

      【解决方案7】:

      我认为接受的答案存在一些重大问题(正如我在我的 cmets 中提到的),因此我提出了一个更好的方法。无论公式是否包含 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】:

        当问题出现在重新计算一个 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)
        

        【讨论】:

        • 自动更新,例如一个没有环绕 IF()=INDIRECT(C$1&amp;"!A1")=INDIRECT(T(NOW())&amp;C$1&amp;"!A1")(解释:T() 过滤文本类型数据;NOW() 是日期时间类型(这是一个数字类型),所以不是文本类型,所以是 T(NOW())返回一个空字符串 ("")。&amp; 连接该空字符串,保持结果不变(在处理字符串时)。)
        【解决方案9】:

        我有一个非常适合我的解决方法,我有一个大工作表,其中包含许多“IMPORTRANGE”和许多指向其他工作表的链接,所以每次有人更新工作表时,它都没有显示在其他任何地方,所以我有逐个选项卡,选择整个内容,删除并返回以更新它,但我只是将公式“=IF(TODAY()=TODAY()”放在我所有的公式之前(这很痛苦脖子),终于成功了,一切都是实时更新的。

        这花了我一些时间,但最终我得到了回报。

        【讨论】:

          【解决方案10】:

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

          【讨论】:

          • 但是这个问题是关于 Google Sheets,而不是 Office 365。CTRL + 会导致 Chrome 放大。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-11-02
          • 2021-01-23
          • 1970-01-01
          • 2011-10-15
          相关资源
          最近更新 更多