简体   繁体   English

需要Google Apps脚本中的.makeCopy替代品以减少运行时间

[英]Need alternative to .makeCopy in Google Apps Script to decrease run time

I wrote a mail merge script that works great, but execution transcripts revealed that the .makeCopy task alone consumed 60% of the 6 minute run time. 我编写了一个很好的邮件合并脚本,但是执行记录显示,仅.makeCopy任务占用了6分钟运行时间的60%。 I am trying to re-write the script in a way that enables me to: 我试图以一种使我能够的方式重新编写脚本:

  • Open a document template 开启文件范本
  • populate the body of the template with spreadsheet data 用电子表格数据填充模板的主体
  • create a new document 创建一个新文件
  • copy the body of the populated template to the new document 将填充的模板的主体复制到新文档
  • save the new document as a PDF, attach it to an email and send it 将新文档另存为PDF,将其附加到电子邮件中并发送
  • delete the new document (I don't need to retain a copy) 删除新文档(我不需要保留副本)

At present, I am receiving a "TypeError" appendtoDoc is not a function, it is undefined." Error in line 72. 目前,我收到“ TypeError” appendtoDoc不是函数,它是未定义的。”第72行出现错误。

//Creates the custom menu in the spreadsheet "Run Script"
function onOpen() {
  var ui = SpreadsheetApp.getUi();
  ui.createMenu('Run Script')
      .addItem('Create Certs', 'menuItem1')
      .addToUi();
}
 //Nest the createDocument function within the menuItem1 function for execution
function menuItem1() {
   function createDocFromSheet() {
}
//Defines the start row and calculates the number of rows to be processed
  var sheet = SpreadsheetApp.getActiveSheet();
  var startRow = Browser.inputBox("Enter Start Row");
  var endRow = Browser.inputBox("Enter End Row");
  var numRows = (endRow - startRow) + 1;
  var dataRange = sheet.getRange(startRow, 1, numRows, 7);

//defines the variables and the email body
    var data = dataRange.getValues();
    for (var i = 0; i < data.length; ++i) {
    var row = data[i];
    var date = row[0];
    var nic = row[1];
    var course = row[2];
    var lastname = row[3];
    var firstname = row[4];
    var middle = row[5]
    var email = row[6];
    var docname = lastname+" "+nic+" PME Cert";
    var subjectTxt = "NWC "+ course +" Online PME Course Certificate";
    var fullBody = "PME COURSE COMPLETION CERTIFICATE" + "\n\n";
      fullBody += "Your " + course + " course completion certificate is attached." + "\n\n";
      fullBody += "Regards," + "\n\n";
      fullBody += "Professor Steve Pierce" + "\n";
      fullBody += "U.S. Naval War College "+ "\n";
      fullBody += "Online PME Program Team" + "\n\n";
      fullBody += "Learn more about NWC's Online PME Program at the link below:" + "\n";
      fullBody += "http://www.usnwc.edu/Academics/College-of-Distance-Education/PME-(1).aspx" + "\n";

// The old makeCopy code
//    var docId = DriveApp
//     .getFileById("1CjdoldpJmPskkqStpmBk3dRznFyURgY5mMsfVHfIGz4")
//     .makeCopy(docname).getId();

// Open the document template
//function createDocFromSheet(){
    var templateid = "1CjdoldpJmPskkqStpmBk3dRznFyURgY5mMsfVHfIGz4"
    var sheet = SpreadsheetApp.getActiveSpreadsheet();
    var data = dataRange.getValues();
    for (var i = 0; i < data.length; ++i) {
//create the new document
    var newDoc = DocumentApp.create(lastname+" "+nic+" PME Cert");
    var newDocId = newDoc.getId()
    var file = DriveApp.getFileById(newDocId)
// fill in the template with data
    for (var i in data){
      var row = data[i];
// opens the template and populates it with data from the sheet      
    var docid = DriveApp.getFileById(templateid).getId();
    var doc = DocumentApp.openById(docid);
    var body = doc.getActiveSection();
        body.replaceText('fname', firstname);
        body.replaceText('lname', lastname);
        body.replaceText('midname', middle);
        body.replaceText('course', course);
        body.replaceText('date', date);    
        doc.saveAndClose();
// appends data from the template to the new document
    var body = doc.getActiveSection();
    var newBody = newDoc.getActiveSection();
    appendToDoc(body, newBody);
    DocsList.getFileById(docid).setTrashed(true); //deletes the temp file
    }
}    

function appendToDoc(src, dst) {
    for (var i = 0; i < src.getNumChildren(); i++) {
    appendElementToDoc (dst, src.getChild(i));
    }
}    

function appendElementToDoc (doc, object) {
    var type = object.getType();
    var element = object.copy();
    if (type == DocumentApp.ElementType.PARAGRAPH) {
        if (element.asParagraph().getNumChildren() != 0 && element.asParagraph().getChild(0).getType() == DocumentApp.ElementType.INLINE_IMAGE) {
            var blob = element.asParagraph().getChild(0).asInlineImage().getBlob();
            doc.appendImage(blob);
      }
        else doc.appendParagraph(element.asParagraph());
    }

    MailApp.sendEmail(email, subjectTxt, fullBody, {attachments: Newdoc.getAs("application/pdf")});

    SpreadsheetApp.flush ();
    DriveApp.getFileById(docId).setTrashed(true);
}}}

I tried to re-create your basic code structure in a simpler format, trying to reproduce the error. 我试图以更简单的格式重新创建您的基本代码结构,以尝试重现该错误。

//Nest the createDocument function within the menuItem1 function for execution
function menuItem1() {
  function createDocFromSheet() {}

  for (var i = 0; i < 2; ++i) {
    //create the new document
    Logger.log("First Loop ran i = " + i);
    for (var i = 0; i < 2; ++i) {
      Logger.log('  Inner For loop: i = ' + i)
      appendToDoc();
    }
  }

  function appendToDoc() {
    Logger.log('appendToDoc ran!');
    for (var i = 0; i < 2; ++i) {
      Logger.log('appendToDoc For Loop i=' + i);
      appendElementToDoc();
    }
  }

  function appendElementToDoc() {
    Logger.log('appendElementToDoc ran!');
    Logger.log('');
  }
}

That code actually runs for me, and is able to access the appendToDoc function when I run the menuItem1() function. 该代码实际上为我运行,并且在我运行menuItem1()函数时能够访问appendToDoc函数。

It looks like you have a function function createDocFromSheet() {} with nothing in it. 看起来您有一个函数function createDocFromSheet() {}其中没有任何内容。 I don't understand that. 我不明白

I modified your script to do it differently: I took a template, did replaceText then created a pdf from the changed template and sent the email; 我修改了您的脚本,以进行不同的操作:我得到了一个模板,做了replaceText然后从更改后的模板创建了pdf并发送了电子邮件; then I did replaceText again, pdf, email etc etc. I could email 10 certs in 15 secs this way. 然后我又做了replaceText,pdf,电子邮件等。我可以在15秒钟内以这种方式通过电子邮件发送10个证书。 I didn't try a bigger number, and didn't check for errors. 我没有尝试更大的数目,也没有检查错误。

function creatCertPdfAndEmail() {   
 var sheet = SpreadsheetApp.openById('1fDe0ju0zkDr0cdA5hWBC4RsxZgFv6mIFn6W1WU-0S0w').getSheets()[0];  //I created a separate spreadsheet for testing purposes.
 var startRow =2;   
 var endRow =10 ;   
 var numRows = (endRow - startRow) + 1;   
 var dataRange = sheet.getRange(startRow, 1, numRows, 7);

 var counter =0;   
 var data = dataRange.getValues();   
 var templateid = "1DizlNa2ENpEMTUGhM78J0ozgh8A8Sc9fI1q1XmhvuLk"   
 var docid = DriveApp.getFileById(templateid).getId();

 var dateOld;   
 var courseOld;   
 var allTheNameOld;   
  for (var i = 0; i < data.length; ++i) {
        var doc = DocumentApp.openById(docid);
        var body = doc.getActiveSection();
        var row = data[i];
        var date = new Date().getTime() - new Date(row[0]).getTime(); //like this for testing to get a different value on each pdf
        var nic = row[1];
        var course = row[2];
        var lastname = row[3];
        var firstname = row[4];
        var middle = row[5]
        var email = row[6];
        //    var docname = lastname+" "+nic+" PME Cert"; //not used in this version
        var subjectTxt = "NWC "+ course +" Online PME Course Certificate";
        var fullBody = "PME COURSE COMPLETION CERTIFICATE" + "\n\n";
        fullBody += "Your " + course + " course completion certificate is attached." + "\n\n";
        fullBody += "Regards," + "\n\n";
        fullBody += "Professor Steve Pierce" + "\n";
        fullBody += "U.S. Naval War College "+ "\n";
        fullBody += "Online PME Program Team" + "\n\n";
        fullBody += "Learn more about NWC's Online PME Program at the link below:" + "\n";
        fullBody += "http://www.usnwc.edu/Academics/College-of-Distance-Education/PME-(1).aspx"
    + "\n";

        var row = data[i];
        var allTheName = firstname+' '+middle+' '+lastname
        if(counter ==0){
          body.replaceText('allTheName',allTheName);  // body.replaceText('Congratulations .*?\.',allTheName);
          body.replaceText('coursex', course);
          body.replaceText('datex', date);  
        }
        else {   
          body.replaceText(allTheNameOld,allTheName);
          body.replaceText(courseOld, course);
          body.replaceText(dateOld, date);  
        }

        dateOld = date;
        courseOld = course;
        allTheNameOld = allTheName

        counter ++

          doc.saveAndClose()
          var attachment = doc.getAs("application/pdf")

          MailApp.sendEmail(email, subjectTxt, fullBody, {attachments: attachment});   
 } 
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM