2013-05-22 3 views
3

Javascript/GAS에 익숙하지 않아 GAS 문제로 다시 돌아 왔습니다. 효율적인 방법으로 함수 호출을 처리하는 방법에 따라 스크립트가 얼마나 느리게 실행되는지에 대한 약간의 문제가 있습니다.Google Apps Script 스프레드 시트 범위 처리 (Get-Process-Set; 작동하지 않음)

나는 일을이 "읽기 모두"다음 "쓰기 모든"- 분석 - 설정을 점점 (스프레드 시트 적어도) 값에 대한 것을, 여러 곳 (아, 그것은 here이었다)에 읽었습니다"get-one, write-one"방법보다 더 빨리 수행하십시오 (분명한 이유가 있습니다).

는 전 범위의 모든 값을 얻는 방법을 알고 있지만 나는 (다차원) 배열, 데이터를 처리를 통해 이동하고 그에 따라 새로운 범위을 설정하는 방법을 정말 모르겠어요.

문제 :이 기능은 시작하는 데 약 2 초 정도 걸립니다, 50 개 행을 실행하는 데 약 5 초 정도 걸립니다. 문제는이 스프레드 시트에 수천 개의 행이있을 가능성이 있으며이 기능을 실행하려면 데이터가 올바르게 처리되어 부메랑 캘린더가 시간 데이터를 올바르게 선택한다는 것입니다. 내 생각에 말도 안되는 말입니다. 이 스크립트는 처리해야하는 모든 데이터 열에 대해 두 배의 시간이 소요됩니다. 이는 끔찍한 일입니다. 나는 다음 학기 중에 나는 종종 "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() 함수를 이용하여 2 차원 배열 범위에서 값을 당겨. 2D 배열의 각 값을 처리합니다 (행 단위로 처리하는 것이 가장 논리적 인 방법 일 수 있음). 새 값으로 편집 된 값의 인덱스를 업데이트합니다 (코드의 Srik-answer 주석 참조). 그런 다음 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로 코드를 작성한 때였습니다. 처음에는 꽤 혼란스러워서 전에는 자바 스크립트로 작업 한 적이 없었기 때문에 모든 전화에서 무슨 일이 일어 났는지 알았는지 확인하고 싶었습니다. P가 도움이된다면 upvote를 자유롭게 사용하십시오;) –

답변

3

기본적으로, 함수의 대부분은 일반 자바 스크립트보다 더 많은 시간이 필요합니다 GAS에 나열된 API에 만들 것을 요구한다. 귀하의 경우, 범위에 대한 호출의 수를 줄이고 시트 클래스

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 방금 일하게되면, 지금 그것을 최적화하는 방법을 살펴 보겠습니다.당신이 Execution Transcript에서 모든 시간을 볼 수 있다는 것을 알았다면 아마 처음부터 더 많이 들었을 것입니다! 팁을 주셔서 감사 드리며, 앞으로 몇 시간 안에 내 진전 상황을 알려 드리겠습니다. –

+0

알았어, 테스트 해보니 몇 가지 API 호출 덕분에 이전보다 훨씬 빨라졌습니다. 그러나 값은 올바르게 조작되고 있지만 올바르게 설정되지는 않습니다. 그래서 'GetCell()'과'setCell()'함수를 가지고 있는데, 왜냐하면'Range.setValues ​​()'는 실제로 아무 일도하지 않았기 때문입니다. 'Logger'에 값을 기록했고 아포스트로피 문자가 올바르게 제거되었습니다. 그러나 값을 다시 Range로 설정하려고하면'dataRange.setValues ​​(values)'는 새로운 값을 설정하지 않습니다. 지금 해결책을 찾고 있습니다. 아이디어? –

+0

함수 끝에서'SpreadsheetApp.flush()'을 시도하십시오. – Srik

관련 문제