Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Google脚本/将执行时间减少到exec时间限制以下_Javascript_Google Apps Script_Google Sheets - Fatal编程技术网

Javascript Google脚本/将执行时间减少到exec时间限制以下

Javascript Google脚本/将执行时间减少到exec时间限制以下,javascript,google-apps-script,google-sheets,Javascript,Google Apps Script,Google Sheets,编辑2: 我决定尝试批处理在所有电子邮件被激发后运行的复制粘贴操作。在之前发布的代码中,在每个循环的最后一行中,我将每个采购订单电子邮件表中的项目复制并粘贴到另一个AsignRec。现在,我想做的是将每个循环中的邮件表中的项目存储到一个Javascript数组中,并在最后粘贴到AsignRec中,只粘贴一次 然而,我还是做得不对。我被最后的粘贴/设置值卡住了。我相信数组的格式是正确的,因为它的长度是49,这是要发送给供应商的唯一SKU的数量。尽管如此,在setValues[OCitems]第18

编辑2:

我决定尝试批处理在所有电子邮件被激发后运行的复制粘贴操作。在之前发布的代码中,在每个循环的最后一行中,我将每个采购订单电子邮件表中的项目复制并粘贴到另一个AsignRec。现在,我想做的是将每个循环中的邮件表中的项目存储到一个Javascript数组中,并在最后粘贴到AsignRec中,只粘贴一次

然而,我还是做得不对。我被最后的粘贴/设置值卡住了。我相信数组的格式是正确的,因为它的长度是49,这是要发送给供应商的唯一SKU的数量。尽管如此,在setValues[OCitems]第185行,我得到了错误的范围高度,是1,但应该是49行185,文件TestArrayMultiple4

我假设这意味着目标/输出范围与称为OCitems的数组/输入大小不同。我不明白为什么,因为我使用OCitems.length定义了输出范围的长度。我错过了一些东西,不知道是什么

这是代码的重要部分,下面是完整的代码。与之前相同的GDocs链接,脚本文件TestArrayMultiple4,第160-185行。

=========================

EDIT1:致力于使用多个单元格的getValue提高性能,而不是多次执行单个getValue。不幸的是,这并没有以稳定或明显的方式减少执行时间,有时它在6分钟之前完成,有时则没有

下面的过帐代码您可以在下面共享的新工作表中的脚本文件TestArrayMultiple2中访问它:

通过使用Execution transcript,我发现尽管之前花费很长时间的getValue行的执行时间基本上已经减少到了零,但其他代码行现在花费了更多的时间,并消除了批处理其他getValue所获得的收益

特定单元格上仍然有4-5个单独的getValue,比以前少得多,但我不明白为什么它们会花费这么长时间。因此,即使我删除了剩下的单个getValue,如果只剩下一个,它也需要更长的时间

在我看来,它与缓存有关,我确信我不完全理解这个概念,原因如下: 1它始终是循环中花费时间最长的第一个getValue。 2我试图走另一条路,通过更改复制/粘贴操作的代码,该操作发生在所有电子邮件发送到TestArrayMultiple2脚本文件的第150行之后。我基本上是尝试创建一个数组,在每个循环append/push方法中提供更多的数据,但不会在每个循环中粘贴—其想法是在完成循环后,在最后粘贴所有数据。我仍然没有弄清楚第二个脚本文件是最后一个,TestArrayMultiple3,但是我可以看到电子邮件的发送速度要快得多

再次感谢您的帮助

> // version with 1 getDataRange array which stores for supplier ID, name, email, MaxTableRow for PO email, email subject all from Dashboard sheet

function TestArrayMultiple2() {

  var ss = SpreadsheetApp.getActiveSpreadsheet ();
  var sheet = ss.getSheetByName("Email"); 
  var sheet1 = ss.getSheetByName("Pedido email");
  var sheet2 = ss.getSheetByName("Dashboard");
  var sheet3 = ss.getSheetByName("AsignRec");
  var sheet4 = ss.getSheetByName("ListadoProductos");
  var sheet5 = ss.getSheetByName("Registro-Consolid");
  var sheet6 = ss.getSheetByName("Registro-Unico");

  var x = ss.getSheetByName("Dashboard").getRange("C4").getValue();
  Logger.log("x = " + x)

  var offsetV = 4; // number of rows of offset for email status to be inserted in Dashboard sheet 

  var OffSetColProv = 1; // column in Dashboard sheet with supplier name
  var OffsetColMaxPOrows = 3; // Number of unique SKUs or rows in PO. Replace MaxTableRow formula in Email Sheet
  var OffSetColPzas = 4; // column in Dashboard sheet with number of items in supplier purchase order. 
  var OffSetColEmail = 5; // column in Dashboard sheet with supplier email
  var OffSetColCC = 13; // column in Dashboard sheet with supplier email CC
  var OffSetColSubject = 14; // column in Dashboard sheet with supplier email Subject

  var colStatus = 11; // column in Dashboard sheet where send status of email inserted -----> LEAVE AS IS FOR NOW, not an offset, is fixed, col. K = 11
  var OffsetEmailRows = 8 // number of rows in Email sheet before the items in PO are shown

  var ProvNumEmail = sheet.getRange(1,2); // Supplier number in email sheet used to refresh products in purchase order email via FILTER formula

  var StatusRange = sheet2.getRange("K5:K100");
  Logger.log("StatusRange = " + StatusRange)

  var currentTime =  new Date();
  var timestamp = Utilities.formatDate(currentTime,'GMT-0600','dd/MM/yyyy HH:mm:ss');
  Logger.log("timestamp = " + timestamp);

  var ProvArray = sheet2.getRange("E5:S100");
  var DashValues = ProvArray.getValues();

  i = 0;

  do {


  var y = DashValues[i][0];
  Logger.log("y = " + y)

  ProvNumEmail.setValue(y);   // set value of next supplier in Email sheet to load next purchase order products


    // emails var here in order to update email value in IF email = ERROR condition and skip to else

  var Prov = DashValues[i][OffSetColProv];
  Logger.log("Prov = " + Prov);

  var EmailSubject = DashValues[i][OffSetColSubject];
  Logger.log("EmailSubject = " + EmailSubject)

  var MaxTableRow = DashValues[i][OffsetColMaxPOrows] + OffsetEmailRows;
  Logger.log("MaxTableRow = " + MaxTableRow)

  var EmailTo = DashValues[i][OffSetColEmail];
  Logger.log("EmailTo = " + EmailTo)

  var EmailCC = DashValues[i][OffSetColCC];
  Logger.log("EmailCC = " + EmailCC)

  var Piezas = DashValues[i][OffSetColPzas];
  Logger.log("Piezas = " + Piezas)

  SpreadsheetApp.flush();

  var name = "Petsy Compras - Juan Carlos León";
  var ReplyToEmail = "compras@petsy.mx";
  var email = EmailTo;
  var subject = EmailSubject;
  var name = name;
  var replyTo = ReplyToEmail;
  var Emailcc = EmailCC;
  var schedRange = sheet.getRange("B7:J"+MaxTableRow);
  var body = '<div>';            
    body += "Estimados," +'<br>' + '<br>';
    body += "Envío la orden de compra, por un total de " + '<b>' + Piezas + " piezas." + '</b>' +'<br>' + '<br>';
    body += "Favor de confirmar las existencias lo más rápidamente posible, dentro del mismo correo y"+ '<b><a style="color:#FF0000">'+ " enviar factura a: "+ '</a></b>' + "facturasproveedores@petsy.mx." +'<br>' + '<br>';
    body += "Al dar " +'<b><a style="color:#FF0000"> '+ "RESPONDER A TODOS" + '</a></b>' +" la tabla con los productos pedidos se hace editable: favor de marcar por cada item si será faltante." +'<br>' + '<br>';
    body += "Cualquier duda avísenme por favor." +'<br>' + '<br>';
    body += "Un saludo" +'<br>' + '<br>';
    body += '<b>'     + "Juan Carlos León" + '<b>' + '<br>';
    body += "Petsy Compras"+'<br>';
    body += "Mapa aquí: "+'<br>';
    body += "Fijo directo 1: (55) 68 12 07 97 / Fijo directo 2: (55) 68 12 07 99 / Cel y Whatsapp: 55 32 23 57 17"+'<br>' + '<br>';
    body += "" +'<br>' + '<br>';
    body += getHtmlTable(schedRange);
    body += '</div>';


  // variables for error email

  var emailERR = 'oscialom@petsy.mx'
  var subjectERR = 'ERROR ENVIO OC' + ' // ' + Prov + ' ' + timestamp


  if(email == 'ERROR' || MaxTableRow == 0) // skip condition to go begin loop with y+1

{

// if above skip condition is true, y+1 to move to next purchase order

  Logger.log("y = " + y);
  Logger.log("IF");
  sheet2.getRange(y + offsetV,colStatus).setValue('NOT_SENT'); // set email send status next to supplier in Dashboard sheet
  {
     GmailApp.sendEmail(emailERR, subjectERR, "Requires HTML", 
                { 
                    'name':name, 
                    'replyTo':replyTo,
                    'htmlBody':'', 
                    'cc':''});
        }


  i++;

  Logger.log("new i IF =" + 1);
  continue

}
else
{

  // if skip condition is false, fire current supplier purchase order email email

  Logger.log("i = " + i);
  Logger.log("y = " + y);
  Logger.log("ELSE");

  GmailApp.sendEmail(email, subject, "Requires HTML", 
                { 
                    'name':name, 
                    'replyTo':replyTo,
                    'htmlBody':body, 
                    'cc':EmailCC});
        }        

sheet2.getRange(y + offsetV,colStatus).setValue('OK'); // set email send status next to supplier in Dashboard sheet



// START copy-paste Asign-Rec

var MaxTableRowASIGN = sheet3.getRange("A1").getValue();
Logger.log("MaxTableRowASIGN = " + MaxTableRowASIGN)


/// Get Range we want to change to creating Javascript array and paste at end only

  debugger; // stop debugger at this point !! REMOVE OR PLACE AT CORRECT LINE IF USING DEBUGGER

var OcNoHeader = sheet.getRange("B9:J" + MaxTableRow);
var ConsolAsignRec = sheet3.getRange("B3:K" + MaxTableRow);
var ProvOC = sheet.getRange("B2").getValue();
Logger.log("ProvOC = " + ProvOC)

var MaxRowB = sheet3.getRange("C1").getValue() + 1;
Logger.log("MaxRowB = " + MaxRowB);

var NextRowB = MaxRowB + 1;
Logger.log("NextRowB = " + NextRowB);

OcNoHeader.copyTo(sheet3.getRange(MaxTableRowASIGN + 1,3),{contentsOnly:true});
var NumRowsProv = OcNoHeader.getNumRows();

var ProvOCcolumn = sheet3.getRange(MaxRowB, 2, NumRowsProv)
Logger.log("ProvOCcolumn = " + ProvOCcolumn);

ProvOCcolumn.setValue(ProvOC);

// END copy-paste Asign-Rec

i++; // after firing email, y+1 to go to next supplier
Logger.log("i++ IF =" + 1);



Logger.log("new i ELSE =" + 1)



} // only do while x = max number of suppliers reached
  while (y<x);  

  // set y = 1 to reset value again after finishing loop 

  sheet.getRange(1,2).setValue(1); // reset ProvNumber = 1 to start again next time script is fired.

  var EmailsSent = sheet2.getRange("C10").getValue(); // set values
  Logger.log("EmailsSent = " + EmailsSent)

  var EmailErrors = sheet2.getRange("C11").getValue();
  Logger.log("EmailErrors = " + EmailErrors)

  var MaxTableRowEND = sheet2.getRange("C9").getValue();
  var schedRange = sheet2.getRange("E4:K" + MaxTableRowEND);
  var emailEND = "oscialom@petsy.mx";
  var subjectEND = 'OCs Inbound enviadas' + ' ' + timestamp + " (errores " +  EmailErrors + " / enviados " + EmailsSent + ")";
  var EmailCCEND = "";
  var bodyEND = getHtmlTable(schedRange);

   GmailApp.sendEmail(emailEND, subjectEND, "Requires HTML", 
                { 
                    'name':name, 
                    'replyTo':replyTo,
                    'htmlBody':bodyEND, 
                    'cc':EmailCCEND});

StatusRange.clearContent();


/// START RecordTimestamp code

  var Avals = sheet4.getRange("A1:A").getValues();
  var lastrow1 = Avals.filter(String).length;
  Logger.log('lastrow1 =' + lastrow1)

  var Avals2 = sheet5.getRange("A1:A").getValues();
  var lastrow2 = Avals2.filter(String).length;
  Logger.log('lastrow2 =' + lastrow2)

    sheet4.getRange("B2:B" + lastrow1).copyTo(sheet5.getRange(lastrow2 + 1, 1)) // copy order-items to Registro sheet, after last filled row

    sheet4.getRange("K2:K" + lastrow1).copyTo(sheet5.getRange(lastrow2 + 1, 2)) // copy Prov1 to Registro sheet, after last filled row


  var Avals3 = sheet5.getRange("C1:C").getValues();
  var lastrow2c = Avals3.filter(String).length;
  Logger.log('lastrow2c =' + lastrow2c);


  if(lastrow2 == 1)
  { sheet5.getRange(lastrow2c + 1, 3, lastrow1 - 1).setValue(timestamp)
    Logger.log('IF')

    }

    else
    {
    sheet5.getRange(lastrow2c + 1, 3, lastrow1 - 1).setValue(timestamp)
    Logger.log('ELSE')
    }

var MaxTableRowEMAIL = sheet6.getRange("G5").getValue()

var subject = "Items pedidos en OC automatizada " + timestamp
var email = "oscialom@petsy.mx";
var EmailCC = "";
var EmailBCC;
var name = "Petsy Compras";
var ReplyToEmail = "compras@petsy.mx"
var schedRange = sheet6.getRange("A1:C" + MaxTableRowEMAIL);
var body = getHtmlTable(schedRange);  


{
     GmailApp.sendEmail(email, subject, "Requires HTML", 
                { 
                    'name':name, 
                    'replyTo':ReplyToEmail,
                    'htmlBody':body, 
                    'cc':''});
        }

/// END RecordTimestamp code


Logger.log("MaxTableRowASIGN " + MaxTableRowASIGN);

var endtime = new Date();
Logger.log("timestamp end " + timestamp);
Logger.log("endtime " + Utilities.formatDate(endtime,'GMT-0600','dd/MM/yyyy HH:mm:ss'));

var scripttime = (endtime - currentTime);
Logger.log("scripttime original" + scripttime);

// strip the ms
scripttime /= 1000;
Logger.log("scripttime / 1000" + scripttime);

// get seconds (Original had 'round' which incorrectly counts 0:28, 0:29, 1:30 ... 1:59, 1:0)
var seconds = Math.round(scripttime % 60);
Logger.log("scripttime % 60" + scripttime);

// remove seconds from the date
scripttime = Math.floor(scripttime / 60);
Logger.log("scripttime / 60" + scripttime);

// Browser.msgBox("Script completado en " + seconds + " segundos",Browser.Buttons.OK_CANCEL); // removed MsgBox to measure real execution time
Logger.log("seconds " + seconds)

}  
=====================

原职


我编写了一个谷歌脚本,将采购订单流程自动化给几个供应商。该流程从sheet ListaProductos获取产品列表,将产品信息格式化为电子邮件格式的sheet email,发送电子邮件,并将其复制/粘贴到同一电子表格的其他表格中。但是,我总是在脚本的75%左右运行执行时间。我对此相当陌生,一直在阅读,但坦率地说,我不知道下一步该做什么。

我在这部分代码中看到了问题:

do { 
  // read info from the sheet
  range.getValue();
  // more code here...

} // only do while x = max number of suppliers reached
  while (y<x)
然后使用数据作为进一步计算的来源

请参见此处的更多信息:


谢谢,我读到我应该getDataRange而不是每个单独的getValue,但我不明白的是如何为数据范围内的每个值分配一个变量名。因为在很多情况下,在获取数据后,这些都是电子邮件或表的最大行值,我需要在一个操作中单独使用每个var,例如sendmail或copyTo。我环顾了四周,但没有找到关于如何执行getDataRange,然后为该范围内的每个数据值分配一个var的答案。你能指出一些这方面的资源吗?你可以从这里开始:嗨,Max,非常感谢你提供的资源。我使用getDataRange在Javascript中存储值,并减少对工作表的调用。然而,结果却很奇怪:有时它至少在220秒130秒的时间内完成,有时仍然会达到执行极限。将当前代码作为编辑添加到原始帖子,
do { 
  // read info from the sheet
  range.getValue();
  // more code here...

} // only do while x = max number of suppliers reached
  while (y<x)
var data = sheet.getDataRange().getValuses();