2017-03-14 5 views
0

私は、特にJavaScript/Googleスクリプト言語の初心者です。私は以下のコードを作成していますが、動作しますが、作業コードを取得したので、どのように最適化できるかを見たいと思います。 getValue()の呼び出しはすべて主要なパフォーマンスヒットであると私は思っています。誰もがこのコードと同じことを達成するためのより良い方法を知っていますか?コードを最適化する - getValue()とループする

機能:フォルダの各スプレッドシートをチェックして、残りのスクリプトを実行する必要があるかどうかを確認します。 trueの場合、シートを開き、ループ内でチェックする行の量を制限するためにデータを持つ行の数を数えます。次に、ドライブ内の別のスプレッドシートに及ぶプッシュとコピーのマークが付いた行を探します。次に、フォルダー内の次のファイルに進み、同じことを行います。

すべての最初の

は、あなたが正しい、スタックオーバーフローに

function myVupdate() { 
    try { 
    var folder = DriveApp.getFolderById("123abc"), 
     files = folder.getFiles(); 
    while (files.hasNext()) { 
    var file = files.next(), 
     sss = SpreadsheetApp.open(file); 
    SpreadsheetApp.setActiveSpreadsheet(sss); 

    //Work orders update 
    var ss = sss.getSheetByName("Sheet2"), 
     refresh = ss.getRange("W3").getValue(); 
    if (refresh == 0) {continue}; 
    var avals = ss.getRange("D5:D").getValues(), 
     count = avals.filter(String).length, 
     rows = count + 5 
    var val = ss.getDataRange().getValues(); 
    for (var row=5; row < rows; row++) { 
    var cell = ss.getDataRange().getCell(row, 23).getValue(); 
    if (cell == 0) {   
     var cells = [["v" + "WO-" + val[row-1][3] + "_" + val[row-1][2],val[row-1][13],val[row-1][14],val[row-1][15],new Date()]]; 
     var tss = SpreadsheetApp.openById("target_spreadsheet"), 
      ts = tss.getSheetByName("Sheet5"); 
     ts.insertRowBefore(2); 
     var last_hmy = ts.getRange(3,1).getValue(); 
     ts.getRange(2,1).setValue(last_hmy+1); 
     ts.getRange(2,2,cells.length,cells[0].length).setValues(cells); 
     ts.getRange(2,7).setValue(sss.getName()); 
     ss.getRange(row,17).setValue(last_hmy+1); 
     ss.getRange(row,18,cells.length,cells[0].length).setValues(cells); 

     //Turnover update 
    var ss = sss.getSheetByName("Sheet1"), 
     avals = ss.getRange("D5:D").getValues(), 
     count = avals.filter(String).length, 
     rows = count + 5 
    var val = ss.getDataRange().getValues(); 
    } 
    } 
    for (var row=5; row < rows; row++) { 
    var cell = ss.getDataRange().getCell(row, 24).getValue(); 
    if (cell == 0) { 

     var cells = [["v" + val[row-1][3] + "_" + val[row-1][2],val[row-1][12],val[row-1][15],val[row-1][16],new Date()]]; 
     var tss = SpreadsheetApp.openById("target_spreadsheet"), 
      ts = tss.getSheetByName("Sheet5"); 
     ts.insertRowBefore(2); 
     var last_hmy = ts.getRange(3,1).getValue(); 
     ts.getRange(2,1).setValue(last_hmy+1); 
     ts.getRange(2,2,cells.length,cells[0].length).setValues(cells); 
     ts.getRange(2,7).setValue(sss.getName()); 
     ss.getRange(row,18).setValue(last_hmy+1); 
     ss.getRange(row,19,cells.length,cells[0].length).setValues(cells); 
    } 
    } 
    } 
} 
    catch(e) { 
    // Browser.msgBox("An error occured. A log has been sent for review."); 
    var errorSheet = SpreadsheetApp.openById ("target_sheet").getSheetByName("Error Log"), 
    source = sss.getName(); 
    lastRow = errorSheet.getLastRow(); 
    var cell = errorSheet.getRange('A1'); 
    cell.offset(lastRow, 0).setValue(e.message); 
    cell.offset(lastRow, 1).setValue(e.fileName); 
    cell.offset(lastRow, 2).setValue(e.lineNumber); 
    cell.offset(lastRow, 3).setValue(source); 
    cell.offset(lastRow, 4).setValue(new Date()); 
    MailApp.sendEmail("[email protected]", "Error report - " + new Date(), 
     "\r\nSource: " + source + "\r\n" 
     + "\r\nMessage: " + e.message 
     + "\r\nFile: " + e.fileName 
     + "\r\nLine: " + e.lineNumber 
    ); 
    } 
} 

答えて

2

こんにちは、歓迎:

は、ここに私のコードです。 getValue()またはsetValue()を呼び出すと、パフォーマンスが悪化します。ベストプラクティスhereをよく読んでください。できるだけこれらをバッチすることをお勧めします。注目に値するものの1つは次のとおりです。

var val = ss.getDataRange().getValues(); 

これで、シート上のすべての値が2次元配列になりました。それは、次のビットで

var ss = sss.getSheetByName("Sheet2"), 
     refresh = ss.getRange("W3").getValue(); 
    if (refresh == 0) {continue}; 
    var avals = ss.getRange("D5:D").getValues(), 
     count = avals.filter(String).length, 
     rows = count + 5 
    var val = ss.getDataRange().getValues(); 
    for (var row=5; row < rows; row++) { 
    var cell = ss.getDataRange().getCell(row, 23).getValue(); 

ひとつひとつgetValue()またはgetValues()はもはや必要であることを意味しません。代わりに、を知っているので、3番目の行と23番目の列が必要です。すでにそのシートのデータがある範囲全体を持っているからです。 n4から始まる

範囲D5:Dのすべての値としてavalsと同じ、vals[n][3]です。 は、配列のインデックスは0(その最初の行から始まり、最初の列はvals[0][0]で、覚えておいてください。

をだから、どこでも、あなたがssスプレッドシートからgetValues()を使用しようとしている、あなたはすでにデータが。あなたも何ができるか、であることを持っていますあなたが持っている配列を操作するので、常にその配列内の値だけを変更します。それを終えたら、ss.getDataRange().setValues(vals)を使用して配列全体を同じ範囲に戻します(datRange = ss.getDataRange()のような変数に範囲を保存するだけです)。 do datRange.setValues(vals)

あなたは他のシートのために別のデータ配列で作業する必要があります。同じアイデアが全部出てくるので、コードの残りの部分について詳しく説明します。 getValues()ですべてを取得しているので、その範囲内のセルにはgetValue()を使用する理由はなくなりました。