【问题标题】:How can I optimize my code using batch operations?如何使用批处理操作优化我的代码?
【发布时间】:2026-02-05 09:25:02
【问题描述】:

我想对电子表格中的一系列值执行基本乘法运算,然后将这些值除以列中的一系列值,请注意我的范围是 8 列长,而我的除法范围是一列长。

我有这个代码:

function multiply() {
  var doc = SpreadsheetApp.openById(SCRIPT_PROP.getProperty("1iXQxyL3URe1X1FgbZ76mEFAxLnxegyDzXOMF6WQ5Yqs"));
  var sheet = doc.getSheetByName("json");
  var sheet2 = doc.getSheetByName("tabla de frecuencias");
  var sheet3 = doc.getSheetByName("Template");

  var range = sheet2.getDataRange();
  var numRows = range.getNumRows();
  var numCols = range.getNumColumns()-1; //This will get the division values which are located in the last column
  var targ =  sheet2.getLastColumn();

  for (var i = 2; i <= numRows; i++) {
    for (var j = 2; j <= numCols; j++) {
      var A = range.getCell(i,j).getValue();
      var value = A;
      for (var v = 1; v <= numRows; v++) {

        var T = range.getCell(v,targ).getValue();

        range.getCell(i,j).setValue(value*100/T);
      }
    }         
  }
}

它非常慢,它从工作表中读取和写入每个单元格,其中我有准备乘以 100 并除以位于单列中的值的数值,该值对于每一行都是不同的。

我的脚本完成工作极其缓慢,批处理操作看起来很有希望,如果这不是最佳解决方案,我将接受任何其他替代解决方案,无论问题标题如何。

【问题讨论】:

    标签: google-apps-script google-sheets


    【解决方案1】:

    我想这就是你要找的东西。

    function multiply() 
    {
      var ss=SpreadsheetApp.getActive();
      var sh=ss.getSheetByName("Sheet60");
      var rg=sh.getDataRange();
      var dataA=rg.getValues();
      for(var i=1;i<dataA.length;i++) 
      {
        for(var j=1;j<dataA[0].length-1;j++) 
        {
          var value=dataA[i][j];
          for (var v=1;v<dataA.length;v++) 
          {
            var T=dataA[v][dataA[0].length-1];//the value in the last column on this row
            Logger.log('v=%s dataA[%s][%s]=%s',v,i,j,dataA[i][j]);
            dataA[i][j]=value * 100 / T;//This seems wrong because it puts a different value into dataA[i][j] which doesn't change inside this inner loop and so only the last value remains in dataA[i][j]
          }
        }         
      }
      rg.setValues(dataA);
    }
    

    尽量少用getValue,用一个getValues代替,获取二维数组中的所有值。然后在循环结束时一次性设置所有值。

    好的,又做了一个更改。得到更合理的结果。

    我开始认为您可能根本不想要 v 循环。看看这个,看看 Logger。我们只写一次数据。

    function percentages() 
    {
      var ss=SpreadsheetApp.getActive();
      var sh=ss.getSheetByName("Sheet60");
      var rg=sh.getDataRange();
      var dataA=rg.getValues();
      for(var i=1;i<dataA.length;i++) 
      {
        for(var j=1;j<dataA[0].length-1;j++) 
        {
          var value=dataA[i][j];
          var T=dataA[i][dataA[0].length-1];
          dataA[i][j]=value * 100 / T;
          Logger.log('dataA[%s][%s]=%s',i,j,dataA[i][j]);
        }         
      }
      rg.setValues(dataA);
    }
    

    这是此版本的输出。

    【讨论】:

    • 我试过你的脚本没有成功,你能评论每一行以帮助我理解吗?
    • 我刚刚对第二个循环进行了更改,因此它不会访问最后一列中的数据。
    • docs.google.com/spreadsheets/d/… 运行调整后的脚本时,我的电子表格没有任何反应。我想将这些值中的每一个乘以 100,然后除以总列中的数字
    • 您的脚本很棒,也许我还不清楚我想要它执行的操作:例如; B2 应乘以 100,然后除以示例中 H2 行上的值(以获取百分比)我不明白脚本正在执行什么计算,如果单元格中的值为 5,则结果应为例如 50。
    • 我做了另一个更改,现在我认为我更接近您的功能所做的工作。