【问题标题】:How to refresh a sheet's cell value in Google Apps Script [duplicate]如何在 Google Apps 脚本中刷新工作表的单元格值 [重复]
【发布时间】:2015-07-27 17:09:23
【问题描述】:

我正在试验Blockspring,它提供了一个 Google 表格插件,例如,它可以运行一个从网络服务返回数据的函数,例如

=BLOCKSPRING("get-stock-current-stats", "ticker", "MSFT")

我想刷新单元格的数据,但在文档中没有看到“刷新”调用。

function onOpen() {
  createTimeDrivenTriggers()
}

function createTimeDrivenTriggers() {
  // Trigger every minute
  ScriptApp.newTrigger('myFunction')
      .timeBased()
      .everyMinutes(1)
      .create();

}

function myFunction() {
  Logger.log('I ran'); // can see this in the logs
  SpreadsheetApp.getActiveSheet().getRange('B4').getValue() //presumably returns a value to the script

}

【问题讨论】:

标签: google-apps-script google-sheets


【解决方案1】:

可以使用flush() 方法。另请参阅其他人提供的答案。

Documentation

SpreadsheetApp.flush();

引用自文档:

应用所有待处理的电子表格更改

如果电子表格没有更改,但您想强制重新计算公式,则需要进行更改,然后使用SpreadsheetApp.flush();

例如,您可以从单元格 A1 中获取值,然后将相同的值设置为单元格 A1。因此,不会丢失数据,因为您获取和设置的值相同。改变允许。 SpreadsheetApp.flush(); 重新计算所有公式。

文档中有一些关于优化的信息: Google Sheets Custom Function Optimization

【讨论】:

  • 感谢您的回答。举了一个例子作为下面的另一个答案,因为根据您提供的真棒线索,我不得不努力让它工作。
  • @bobjunga 在下面有一个更好的答案。我发现“刷新”方法禁用了“撤消”,我不会这样做!
【解决方案2】:

您可以不使用flush,而是通过在其预期参数末尾将它们传递给公式来告诉电子表格该函数依赖于哪些单元格。可以传递比函数使用的更多的参数。这样,如果输入不同,电子表格将假定函数返回的值可能不同,并且正常的更新过程会处理它。

如果您希望它在任何单元格更改时重新评估,只需传入一个包含所有单元格的范围即可。

例如:

=MyFunction("this", "that", A1:Z10000)

如果您花时间准确地传入函数在逻辑上依赖的单元格,则在不需要时不重新评估会更有效。

=MyFunction("this", "that", A10, C5, G6:H9 )

如果它并不真正依赖于任何单元格,但您想手动评估函数,按需创建一个单元格,当用户单击它时增加其隐藏值(参见按钮),然后将该单元格地址传递给函数.

=MyFunction("this", "that", A10 )
// make A10 change its value on a button click

【讨论】:

  • 这是一个令人难以置信的救生技巧。谢谢!
【解决方案3】:

刷新所有表格 它很慢,但很有效!

var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var rangeData = sheet.getDataRange();
var lastColumn = 38;
var lastRow = 17;
var searchRange = sheet.getRange(2,2, lastRow-1, lastColumn-1);

function forceRefresh() {
  //Loop through each column and each row in the sheet.
  for(i = 1; i < lastColumn; i++){
    for (j = 1; j < lastRow ; j++){
      var cell = searchRange.getCell(j,i);
      var formula = cell.getFormula();
      var tempFormula = formula.replace("=", "?");
      cell.setFormula(tempFormula);
      SpreadsheetApp.flush();
      cell.setFormula(formula);
    };
  };
};

forceRefresh(); //call

【讨论】:

    【解决方案4】:

    发布一个有用的 sn-p,以防您需要强制所有公式重新计算。这比此处发布的其他示例性能要好得多。

    function forceRefreshSheetFormulas(sheetName) {
      var activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
      var sheet = activeSpreadsheet.getSheetByName(sheetName);
      var range = sheet.getDataRange();
      var numCols = range.getNumColumns();
      var numRows = range.getNumRows();
      var rowOffset = range.getRow();
      var colOffset = range.getColumn();
    
      // Change formulas then change them back to refresh it
      var originalFormulas = range.getFormulas();
    
      //Loop through each column and each row in the sheet
      //`row` and `col` are relative to the range, not the sheet
      for (row = 0; row < numRows ; row++){
        for(col = 0; col < numCols; col++){
          if (originalFormulas[row][col] != "") {
            range.getCell(row+rowOffset, col+colOffset).setFormula("");
          }
        };
      };
      SpreadsheetApp.flush();
      for (row = 0; row < numRows ; row++){
        for(col = 0; col < numCols; col++){
          if (originalFormulas[row][col] != "") {
            range.getCell(row+rowOffset, col+colOffset).setFormula(originalFormulas[row][col]);
          }
        };
      };
      SpreadsheetApp.flush();
    };
    

    有一些技巧在起作用: - 将单元格的公式设置为"" 会清除它,所以我们避免了这种情况。 - 我们需要更改公式,刷新,然后将其更改回来并再次刷新。

    【讨论】:

    • 将单元格的公式设置为 "" 会清除它,如果由于某种原因在重新分配原始公式之前运行此脚本被中断,所有公式都将消失,我们将以灾难告终!跨度>
    【解决方案5】:

    示例基于上述接受的答案。添加,因为我不得不努力解释如何使用它来自动评估任何工作表更改的单元格公式。此代码运行缓慢,但我将其作为一般示例分享,希望对您有所帮助,YMMV。

    /* Force evaluation of custom formula on sheet change.
    * Temporarily changes formula text.
    * @param sheetName: String Needs to be present in the formula
    * @param row: Int
    * @param col: Int 
    */
    
    function forceEval(sheetName, row, col){
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var sheet = ss.getSheetByName(sheetName);
      var orig = sheet.getRange(row,col).getFormula(); 
      var temp = orig.replace("=", "?");
      sheet.getRange(row,col).setFormula(temp); 
      SpreadsheetApp.flush();
      sheet.getRange(row,col).setFormula(orig); 
    }
    

    现在使用 onEdit 触发器调用它

    function onEdit(e){
        forceEval("MySheet", 1, 1)
    }
    

    这将暂时重写单元格 1,1 中的公式,将“=”替换为“?”,然后使用 flush(),然后将其改回,强制在工作表中进行任何编辑后进行评估。

    单元格中的自定义公式可能如下所示:=SUMSTATUS("MySheet","InProgress")

    应该适用于: =BLOCKSPRING("get-stock-current-stats", "ticker", "MSFT")

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-24
      • 2023-01-03
      • 1970-01-01
      相关资源
      最近更新 更多