脚本&在试图在Google脚本中打印大型数组时的表格计时

发布于 2025-01-24 23:59:03 字数 5042 浏览 2 评论 0原文

背景

I具有一个函数,可以在Google脚本中使用urlfetchapp进行REST API调用。

但是响应仅一次返回2000年的记录。如果有更多记录,则在响应中,有一个称为 nextrecordsurl 的键,其中包含获取下一批记录所需的端点和参数。

我使用做...而循环遍历遍历,将记录推入预先指定的数组,进行下一个API调用。当它达到最后一批记录时,它存在于do-e-lile循环时,然后打印(不确定在这里这是正确的术语),整个是Google表。

代码

它看起来像这样的

function getCampaignAssociations() {
  clearPage('CampaignAssociations');
  var query = '?q=select+CampaignMember.FirstName,CampaignMember.LastName,CampaignMember.LeadId,CampaignMember.ContactId,CampaignMember.Name,CampaignMember.CampaignId,CampaignMember.SystemModstamp,CampaignMember.Email+from+CampaignMember+ORDER+BY+Email ASC,SystemModstamp+ASC';

  try {
    var arrCampAssociation = getInfoByQuery(query);

    if (arrCampAssociation.records.length < 1) {
      throw 'there are no records in this query';
    }

    var campaignAssoc = [];
    do {
      Logger.log(arrCampAssociation.nextRecordsUrl);

      for (var i in arrCampAssociation.records) {
        let data = arrCampAssociation.records[i];
        let createDate = Utilities.formatDate(new Date(data.SystemModstamp), "GMT", "dd-MM-YYYY");
        let a1 = "$A" + (parseInt(i) + 2);
        let nameFormula = '=IFERROR(INDEX(Campaigns,MATCH(' + a1 + ',Campaigns!$A$2:A,0),2),"")';
        let typeFormula = '=IFERROR(INDEX(Campaigns,MATCH(' + a1 + ',Campaigns!$A$2:A,0),3),"")';

        campaignAssoc.push([data.CampaignId, nameFormula, typeFormula, data.Email, data.FirstName, data.LastName, data.LeadId, data.ContactId, createDate]);
      }

      var arrCampAssociation = getQueryWithFullEndPoint(arrCampAssociation.nextRecordsUrl);
      
    } while (arrCampAssociation.nextRecordsUrl != null && arrCampAssociation.nextRecordsUrl != undefined);

      let endRow = campAssocSheet.getLastRow(), 
       endColumn = campAssocSheet.getLastColumn(), 
       nameRange = campAssocSheet.getRange(2, 1, endRow, endColumn),
       destRange = campAssocSheet.getRange(2, 1, campaignAssoc.length, campaignAssoc[0].length);
      destRange.setValues(campaignAssoc);
      sheet.setNamedRange('CampaignAssociation', nameRange);


    } catch (e) {
      Logger.log(e);
      Logger.log(arrCampAssociation);
      Logger.log(campaignAssoc);
      Logger.log(i);
    }
  }

:发行

一切都很好,直到将数组 ApaindAssoc 打印到Google Sheet上为止。

请参阅下面日志的屏幕截图。它包含下一个两者的端点。请注意,较早的日志和最后一个端点与日志的时间戳之间的时间戳。

在我看来,问题是在数据打印时,它存在问题。如果是这样,我是否超载了数组?总共有36400多个记录。

第二次尝试,

我尝试在每个循环中重置阵列,然后将阵列打印到Google Sheet。这只是每次尝试的2000个记录,我肯定会在1次做更多的行,但这无济于事。

这是该尝试的代码。

function getCampaignAssociations() {
  clearPage('CampaignAssociations');
  var query = '?q=select+CampaignMember.FirstName,CampaignMember.LastName,CampaignMember.LeadId,CampaignMember.ContactId,CampaignMember.Name,CampaignMember.CampaignId,CampaignMember.SystemModstamp,CampaignMember.Email+from+CampaignMember+ORDER+BY+Email ASC,SystemModstamp+ASC';

  try {
    var arrCampAssociation = getInfoByQuery(query);

    if (arrCampAssociation.records.length < 1) {
      throw 'there are no records in this query';
    }

    
    do {
      Logger.log(arrCampAssociation.nextRecordsUrl);
      var campaignAssoc = [];
      for (var i in arrCampAssociation.records) {
        let data = arrCampAssociation.records[i];
        let createDate = Utilities.formatDate(new Date(data.SystemModstamp), "GMT", "dd-MM-YYYY");
        let a1 = "$A" + (parseInt(i) + 2);
        let nameFormula = '=IFERROR(INDEX(Campaigns,MATCH(' + a1 + ',Campaigns!$A$2:A,0),2),"")';
        let typeFormula = '=IFERROR(INDEX(Campaigns,MATCH(' + a1 + ',Campaigns!$A$2:A,0),3),"")';

        campaignAssoc.push([data.CampaignId, nameFormula, typeFormula, data.Email, data.FirstName, data.LastName, data.LeadId, data.ContactId, createDate]);
        
      }
      let lastRow = campAssocSheet.getLastRow()+1;
      campAssocSheet.getRange(lastRow,1,campaignAssoc.length,campaignAssoc[0].length).setValues(campaignAssoc);
      var arrCampAssociation = getQueryWithFullEndPoint(arrCampAssociation.nextRecordsUrl);
      
    } while (arrCampAssociation.nextRecordsUrl != null && arrCampAssociation.nextRecordsUrl != undefined);

      let endRow = campAssocSheet.getLastRow(), 
       endColumn = campAssocSheet.getLastColumn(), 
       nameRange = campAssocSheet.getRange(2, 1, endRow, endColumn);

      sheet.setNamedRange('CampaignAssociation', nameRange);


    } catch (e) {
      Logger.log(e);
      Logger.log(arrCampAssociation);
      Logger.log(campaignAssoc);
      Logger.log(i);
    }
  }

因此,在这里,每个循环花费了更长的时间。而不是每个环之间的1-2秒钟,而是在第4个循环之后的每个循环中花费了45秒至一分钟。请参阅下面的日志:

我该如何解决?

Background

I have a function that makes a REST API call using UrlFetchApp in Google Scripts.

But the response only returns 2000 records at a time. If there are more records, there is, in the response, a key called nextRecordsUrl, which contains the endpoint and parameters needed to get the next batch of records.

I use a do...while loop to iterate through, pushing the records into a predesignated array, make the next api call. And when it reaches the last batch of records, it exists the do-while loop, then prints (not sure if that's the right term here) the entire to a Google Sheet.

The code

It looks like this:

function getCampaignAssociations() {
  clearPage('CampaignAssociations');
  var query = '?q=select+CampaignMember.FirstName,CampaignMember.LastName,CampaignMember.LeadId,CampaignMember.ContactId,CampaignMember.Name,CampaignMember.CampaignId,CampaignMember.SystemModstamp,CampaignMember.Email+from+CampaignMember+ORDER+BY+Email ASC,SystemModstamp+ASC';

  try {
    var arrCampAssociation = getInfoByQuery(query);

    if (arrCampAssociation.records.length < 1) {
      throw 'there are no records in this query';
    }

    var campaignAssoc = [];
    do {
      Logger.log(arrCampAssociation.nextRecordsUrl);

      for (var i in arrCampAssociation.records) {
        let data = arrCampAssociation.records[i];
        let createDate = Utilities.formatDate(new Date(data.SystemModstamp), "GMT", "dd-MM-YYYY");
        let a1 = "$A" + (parseInt(i) + 2);
        let nameFormula = '=IFERROR(INDEX(Campaigns,MATCH(' + a1 + ',Campaigns!$A$2:A,0),2),"")';
        let typeFormula = '=IFERROR(INDEX(Campaigns,MATCH(' + a1 + ',Campaigns!$A$2:A,0),3),"")';

        campaignAssoc.push([data.CampaignId, nameFormula, typeFormula, data.Email, data.FirstName, data.LastName, data.LeadId, data.ContactId, createDate]);
      }

      var arrCampAssociation = getQueryWithFullEndPoint(arrCampAssociation.nextRecordsUrl);
      
    } while (arrCampAssociation.nextRecordsUrl != null && arrCampAssociation.nextRecordsUrl != undefined);

      let endRow = campAssocSheet.getLastRow(), 
       endColumn = campAssocSheet.getLastColumn(), 
       nameRange = campAssocSheet.getRange(2, 1, endRow, endColumn),
       destRange = campAssocSheet.getRange(2, 1, campaignAssoc.length, campaignAssoc[0].length);
      destRange.setValues(campaignAssoc);
      sheet.setNamedRange('CampaignAssociation', nameRange);


    } catch (e) {
      Logger.log(e);
      Logger.log(arrCampAssociation);
      Logger.log(campaignAssoc);
      Logger.log(i);
    }
  }

Issue

Everything works nicely until it comes to printing the array campaignAssoc to the Google Sheet.

See screenshot of the log below. It contains the endpoint for the next both. Notice the timestamp between the earlier logs and the timestamp between the last endPoint and the log where it timed out.

enter image description here

It seems to me that the issue is that when it comes to the printing of the data, it's having issues. If that's the case, have I overloaded the array? There are a total of over 36400 records.

Second attempt

I've tried resetting the array at each loop and printing the array to Google sheet. This is just 2000 records at each attempt and I've definitely done more rows at 1 time, but that didn't help.

Here's the code for that attempt.

function getCampaignAssociations() {
  clearPage('CampaignAssociations');
  var query = '?q=select+CampaignMember.FirstName,CampaignMember.LastName,CampaignMember.LeadId,CampaignMember.ContactId,CampaignMember.Name,CampaignMember.CampaignId,CampaignMember.SystemModstamp,CampaignMember.Email+from+CampaignMember+ORDER+BY+Email ASC,SystemModstamp+ASC';

  try {
    var arrCampAssociation = getInfoByQuery(query);

    if (arrCampAssociation.records.length < 1) {
      throw 'there are no records in this query';
    }

    
    do {
      Logger.log(arrCampAssociation.nextRecordsUrl);
      var campaignAssoc = [];
      for (var i in arrCampAssociation.records) {
        let data = arrCampAssociation.records[i];
        let createDate = Utilities.formatDate(new Date(data.SystemModstamp), "GMT", "dd-MM-YYYY");
        let a1 = "$A" + (parseInt(i) + 2);
        let nameFormula = '=IFERROR(INDEX(Campaigns,MATCH(' + a1 + ',Campaigns!$A$2:A,0),2),"")';
        let typeFormula = '=IFERROR(INDEX(Campaigns,MATCH(' + a1 + ',Campaigns!$A$2:A,0),3),"")';

        campaignAssoc.push([data.CampaignId, nameFormula, typeFormula, data.Email, data.FirstName, data.LastName, data.LeadId, data.ContactId, createDate]);
        
      }
      let lastRow = campAssocSheet.getLastRow()+1;
      campAssocSheet.getRange(lastRow,1,campaignAssoc.length,campaignAssoc[0].length).setValues(campaignAssoc);
      var arrCampAssociation = getQueryWithFullEndPoint(arrCampAssociation.nextRecordsUrl);
      
    } while (arrCampAssociation.nextRecordsUrl != null && arrCampAssociation.nextRecordsUrl != undefined);

      let endRow = campAssocSheet.getLastRow(), 
       endColumn = campAssocSheet.getLastColumn(), 
       nameRange = campAssocSheet.getRange(2, 1, endRow, endColumn);

      sheet.setNamedRange('CampaignAssociation', nameRange);


    } catch (e) {
      Logger.log(e);
      Logger.log(arrCampAssociation);
      Logger.log(campaignAssoc);
      Logger.log(i);
    }
  }

So here, each loop took a lot longer. Instead of being 1-2 seconds between each loop, it took 45 seconds to a minute between each and timed out after the 4th loop. See the log below:
enter image description here

How do I fix this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文