【问题标题】:How to optimise Apps Script code by using arrays to pull data from Google Sheets and format it?如何通过使用数组从 Google 表格中提取数据并格式化来优化 Apps 脚本代码?
【发布时间】:2020-08-20 15:45:01
【问题描述】:

我有一个脚本,它从 gsheet 中获取数据并替换 gdoc 上的占位符。我希望通过使用数组来优化脚本。

这是我的 gsheet 示例(原始 gsheet 跨越 1000+ 行和 15+ 列),

原文:

function generategdoc() {

  SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1").activate();

  var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var lr = ss.getLastRow();

  for (var i =2;i<=lr;i++){

    if(ss.getRange(i, 1).getValue()){    

  //Make a copy of the template file
  var documentId = DriveApp.getFileById('FileID').makeCopy().getId();

  var Client = ss.getRange(i, 2).getValue();
  var Amount = ss.getRange(i, 3).getValue();
    var AmountFormat = Amount.toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, '$1,');  

  var Date = ss.getRange(i, 4).getValue();
    var temp = new Date(Date)
    var DateFormat = Utilities.formatDate(temp, "GMT+0400", "dd MMM yyyy")

  //Rename the copied file
  DriveApp.getFileById(documentId).setName(Client);  

  //Get the document body as a variable
  var body = DocumentApp.openById(documentId).getBody();

  body.replaceText('##Client##', Client).replaceText('##Amount##', AmountFormat).replaceText('##Date##', DateFormat)
    }
    else {}
  }
}

如您所见,此脚本只会针对所有已选中 TRUE 的行运行。

尝试1优化:

function optimise() {

  SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1").activate();

  var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var lr = ss.getLastRow();

  var rng = ss.getRange("A1:"+"D"+lr).getValues();  //Creation of Array

  for (var i =2;i<=lr;i++){

    if(ss.getRange(i, 1).getValue()){
      var Client = rng[i-1][1];
      var Amount = rng[i-1][2];
      var Date = rng[i-1][3];

  var documentId = DriveApp.getFileById('FileID').makeCopy().getId();

      DriveApp.getFileById(documentId).setName(Client);  

  var body = DocumentApp.openById(documentId).getBody();
      body.replaceText('##Client##', Client).replaceText('##Amount##', Amount).replaceText('##Date##', Date)
          }
    else {}
  }
}

问题:
我能够为AmountDate 格式化原始脚本。如何对数组使用相同的格式?因为我不能再将formatDate(class utilities)toFixed 应用于我的变量,因为它们现在是数组。

【问题讨论】:

  • 因为 formatDate 和 toFixed 是 Class Range 的方法。 你为什么这么说?提供此声明的文件
  • 我已经更新了声明——我的意思是说我不能应用 formatDate 和 toFixed 方法。我还更新了问题,改为问一个。
  • 根据您的文档链接,所有参数都不需要range 类型。它们属于Datestring 类型。您的数组类型是object[][](如getValues() 文档中所述),它由Datestring 类型组成。没有任何迹象表明您不能将 formatDate() 应用于数组内的值。
  • 是的,你是对的,我不应该假设。这是我应该使用的getDisplaceValues()。感谢您的耐心和指导。我很欣赏你的教学道德@TheMaster!

标签: javascript arrays google-apps-script optimization google-sheets


【解决方案1】:

我相信您可以通过使用适当的方法来优化您的代码,以保留您的 Google 工作表值的文本格式。

考虑使用SpreadsheetApp 服务中Range 类的以下方法。

方法getDisplayValue()返回范围内单元格的显示值。该值是一个字符串。显示的值考虑了日期、时间和货币格式,包括由电子表格的区域设置自动应用的格式。空单元格返回一个空字符串。

这应该通过消除正则表达式的必要性来优化您的代码。如果我没有正确理解您的问题,请发表评论。


参考资料:

【讨论】:

    【解决方案2】:

    你可以试试这样的。但这可能没有任何区别,因为创建文件需要很长时间。

    function optimise() {
      var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
      var vA= ss.getRange(1,1,ss.getLastRow(),4).getValues();
      var file = DriveApp.getFileById('FileID');
      for(var i=0;i<vA.length;i++){
        if(vA[i][0]){
          var Client=vA[i][1];
          var Amount=vA[i][2];
          var Date=vA[i][3];
          DriveApp.getFileById(file.makeCopy().getId()).setName(Client);  
          var body=DocumentApp.openById(documentId).getBody();
          body.replaceText('##Client##', Client).replaceText('##Amount##', Amount).replaceText('##Date##', Date)
        }
      }
    }
    

    我想知道您是否需要 saveAndClose() 文档。

    【讨论】:

    • 我已经更新了 if 语句 for (var i =2;i&lt;=lr;i++){ if(rng[i-1][0]){ 但是仍然可以最小化调用吗?此外,格式也没有按照原始脚本出现(参见问题 2)。如果有办法修复数组中的格式?
    猜你喜欢
    • 2022-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多