方法Range.getValue被脚本大量使用

时间:2018-10-12 17:46:31

标签: google-apps-script google-sheets

我有一个可以正常工作的脚本,但是需要很长时间才能完成。我在各种不同的工作簿和工作表上都有许多有效的复制粘贴。我对脚本的了解是有限的,我很高兴能完全使它起作用。尽管大约15分钟,但运行时间确实很垃圾,我什至没有设置它来完成所有必需的循环。灯泡建议说:

  

方法Range.getValue被脚本大量使用。崩溃
      文件:学生反思副本行:17
      该脚本使用一种被认为很昂贵的方法。每次调用都会生成对远程服务器的耗时调用。那   可能会对脚本的执行时间产生重大影响,   特别是在大数据上。如果脚本的性能是问题,   您应该考虑使用其他方法,例如Range.getValues()。

但是我真的不知道该怎么办。我无法再次启动该项目,并且总是会在不同的工作表之间粘贴复制内容以进行设置。任何帮助将不胜感激。 这是我的工作代码:

function myFunction() {
  var spreadsheet = SpreadsheetApp.getActive();
  var studentID = spreadsheet.getSheetByName('Sheet11');
  var sourceSheet = spreadsheet.getSheetByName('Sheet6');
  var createLink = spreadsheet.getSheetByName('Sheet14');

  var i ,j, k;

  for( var k = 1; k< 3; k++) {

    // copy studentID
    studentID.getRange(k, 2).copyTo(createLink.getRange(4, 4 ,{contentsOnly: true}));

    for( var i = 1; i< 21; i++) {
      //copy students subject
      var subjectName = sourceSheet.getRange(i+1,7*k-5).getValue();
      if (subjectName =="") {
        break;
      }else {
        createLink.getRange(4, 6).setValue(subjectName)
        //copy row number of reflection
        for (var j = 1; j<31; j++){
          var rownumber = j+5;
          createLink.getRange(4, 8).setValue(rownumber);
          SpreadsheetApp.flush(); 
          //copy link of student reflection into teacher marksheet
          var markSheetID = sourceSheet.getRange(i+1, 7*k-3).getValue();
          var groupNumber = sourceSheet.getRange(i+1,7*k-2).getValue();
          var MarkSheet = SpreadsheetApp.openById(markSheetID).getSheets()[groupNumber-1];
          var linkvalue = createLink.getRange(4, 10).getValue();
          MarkSheet.getRange(2+k, 6*j).setValue(linkvalue);}
      }
    }
  }
}

我知道这不好,但是我以前从未做过这些事情。关于如何加快此过程的任何建议?

更新: 请找到随附的工作簿。将学生信息粘贴到工作表14中,以创建导入范围链接,然后将其粘贴回老师的标记书中。对每个科目然后对每个学生重复此过程。我不知道如何使用数组以及如何使用这些信息存储而不是每个单独的值进行编码。 copy of workbook

2 个答案:

答案 0 :(得分:1)

系统消息很可能是由于在嵌套的for循环内使用setValue(存在三个for循环)以及在嵌套的for循环内使用SpreasheetApp.flush()导致阻止Apps脚本引擎使用它而导致的内置的写优化算法。

尝试避免在for循环中使用setValue()。为此,您可以使用JavaScript数组保存值,然后使用setValues()一次传递多个值,而不是一个一个地传递。

答案 1 :(得分:0)

如果没有能力用真实数据运行程序,很难在真空中做到这一点。

没有太多改变。但是,如果您可以使用SpreadsheetApp.flush那就很好了。除此之外,我只能用一个getValues()替换几个getValue()。我只是注释掉我替换的行。

  function myFunction() {
  var spreadsheet = SpreadsheetApp.getActive();
  var studentID = spreadsheet.getSheetByName('Sheet11');
  var sourceSheet = spreadsheet.getSheetByName('Sheet6');
  var createLink = spreadsheet.getSheetByName('Sheet14');
  for( var k = 1; k< 3; k++) {
    // copy studentID
    studentID.getRange(k, 2).copyTo(createLink.getRange(4, 4 ,{contentsOnly: true}));
    for( var i = 1; i< 21; i++) {
      //copy students subject
      var subjectName = sourceSheet.getRange(i+1,7*k-5).getValue();
      if (subjectName =="") {
        break;
      }else {
        createLink.getRange(4, 6).setValue(subjectName)
        //copy row number of reflection
        for (var j = 1; j<31; j++){
          var rownumber = j+5;
          createLink.getRange(4, 8).setValue(rownumber);
          //SpreadsheetApp.flush(); 
          //copy link of student reflection into teacher marksheet
          var mgvA=sourceSheet.getRange(i+1, 7*k-3, 1, 2).getValues();
          //var markSheetID = sourceSheet.getRange(i+1, 7*k-3).getValue();
          //var groupNumber = sourceSheet.getRange(i+1,7*k-2).getValue();
          var MarkSheet=SpreadsheetApp.openById(mgvA[0][0]).getSheets()[mgvA[0][1]-1];
          //var MarkSheet = SpreadsheetApp.openById(markSheetID).getSheets()[groupNumber-1];
          var linkvalue = createLink.getRange(4, 10).getValue();
          MarkSheet.getRange(2+k, 6*j).setValue(linkvalue);}
      }
    }
  }
}