2013-05-22 99 views
3

因爲我對Javascript/GAS還不太熟悉,所以我再次回到SO來解決GAS問題。基於處理函數調用的方法,以有效的方式處理腳本的速度有點慢,我遇到了一些麻煩。Google Apps腳本電子表格範圍處理(Get-Process-Set; Set Not Working)

我讀過幾個地方(啊,這是here),即做一個「讀所有」,然後「寫全」爲得到的解析設置值(在電子表格中至少)是更快比做一個「得到一個,寫一個」方法(由於顯而易見的原因,這是有道理的)。

我知道如何獲得範圍內的所有值,但我不確定如何通過(多維)數組,處理數據並相應地設置新的範圍

問題:該功能需要大約2秒鐘啓動,大約需要5秒鐘才能運行50行。問題是,我可能會在這個電子表格中有成千上萬的行,並且要讓這個函數運行到確保數據被正確地後處理,以便Boomerang Calendar正確地獲取時間數據在我看來是有點荒謬的。腳本需要處理的每一列數據需要兩倍的時間,這是可怕的。我擔心在下學期我會經常過去我的「GAS處理時限」。

這裏是起點代碼(不好,我承認):

function fixApostrophes() { 
    // Get the active spreadsheet to run the script on 
    var spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); 

    // Get the active sheet within the document to run the script on 
    var sheet = spreadsheet.getActiveSheet(); 

    // Get max number of rows needed to process 
    var maxRows = sheet.getLastRow(); 

    // Get the range for the startTime column and endTime column 
    var apostropheRange = sheet.getRange(1, 10, maxRows, 2); 

    // Get the value in each cell, remove apostrophes from the start, 
    // and replace the value in that cell 
    for (var i = 1; i < apostropheRange.getNumRows(); ++i) { 

    // Get the cells for startTime and endTime to speed things up a bit 
    var startCell = apostropheRange.getCell(i, 1); 
    var endCell = apostropheRange.getCell(i, 2); 

    // Get the values for startTime and endTime 
    var startTime = startCell.getValue(); 
    var endTime = endCell.getValue(); 

    // Remove apostrophes from start of startTime 
    while(startTime.charAt(0) == "'") { 
     startTime = startTime.substring(1); 
    } 

    // Remove apostrophes from start of startTime 
    while(endTime.charAt(0) == "'") { 
     endTime = endTime.substring(1); 
    } 

    // Set the values for startTime and endTime 
    startCell.setValue(startTime); 
    endCell.setValue(endTime); 
    } 
} 

這是高度相關的我的previous question有關修復這是打破迴旋鏢日曆功能調度事件的時間格式的撇號問題。

解決方案:使用Range.getValues()函數將值從範圍拖到二維數組中。處理2D數組中的每個值(逐行可能是最合乎邏輯的方法),然後更新編輯值的索引和新值(請參閱代碼中的回答註釋)。之後,使用Range.setValues(2Darray)將2D陣列中的元素放回到原始範圍中。我希望這可以幫助你,如果你遇到它!這也是很多比我原來的代碼中多次調用API更快。

function myNewLibraryFunction(startCol, numColumns) { 

    // Get the active spreadsheet to run the script on 
    var spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); 

    // Get the active sheet within the document to run the script on 
    var sheet = spreadsheet.getActiveSheet(); 

    // Get max number of rows needed to process 
    var maxRows = sheet.getLastRow(); 

    // Get the range for the startTime column and endTime column 
    var dataRange = sheet.getRange(1, startCol, maxRows, numColumns); 
    var values = dataRange.getValues(); 

    // Get the value in each cell, remove apostrophes from the start, 
    // and replace the value in that cell 
    for (var i = 1; i < maxRows; ++i) { 

// Get the values for startTime and endTime 
var startTime = values[i][0]; 
var endTime = values[i][1]; 

    // Remove apostrophes from start of startTime 
    while(startTime.charAt(0) == "'") { 
     startTime = startTime.substring(1); 
    } 

    // Remove apostrophes from start of startTime 
    while(endTime.charAt(0) == "'") { 
     endTime = endTime.substring(1); 
    } 

    values[i][0] = startTime; // New stuff from Srik's answer 
    values[i][1] = endTime; // New stuff from Srik's answer 
    } 
    dataRange.setValues(values); 
    SpreadsheetApp.flush(); // New stuff from Srik's answer 
} 
+1

感謝您搭建的解決方案。我一直有一些問題得到範圍值的工作,這讓我很對。榮譽;並熱愛全面評論! – MrGreggles

+0

@GreggCleland這是我第一次開始用GAS編碼。開始時,它非常混亂,以前從未使用Javascript,所以我想確保我評論它,以便知道所有呼叫發生了什麼:P如果這對您有幫助,請隨時致電;) –

回答

3

基本上,您對GAS中列出的API進行的大部分函數調用將需要比普通JavaScript更多的時間。在你的情況,減少調用的數量範圍,並表類

function fixApostrophes() { 
    // Get the active spreadsheet to run the script on 
    var spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); 

    // Get the active sheet within the document to run the script on 
    var sheet = spreadsheet.getActiveSheet(); 

    // 1. Replace two calls and many other calls later with one. 
    var dataRange = sheet.getDataRange(); 
    var values = dataRange.getValues();// a 2D array 

    // Get the value in each cell, remove apostrophes from the start, 
    // and replace the value in that cell 
    for (var i = 1; i < values .length ; ++i) { 

    // Get the values for startTime and endTime 
    var startTime = values [i][0]; 
    var endTime = values [i][1]; 

    // Remove apostrophes from start of startTime 
    // These are okay. Regular Javascript - not time consuming 
    while(startTime.charAt(0) == "'") { 
     startTime = startTime.substring(1); 
    } 

    // Remove apostrophes from start of startTime 
    while(endTime.charAt(0) == "'") { 
     endTime = endTime.substring(1); 
    } 

    } 

    dataRange.setValues(values); 
} 

提示:你可以看到每個呼叫多少時間參加了執行紀錄

+0

I剛剛開始工作,我會看看現在優化它。如果我知道你可以看到執行記錄中的所有時間,我可能會從一開始就更多地瞭解它!感謝提示,我會在接下來的幾個小時內讓你知道我的進展。 –

+0

好吧,測試一下,由於少數API調用,它比以前快得多。但是,這些值正在被正確操作,但沒有正確設置**。這就是爲什麼我有'getCell()'和'setCell()'函數,因爲'Range.setValues()'實際上並沒有做任何事情,就像現在它沒有做任何事情一樣。我已經在'Logger'中記錄了這些值,並且撇號正在被正確刪除。但是,當我們將值設置回'Range'時,'dataRange.setValues(values)'不會按照它應該設置的新值。現在尋找解決方案。想法? –

+0

在函數的末尾嘗試'SpreadsheetApp.flush()' – Srik

相關問題