如何通过使用数组从 Google 表格中提取数据并格式化来优化 Apps 脚本代码?

Posted

技术标签:

【中文标题】如何通过使用数组从 Google 表格中提取数据并格式化来优化 Apps 脚本代码?【英文标题】:How to optimise Apps Script code by using arrays to pull data from Google Sheets and format it? 【发布时间】: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)(?=(\d3)+\.)/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! 【参考方案1】:

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

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

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

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


参考资料:

getDisplayValue() getDisplayValues() getRichTextValue() getRichTextValues()

【讨论】:

【参考方案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)。如果有办法修复数组中的格式?

以上是关于如何通过使用数组从 Google 表格中提取数据并格式化来优化 Apps 脚本代码?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Google Apps 脚本中使用 Cheerio 提取 HTML 表格数据(雅虎财经)?

从第一张表格中提取信息时如何更新其他Google表格?

如何将数组传递到 Google 电子表格的 Google App 脚本中的查询字符串

我如何解析 JSON,将其排序为数组。提取数据并填充到表格视图中?

关于如何使用从其电子表格的html表单接收的数据创建pdf并通过电子邮件发送pdf文件的Google应用程序脚本

从 Google 表格中提取坐标。 int float 的问题切断了一切。我怎样才能通过实数?