【问题标题】:How to overwrite cell function with Paste value only using Google Script如何仅使用 Google 脚本用粘贴值覆盖单元格函数
【发布时间】:2020-10-08 16:05:30
【问题描述】:

我有一个可以进行实时计算的数据库,但是在当天处理了添加到数据库的新数据后,我实际上只想在这些单元格上复制 + 粘贴值,以便公式的结果是固定的并且可以不再改变。

我当前使用的脚本是:

function myFunction() {
  var sh = SpreadsheetApp.getActiveSpreadsheet();
  var ss = sh.getActiveSheet();
  var r = ss.getRange(1,2,ss.getLastRow());
  var vals = r.getValues();
  for(var i =0;i<vals.length;i++){
      ss.getRange(i+1,2).setValue(ss.getRange(i+1,2).getValue());
  }
}

但是,在数据集下方的 B 列中,所有单元格都以 IF(B2092="","",etc) 开头。在空的单元格上,我仍然需要公式保持不变。我只想将脚本应用于其中包含数据的单元格。

有人可以帮忙吗?谢谢

【问题讨论】:

    标签: google-apps-script google-sheets


    【解决方案1】:

    试试这个:

    function myFunction() {
        var sh = SpreadsheetApp.getActive();
        var ss = sh.getActiveSheet();
        var rg = ss.getRange(1,2,ss.getLastRow());
    
        var vals     = rg.getValues();   // get values
        var formulas = rg.getFormulas(); // get formulas
    
        // merge values & formulas
        var data = formulas.map((row,row_index) => 
                        row.map((cel, cel_index) => 
            { return (cel) ? cel : vals[row_index][cel_index] }));    
    
        rg.setFormulas(data);            // output
    }
    

    修正版:

    function copy_values_and_formulas() {
        var sh = SpreadsheetApp.getActive();
        var ss = sh.getActiveSheet();
        var rg = ss.getRange(1,2,ss.getLastRow());
        
        var vals     = rg.getValues();   // get values
        var formulas = rg.getFormulas(); // get formulas
        
        // merge values & formulas
        var data = vals.map((row, row_index) => 
                    row.map((cel, cel_index) => 
            { return (cel == 0) ? formulas[row_index][cel_index] : cel }));
    
        rg.setFormulas(data);            // output
    }
    

    【讨论】:

    • 嗨。这似乎并没有改变工作表上的任何内容。您可以在此处查看我的示例表:docs.google.com/spreadsheets/d/… 左侧的列表是脚本运行前的显示方式。右边的表格是 >>> 之后的结果,任何有结果的单元格都将“修复”,而没有结果的单元格将继续显示公式。任何想法将不胜感激。
    • 它看起来有点像蛮力,因为您的链接显示“拒绝访问”(使用公共链接是有意义的)。我已经更改了var = data ... 的行,希望对您有所帮助。再试一次。
    • 完美!!谢谢你的帮助:)
    • 我已经让这段代码成功运行,但大多数时候我收到错误Exceeded maximum execution time。我想知道是否是因为数据集太大(10 列和超过 3200 行),所以我将 getRange 更改为 var rg = ss.getRange(3100,12,ss.getLastRow(),10); 以便脚本在第 3100 行的较小范围内工作,但是这并没有排序问题。你有什么想法吗?
    • 据我所知,你做得很好。 GAS 有限制:developers.google.com/apps-script/guides/services/quotas 看起来您已经超出了其中一些限制。是的,100 行 x 10 列看起来并不完全像大数据。但我会尝试处理 50 或 10 行,看看它是如何进行的。如果顺利的话,你可以做一个循环,并在几个步骤中处理所有数据。
    【解决方案2】:
    function myFunction() {
      var sh = SpreadsheetApp.getActive();
      var ss = sh.getActiveSheet();
      var rg = ss.getRange(1,2,ss.getLastRow());
      var vals = rg.getDisplayValues();
      for(var i=0;i<vals.length;i++){
        if(vals[i][1] && vals[i][1].length!=0) {
          ss.getRange(i+1,2).setValue(ss.getRange(i+1,2).getValue());
        }
      }
    }
    

    【讨论】:

    • 感谢您的回复。这仍然从数据集下方的单元格中删除了公式。我已经建立了一个示例数据集。 docs.google.com/spreadsheets/d/… 在此,我想修复 B1:B13 中的计算,但将公式保留在 B14:B 中。
    • 抱歉,我不关注本网站电子表格的链接。
    • 好的。根据书面解释,您有什么想法。对于单元格 B1,B 列中的所有单元格都具有公式 =IF(A1="","",SUM(1+1))。 A1:A13 包含数据,因此 B1:B13 的结果为 2。我想要实现的是将结果“2”固定为 B1:B13,但保留 B14:B 中的公式。有什么想法吗?
    猜你喜欢
    • 1970-01-01
    • 2012-07-26
    • 1970-01-01
    • 1970-01-01
    • 2022-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多