如何提高Google表格中包含循环的脚本的速度?

时间:2019-03-01 09:15:11

标签: google-apps-script

我的Google Apps脚本包含循环的速度较慢,这是一个问题。我正在寻找有关如何提高速度的建议。

我在名为“测试”的工作表上有以下输入数据(出于演示目的只是摘录,但要记住原始数据要大得多-产品和供应商更多)

Input sheet

我想在名为“供应商”的另一张纸上实现以下结果:

enter image description here

这个想法是按照上面显示的格式对供应商及其各自的产品和价格进行重组。条件是:

  • 排除无效产品;
  • 排除不活跃的供应商;
  • 仅包括每个供应商提供的可用价格的产品;
  • 添加新产品/供应商或更改输入表中的内容时动态更新数据。

我已经完成了以下脚本-它正在工作,但是考虑到原始数据很大的事实,速度相当慢。我非常感谢任何建议如何对其进行优化。我花了很多时间试图自己优化它,但无济于事。提前非常感谢!

function Suppliers() {
    var file                 = SpreadsheetApp.getActiveSpreadsheet();
    var sheetSourceName      = 'Test';
    var sheetDestinationName = 'Suppliers';
    var sourceSheet          = file.getSheetByName(sheetSourceName);
    var numRows              = sourceSheet.getLastRow();
    var numCols              = sourceSheet.getLastColumn();
    var destinationSheet     = file.getSheetByName(sheetDestinationName);  
    var sheet                = file.getActiveSheet();

    if( sheet.getSheetName() == sheetSourceName ) {

        var lastRow = destinationSheet.getLastRow();  

        destinationSheet.getRange( 2, 1, lastRow, 3 ).clear( { contentsOnly : true } );    

        var lastRow = 1;

        for( var s = 3; s < numCols + 3; s++ ){
            for( var p = 3; p < numRows + 3; p++ ){

                var product        = sourceSheet.getRange( p, 2 ).getValues();
                var activeProduct  = sourceSheet.getRange( p, 1 ).getValues();
                var price          = sourceSheet.getRange( p, s ).getValues();
                var supplier       = sourceSheet.getRange( 2, s ).getValues();
                var activeSupplier = sourceSheet.getRange( 1, s ).getValues();

                if( activeProduct == "active" && price > 0 && activeSupplier == "active" ){
                    lastRow = lastRow + 1;

                    destinationSheet.getRange( lastRow, 1 ).setValues( product  );
                    destinationSheet.getRange( lastRow, 2 ).setValues( price    );
                    destinationSheet.getRange( lastRow, 3 ).setValues( supplier );

                }
            }
        }
    }
}

1 个答案:

答案 0 :(得分:1)

不能保证,因为我没有设置适合您情况的数据表,但我认为这对您有用。在电子表格的副本中尝试。请注意,在您的getRange中,您使用以1开头的列和行。我将所有内容加载到数组中,并循环通过其值(索引从0开始)。因此它成为您的row / col -1。

function Suppliers() {
  var file                 = SpreadsheetApp.getActiveSpreadsheet();
  var sheetSourceName      = 'Test';
  var sheetDestinationName = 'Suppliers';
  var sourceSheet          = file.getSheetByName(sheetSourceName);
  var numRows              = sourceSheet.getLastRow();
  var numCols              = sourceSheet.getLastColumn();
  var destinationSheet     = file.getSheetByName(sheetDestinationName);  
  var sheet                = file.getActiveSheet();

  if( sheet.getSheetName() == sheetSourceName ) {
    destinationSheet.getRange( 2, 1, lastRow, 3 ).clear( { contentsOnly : true } );    
    var sourceData = sourceSheet.getRange(1,1,sourceSheet.getLastRow(),sourceSheet.getLastColumn()).getValues();
    var destinationData = [];
    // Not sure why +3 added to numRows and numCols because there is no data there
    for( var s=2; s<numCols; s++ ) {
      for( var p=2; p<numRows; p++ ) {
        var product        = sourceData[p][1];
        var activeProduct  = sourceData[p][0];
        var price          = sourceData[p][s];
        var supplier       = sourceData[1][s];
        var activeSupplier = sourceData[0][s];      
        if( activeProduct == "active" && price > 0 && activeSupplier == "active" ){
          destinationData.push([product,price,supplier]);
        }
      }
    }
    destinationSheet.getRange(2,1,destinationData.length,3).setValues(destinationData);
  }
}