我使用下面的代碼從 API 獲取資料。我在for回圈中使用了for回圈,它需要很長時間并且程式會隨著時間的推移而停止。
function devicedetails(){
var apikey='YWQ0OWFhYjgtNTY2asiHSNSajiasn'
var todaydate = Utilities.formatDate(new Date(Date.now() - 1000*60*60*24), "UTC", "yyyy-MM-dd")
var thirtydate = Utilities.formatDate(new Date(Date.now() - 1000*60*60*24*30), "UTC", "yyyy-MM-dd")
var cisss= SpreadsheetApp.getActiveSpreadsheet();
var workspacesheet = cisss.getSheetByName("Device");
var lastRows = workspacesheet.getLastRow() 1;
for(var im = 2; im < lastRows; im )
{
var workspacedata = workspacesheet.getRange('B' im).getValue();
var encodedata = encodeURIComponent(workspacedata);
var cisurl = "https://testapi.com/v1/workspaceDurationMetrics?workspaceId=" encodedata "&aggregation=daily&measurement=timeUsed&from=" thirtydate "T00:00:00.00Z&to=" todaydate "T00:00:00.00Z";
var cisss= SpreadsheetApp.getActiveSpreadsheet()
var ciswsLocation = cisss.getSheetByName("HourlyUsed")
var lastRow = ciswsLocation.getLastRow();
var headers = {
"Content-type": "application/json",
"Authorization": `Bearer ${apikey} `
};
var options = {
"method" : "get",
"headers" : headers
};
var response = UrlFetchApp.fetch(cisurl,options);
var cisjson=response.getContentText();
var cisdata=JSON.parse(cisjson);
for(var i = 0; i < cisdata['items'].length; i )
{
ciswsLocation.getRange(lastRow 1 i,1).setValue([cisdata["workspaceId"]]);
ciswsLocation.getRange(lastRow 1 i,2).setValue(Utilities.formatDate(new Date([cisdata["items"][i]['start']]), "UTC", "yyyy-MM-dd"));
ciswsLocation.getRange(lastRow 1 i,3).setValue([cisdata["items"][i]['duration']]);
}
}
}
請幫助我如何減少執行時間?
uj5u.com熱心網友回復:
正是 liqidkat 所說的。
有了它,它可能看起來像這樣:
function devicedetails() {
/** Variables **/
const apikey ='YWQ0OWFhYjgtNTY2asiHSNSajiasn'
const todaydate = Utilities.formatDate(new Date(Date.now() - 1000*60*60*24), "UTC", "yyyy-MM-dd")
const thirtydate = Utilities.formatDate(new Date(Date.now() - 1000*60*60*24*30), "UTC", "yyyy-MM-dd")
/** Sheet Variables **/
const cisss = SpreadsheetApp.getActiveSpreadsheet()
const workspacesheet = cisss.getSheetByName("Device")
const workspaceData = workspacesheet.getRange(2, 2, workspacesheet.getLastRow()-1).getValues().flat()
const ciswsLocation = cisss.getSheetByName("HourlyUsed")
const lastRow = ciswsLocation.getLastRow()
/** Request Handling **/
const allRequests = workspaceData.map(i => {
const encodeData = encodeURIComponent(i)
return {
"url": `https://testapi.com/v1/workspaceDurationMetrics?workspaceId=${encodeData}&aggregation=daily&measurement=timeUsed&from=${thirtydate}T00:00:00.00Z&to=${todaydate}T00:00:00.00Z`,
"method": "get",
"headers": {
"Content-type": "application/json",
"Authorization": `Bearer ${apikey}`
}
}
})
/** Response Handling **/
const allResponses = UrlFetchApp.fetchAll(allRequests)
const data = allResponses.map(response => {
const cisjson = response.getContentText()
const cisData = JSON.parse(cisjson)
return cisData[`items`].map(i => [
cisdata["workspaceId"],
Utilities.formatDate(new Date(i['start']), "UTC", "yyyy-MM-dd"),
i['duration']
])
})
/** Set data **/
ciswsLocation.getRange(lastRow 1, 3, data.length, data[0].length).setValues(data)
}
也可以看看:
- 陣列.map()
- UrlFetchApp.fetchAll()
- Range.setValues()
uj5u.com熱心網友回復:
我將提供我對這個問題的特殊方法,因為我認為它可能會引起社區的興趣。
由于 OP 沒有提供 API 提供的回應型別(并指出它是供私人使用的),因此我將使用公共 API 作為示例,在這種情況下是Google Books API 。我還將考慮對相同的 API 進行呼叫,因此假定回應是相同的。
我認為這個問題可以分為4個主要步驟。
- 生成呼叫的 URL(取決于 API)。
- 通過獲取資料
UrlFetchApp.fetchAll(Object) - 規范化資料(這是最關鍵的步驟,因為它取決于 API 回應)。重點是獲取
Object[][]下一步所需的陣列陣列( )。 - 使用 將資料寫入作業表
setValues(Object[][])。
完整的例子在這里。
生成 URL
const generateUrl = (authors) => authors.map(author => `https://books.googleapis.com/books/v1/volumes?q=${author}&country=US`)
獲取資料
const fetchAndNormalizeData = (urlList) => {
const resAll = UrlFetchApp.fetchAll(urlList).map(res => res.getContentText())
return resAll.map(normalizeResponse).flat()
}
規范化資料
const normalizeResponse = (res) => {
/* This depends on the RestAPI response */
const { items } = JSON.parse(res)
return items.map((book) => {
const { selfLink, volumeInfo: { title, authors, publishedDate } } = book
const parsedAuthors = authors ? authors.join('\n') : ""
return [title, parsedAuthors, selfLink, publishedDate]
})
}
寫入作業表
const writeToSheet = (data) => {
sS
.getRange(sS.getLastRow() 1, 1, data.length, data[0].length)
.setValues(data)
console.log("DATA SAVED")
}
主功能
const SS_ID = "<SS_ID>"
const sS = SpreadsheetApp.openById(SS_ID).getSheetByName('BookData')
const main = () => {
const urlList = generateUrl(["Twain", "Joyce", "Pasternak"])
const data = fetchAndNormalizeData(urlList)
writeToSheet(data)
}
在 OP 的情況下,只需修改normalizeResponse(地圖函式的回呼)并generateUrl使其適應他們的需要。
檔案:
Array.prototype.map()Array.prototype.flat()
uj5u.com熱心網友回復:
描述
我冒昧地編輯了您的腳本,將所有 getValue/setValue 替換為 getValues/setValues。我移動了所有只需要在回圈外設定一次的變數。首先,我獲取所有作業空間資料,然后在回圈中,為每一行索引到該陣列。接下來,由于您的結果在行和列中是連續的,因此我收集所有結果并呼叫 setValues 以放置在作業表中。
盡管由于輸入資料不可用,我無法對其進行測驗,但我相信它會起作用并且運行速度會更快。
盡管 Google 通過快取請求改進了 getValue/setValue 的性能,但我嘗試組織我的電子表格,以便始終使用 getValues/setValues。其他 getter 和 setter 也是如此。
腳本
function devicedetails(){
var apikey='YWQ0OWFhYjgtNTY2asiHSNSajiasn'
var todaydate = Utilities.formatDate(new Date(Date.now() - 1000*60*60*24), "UTC", "yyyy-MM-dd")
var thirtydate = Utilities.formatDate(new Date(Date.now() - 1000*60*60*24*30), "UTC", "yyyy-MM-dd")
var cisss= SpreadsheetApp.getActiveSpreadsheet();
var workspacesheet = cisss.getSheetByName("Device");
var lastRows = workspacesheet.getLastRow()-1;
var workspacedata = workspacesheet.getRange(2,2,lastRows-1,1).getValues();
var ciswsLocation = cisss.getSheetByName("HourlyUsed")
for(var im = 0; im < lastRows; im ) {
var encodedata = encodeURIComponent(workspacedata[im][0]);
var cisurl = "https://testapi.com/v1/workspaceDurationMetrics?workspaceId=" encodedata "&aggregation=daily&measurement=timeUsed&from=" thirtydate "T00:00:00.00Z&to=" todaydate "T00:00:00.00Z";
var lastRow = ciswsLocation.getLastRow();
var headers = {
"Content-type": "application/json",
"Authorization": `Bearer ${apikey} `
};
var options = {
"method" : "get",
"headers" : headers
};
var response = UrlFetchApp.fetch(cisurl,options);
var cisjson=response.getContentText();
var cisdata=JSON.parse(cisjson);
var results = [];
for(var i = 0; i < cisdata['items'].length; i ) {
let row = []
row[0] = cisdata["workspaceId"];
row[1] = Utilities.formatDate(new Date(cisdata["items"][i]['start']), "UTC", "yyyy-MM-dd");
row[2] = cisdata["items"][i]['duration'];
results.push(row);
}
ciswsLocation.getRange(lastRow 1,1,results.length,results[0].length).setValues(results);
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/473307.html
