2016-05-22 19 views
0

我是Google App的腳本編程新手,除了基本的HTML以外,我沒有任何其他類型的腳本知識。但是,由於這個論壇,Google App腳本並沒有帶來太大的挑戰。什麼是適當的谷歌腳本複製動態更新範圍和粘貼在歸檔表?

我是一名數據分析師,一直在研究低成本/開源方式來模擬網站發佈商的一些基本大數據優勢。我的任務把我帶到Google腳本。自從我在一週前瞭解它之後,我已經能夠寫出一些。

目標面臨的挑戰是:

  1. 我有一個電子表格,動態拉使用IMPORTHTML功能約1000行。隨着源每天刷新,範圍會自動刷新,因此前一天的數據會丟失。這需要備份歸檔表中的數據,以便我可以分析選擇時間範圍內的歷史數據。

  2. 我想自動複製行並將它們粘貼到歸檔表的頂部,位於範圍標題下方,這樣我就不必按日期對歸檔進行歸類了,這可能需要進行數據分析。我還需要檢查重複的行並刪除它們 - 以防萬一。

首先,我寫了一個腳本,將複製的行追加到歸檔範圍的最後一行下面。但是,按日期排序變得非常必要,因爲我必須根據特定日期範圍(例如14天或7天)過濾數據以進行高級分析。所以我添加了一個用於排序的片段,另一個用於刪除重複。它運作良好,但是排序需要很長時間。考慮到每天都會增加數千個新的行,它將會持續更長的時間。我需要一個更智能的解決方案。因此我開始編寫一個腳本,它將(1)檢測源範圍中的行數(2)在歸檔表頭中插入儘可能多的行,以及(3)將複製範圍粘貼到新插入的行中。

我寫完了,它的工作速度非常快;顯然不需要分類。但是,我想知道,是否有辦法讓它更快,更智能,更具前瞻性。請找到下面的代碼。任何建議將不勝感激。

function myFunction() { 
 

 

 
    //1. Get data from source sheet of a spreadsheet whose id is known, we will also need the data range's last row number 
 

 
    var firstStep = SpreadsheetApp.openById("ID of Source Spreadsheet"); 
 
    var ss = firstStep.getSheetByName("Sheet1"); 
 
    ss.activate(); 
 
    var myRange = ss.getRange(4, 2, ss.getLastRow() - 3, ss.getLastColumn()); 
 
    var myData = myRange.getValues(); 
 

 

 
    //'3' subtracted from last row data collector above as first three rows contain static data or blank row in my source sheet. Applied same technique at line 17 below as well. This totally depends on how you position the source range in the source sheet. For exaple, for a range starting at 1,1 on any sheet, no such subtraction woud be required. 
 

 
    var lastRow = myRange.getLastRow() - 3; 
 

 

 
    //2. Open archive spreadsheet, select the destination sheet, insert exact number of rows of source range and then paste copied range. 
 

 
    var secondStep = SpreadsheetApp.openById("ID of archive spreadsheet"); 
 
    var newSS = secondStep.getSheetByName("dump1"); 
 
    newSS.activate(); 
 

 

 
    //2.a Insert Rows as in #lastrow in the new sheet, just below the header at Row 1 
 

 
    newSS.insertRowsBefore(2, lastRow) 
 

 

 
    //2.b Paste values 
 

 
    newSS.getRange(2, 1, myData.length, myData[0].length).setValues(myData); 
 

 

 
    //2.c Paste last row number of the copied range in another cell of the same sheet, optional step, just to be sure that last row determination process is right. You may remove this step if you like. 
 

 
    newSS.getRange(1, 15).setValue(lastRow); 
 

 
    /* 
 
    //3.a Optional: Script to remove duplicate rows in archive sheet. Will increase the script-run duration considerably. 
 
    
 
    var data = newSS.getDataRange().getValues(); 
 
    var newData = new Array(); 
 
    for(i in data){ 
 
    var row = data[i]; 
 
    var duplicate = false; 
 
    for(j in newData){ 
 
     if(row.join() == newData[j].join()){ 
 
     duplicate = true; 
 
     } 
 
    } 
 
    if(!duplicate){ 
 
     newData.push(row); 
 
    } 
 
    } 
 
    newSS.clearContents(); 
 
    newSS.getRange(1, 1, newData.length, newData[0].length).setValues(newData); 
 
    
 
    */ 
 

 
}

+1

,你應該認真考慮的Google BigQuery代替。有從應用程序腳本中使用它的示例。 –

+0

嗨Zig曼德爾,感謝您的評論。你能分享使用bigquery的鏈接/資源嗎? – AliveToLearn

+0

你到目前爲止搜索了什麼? –

回答

0

任何你可以在谷歌完成Apps腳本本身會比讓那些需要獲取從谷歌的服務器或外部服務器的數據,如請求電子表格,文檔,網站調用更快等等。如果您可以找到方法來儘量減少腳本對這些服務的調用,那麼腳本運行得更快。

要加速腳本,請使用一個命令將所有數據讀入數組,並對數組中的數據執行任何操作,並使用一個命令寫入數據。

下面是一個例子:

var cell = sheet.getRange('a1'); 
var colors = new Array(100); 
for (var y = 0; y < 100; y++) { 
xcoord = xmin; 
colors[y] = new Array(100); 
for (var x = 0; x < 100; x++) { 
colors[y][x] = getColor_(xcoord, ycoord); 
xcoord += xincrement; 
} 
ycoord -= yincrement; 
} 
sheet.getRange(1, 1, 100, 100).setBackgroundColors(colors); 

必須使用谷歌的最佳實踐,從谷歌的名單的亮點是:

  • 減少API調用的次數
  • 使得當API調用,批量請求
  • 使用內置緩存服務的Apps腳本
  • 請勿使用了UiApp;使用HTMLService

這裏的,這將幫助你提高你的腳本性能的文檔列表最佳實踐:除非你計劃只有幾千行https://developers.google.com/apps-script/best_practices#minimize-calls-to-other-services

+0

感謝d.datul1990提供您的答案。 – AliveToLearn

相關問題