Google表单应用脚本超时和基于时间的触发器未运行

时间:2017-11-21 21:07:07

标签: javascript jquery google-apps-script google-sheets

以下是我已经工作了一段时间的函数的所有代码。基本上我正在尝试创建一个类分析包(我是一名教师)并打印一个google工作表作为PDF然后更改下拉(有效地更改页面和数据),然后再次打印,直到所有类代码在下拉已经完成。该功能非常有效但我遇到的问题是运行时间超过6分钟,因为要创建大约150个包。我已经查看了触发器并创建了一个基于时间的触发器,它应该在超时后几分钟开始。它似乎成功创建了触发器,但触发器实际上从未运行过。这是正确的方法吗?如果是这样,任何人都能发现它为什么不起作用?任何反馈都会令人惊讶,因为这让我疯狂!

function CreateClassPacks() {
  SpreadsheetApp.getUi() // Or DocumentApp or FormApp

  var startTime= (new Date()).getTime();
  var REASONABLE_TIME_TO_WAIT = 100000
  var MAX_RUNNING_TIME = 340000

  // Getting the date and putting it into the format we want
  var d= new Date();
  var dateStamp = d.getDate()+"/"+d.getMonth()+"/"+d.getYear();

  // Getting a token which will give me the authorisation I need
  var request = {
    "method": "GET",
    "headers":{"Authorization": "Bearer "+ScriptApp.getOAuthToken()},    
    "muteHttpExceptions": true
  };

  // This is the key for the spreadsheet I am working on and then it gets fetched
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var getKeys = ss.getSheetByName("Settings");
  var mainSSKey= getKeys.getRange("B1").getValue();
  // Key for the folder we will save the documents into
  var folderCPKey = getKeys.getRange("B2").getValue();
  var foldersave=DriveApp.getFolderById(folderCPKey);
  var fetch='https://docs.google.com/spreadsheets/d/'+mainSSKey+'/export?format=pdf&size=A4&portrait=false'

  // This section gets all of the class codes from whichever sheet we choose.
  // The first variable will need changing to whichever number sheet holds the codes.
  var classCodeSheetNum = 0
  var classCodeSheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[classCodeSheetNum]
  var maxRowNum = classCodeSheet.getLastRow()-1;
  // This variable must contain the correct column for the class codes
  var dataRange = classCodeSheet.getRange(1, 1, maxRowNum, 1);
  var data = dataRange.getValues();
  Logger.log(data)

  // This must be the sheet number for the class analysis packs
  var sheetNum = 4
  var newTrig = false

  // This will loop through my data variable which contains all the class codes
  for (var r=0; r<(data.length)-1; r++) { 
    for (i in data[0]) {

      var scriptProperties = PropertiesService.getScriptProperties();
      var startRow= scriptProperties.getProperty('start_row');
      var currTime = (new Date()).getTime();
      if(currTime - startTime >= MAX_RUNNING_TIME) {
        if (newTrig == false){
                  ScriptApp.newTrigger("CreateClassPacks")
                 .timeBased()
                 .at(new Date(currTime+REASONABLE_TIME_TO_WAIT))
                 .create();
                 newTrig = true
          break;
          }
        } else {
          // This sets the value of A2 on the analysis sheet to the value from the data structure
          SpreadsheetApp.getActiveSpreadsheet().getSheets()[sheetNum].getRange('O1').setValue(data[r][i]);

          var source = SpreadsheetApp.getActiveSpreadsheet();
          var sheet = source.getSheets()[sheetNum];

          // This gets the value from A2 and sorts out the name of the file
          var classCode = data[r][i]
          var name = classCode + " " + dateStamp + ".pdf";

          // This checks if the file already exists which will hopefully fix any timeout issues
          var file = DriveApp.getFilesByName(name)
          var chk = file.hasNext()
          if (chk === false) {

              // This hides all the sheets except for the one I am printing
              for(var w=0; w< sheetNum;w++)
              {
                sheet = source.getSheets()[w];
                sheet.hideSheet();
              }

              // This PDFs the page and has a timeout delaying the access requests so I don't get the annoying errors
              var pdf = UrlFetchApp.fetch(fetch, request);
              pdf = pdf.getBlob().setName(name);
              Utilities.sleep(4000);
              var file = foldersave.createFile(pdf)

              // This shows all the sheets that I previously hid
              for(var q=0; q< sheetNum;q++)
              {
                sheet = source.getSheets()[q];
                sheet.showSheet();
              }
          }
        }
      }
    }
  }

This shows that the trigger seems to be created even though it doesn't run the function again

1 个答案:

答案 0 :(得分:0)

也许我在这里遗漏了一些东西,但我认为你的代码可以更快。首先,创建const control = <FormArray>this.myForm.controls['questions']; const paramNames = Object.keys(control.controls[index]['controls'].params.controls); for (let i = 0; i < paramNames.length; i++) { control.controls[index]['controls'].params.removeControl(paramNames[i]); } ,然后在其他地方使用ss。全部创建var ss=SpreadsheetApp.getActive(),然后使用var allSheets=ss.getSheets()代替'ss.getSheets()[i]`。数据[0]中的i部分对我来说毫无意义。数据是一列宽。所有我都会在循环之前隐藏所有的纸张,然后如果必要的话显示我正在打印的纸张。隐藏和显示工作表需要时间。尽量不要这样做。我已经仔细阅读了一些代码,但我承认我没有任何上下文所以我怀疑它是否运行。但我试图尽可能多地从循环中取出,你也应该这样做。您可能会发现可以在规定的时间内运行它。

allSheets[i]