应用程序脚本 运行ning 上的 for 循环非常慢,我怎样才能让它 运行 更快?
for loop on apps script running very slow, how can i make it run faster?
我有一个代码已经使用了 2 年,直到最近它都运行良好。几周前它开始发出超时警告,现在它不再 运行ning 了。
该代码从 google 驱动器上的 13 个不同文件夹中提取每张图片,然后将它们添加到 sheet,它在第 200 行后发出超时警告。我对其进行了一些修改,但我仍然得到超过最大执行时间警告(现在 360 行之后)
如果有人对此有解决方案,我将不胜感激。该脚本过去 运行 非常快(每秒大约 2-3 行),现在每行大约需要 3-4 秒。
非常感谢您!
这是脚本:
function Iteration() {
var lista_carpetas = SpreadsheetApp.getActive().getSheetByName("carpetas").getRange("A2:A").getValues(); //event list
var lista_carpetas_ok = lista_carpetas.reduce(function(ar, e) {
if (e[0]) ar.push(e[0])
return ar;
}, []);
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("data");
sheet.clear()
sheet.appendRow(["Name", "Date", "Size", "URL", "Download", "Description", "Image","Folder Id"]);
for (var i = 5; i <8; i++) {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("data");
var folderId = lista_carpetas_ok[i];
var season1 = SpreadsheetApp.getActive().getSheetByName("carpetas").getRange("B2:B").getValues(); //event list
var season = season1.reduce(function(ar, e) {
if (e[0]) ar.push(e[0])
return ar;
}, []);
var folder = DriveApp.getFolderById(folderId);
var contents = folder.getFiles();
var cnt = 0;
var file;
while (contents.hasNext()) {
var file = contents.next();
cnt++;
Logger.log(file);
Logger.log(cnt);
// writes the various chunks to the spreadsheet- just delete anything you don't want
data = [
file.getName(),
file.getDateCreated(),
file.getSize(),
file.getUrl(),
"https://docs.google.com/uc?export=download&confirm=no_antivirus&id=" + file.getId(),
file.getDescription(),
"=image(\"https://docs.google.com/uc?export=download&id=" + file.getId() +"\")",
folderId,
];
sheet.appendRow(data);
};
}
}
试试这个:
function Iteration() {
const ss = SpreadsheetApp.getActive();
const sh0 = ss.getSheetByName("carpetas");
const evlist = sh0.getRange("A6:A9").getValues().flat();
const sh1 = ss.getSheetByName("data");
sh1.clear();
sh1.appendRow(["Name", "Date", "Size", "URL", "Download", "Description", "Image", "Folder Id"]);
for (let i = 0; i < 3; i++) {
let folder = DriveApp.getFolderById(evlist[i]);
let contents = folder.getFiles();
while (contents.hasNext()) {
let file = contents.next();
sh1.appendRow([file.getName(),file.getDateCreated(),file.getSize(),file.getUrl(),"https://docs.google.com/uc?export=download&confirm=no_antivirus&id=" + file.getId(),file.getDescription(),"=image(\"https://docs.google.com/uc?export=download&id=" + file.getId() + "\")",evlist[i]]);
};
}
}
如果您必须使用“A2:A”之类的范围,则始终使用“A2:A”+ sheet.getLastRow() 的形式,否则您始终必须删除插入的空值从 getLastRow() 到 getMaxRows() 的范围很浪费时间。在这种情况下,使用固定范围实际上效果更好,因为您只使用了三行。
您可以将所有图像存储在 Google 图片库中,然后将其与 API 一起删除。
根据您在回复中的解释,
I didn't copy the whole code because the rest is just 4 more loops just like the one that i copied but for the other folders. So 4 loops in total pull the pictures from 13 different folders on google drive, and each loop pulls the pictures from 3-4 folders.
We have 13 folders on google drive which hold pictures from 2019-2022, and I made a loop that pulls the pictures from each folder that holds pictures for that year. Therefore the script has 4 for loops (only showing the first one above, which pulls the pictures from folders in rows 6 to 8, which are the folders for year 2018) that pull pictures from the folders on google drive.
我相信你的现状和目标如下。
- 您在“carpetas”的“A”列中有 13 个文件夹 ID sheet。
- 在您的脚本中,您想使用“carpetas”的“A6:A8”中的值sheet。
- 通过从“carpetas”的“A7:A9”检索到的文件夹 ID 的文件夹中检索文件元数据sheet,您想将检索到的文件元数据放入“数据”sheet .
- 您想降低脚本的处理成本。
修改点:
- 当您想从单元格“A6:A8”中检索文件夹 ID 时,当我看到您的脚本时,您的脚本似乎从单元格“A7:A9”中检索值。
- 在您的脚本中,循环中使用了
appendRow
。在这种情况下,工艺成本变高。 Ref
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("data")
可以出循环
season
未使用。所以var season1 = SpreadsheetApp.getActive().getSheetByName("carpetas").getRange("B2:B").getValues()
可以去掉。
当这些点反映在你的脚本中,就变成了下面这样。
修改后的脚本:
function Iteration() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var carpetasSheet = ss.getSheetByName("carpetas");
var lista_carpetas = carpetasSheet.getRange("A2:A" + carpetasSheet.getLastRow()).getValues();
var lista_carpetas_ok = lista_carpetas.filter(([a]) => a);
var sheet = ss.getSheetByName("data");
sheet.clear();
var files = [["Name", "Date", "Size", "URL", "Download", "Description", "Image", "Folder Id"]];
for (var i = 4; i < 7; i++) {
console.log(lista_carpetas_ok[i][0]) // Here, you can see the folder ID in the log.
var folderId = lista_carpetas_ok[i][0];
try {
var folder = DriveApp.getFolderById(folderId);
var contents = folder.getFiles();
while (contents.hasNext()) {
var file = contents.next();
var id = file.getId();
data = [
file.getName(),
file.getDateCreated(),
file.getSize(),
file.getUrl(),
"https://docs.google.com/uc?export=download&confirm=no_antivirus&id=" + id,
file.getDescription(),
"=image(\"https://docs.google.com/uc?export=download&id=" + id + "\")",
folderId,
];
files.push(data);
};
} catch (e) {
// In this modification, when your folder ID cannot be used, that folder ID is skipped. At that time, an error message can be seen in the log.
console.log(e.message);
}
}
if (files.length == 0) return;
sheet.getRange(1, 1, files.length, files[0].length).setValues(files);
}
注:
- 由于您的回复
only showing the first one above, which pulls the pictures from folders in rows 6 to 8, which are the folders for year 2018
,此修改后的脚本从单元格“A6:A8”中检索文件夹 ID。但如果你想从“A7:A9”中检索文件夹ID,请将for (var i = 4; i < 7; i++) {
修改为for (var i = 5; i < 8; i++) {
。
参考文献:
我有一个代码已经使用了 2 年,直到最近它都运行良好。几周前它开始发出超时警告,现在它不再 运行ning 了。 该代码从 google 驱动器上的 13 个不同文件夹中提取每张图片,然后将它们添加到 sheet,它在第 200 行后发出超时警告。我对其进行了一些修改,但我仍然得到超过最大执行时间警告(现在 360 行之后)
如果有人对此有解决方案,我将不胜感激。该脚本过去 运行 非常快(每秒大约 2-3 行),现在每行大约需要 3-4 秒。 非常感谢您!
这是脚本:
function Iteration() {
var lista_carpetas = SpreadsheetApp.getActive().getSheetByName("carpetas").getRange("A2:A").getValues(); //event list
var lista_carpetas_ok = lista_carpetas.reduce(function(ar, e) {
if (e[0]) ar.push(e[0])
return ar;
}, []);
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("data");
sheet.clear()
sheet.appendRow(["Name", "Date", "Size", "URL", "Download", "Description", "Image","Folder Id"]);
for (var i = 5; i <8; i++) {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("data");
var folderId = lista_carpetas_ok[i];
var season1 = SpreadsheetApp.getActive().getSheetByName("carpetas").getRange("B2:B").getValues(); //event list
var season = season1.reduce(function(ar, e) {
if (e[0]) ar.push(e[0])
return ar;
}, []);
var folder = DriveApp.getFolderById(folderId);
var contents = folder.getFiles();
var cnt = 0;
var file;
while (contents.hasNext()) {
var file = contents.next();
cnt++;
Logger.log(file);
Logger.log(cnt);
// writes the various chunks to the spreadsheet- just delete anything you don't want
data = [
file.getName(),
file.getDateCreated(),
file.getSize(),
file.getUrl(),
"https://docs.google.com/uc?export=download&confirm=no_antivirus&id=" + file.getId(),
file.getDescription(),
"=image(\"https://docs.google.com/uc?export=download&id=" + file.getId() +"\")",
folderId,
];
sheet.appendRow(data);
};
}
}
试试这个:
function Iteration() {
const ss = SpreadsheetApp.getActive();
const sh0 = ss.getSheetByName("carpetas");
const evlist = sh0.getRange("A6:A9").getValues().flat();
const sh1 = ss.getSheetByName("data");
sh1.clear();
sh1.appendRow(["Name", "Date", "Size", "URL", "Download", "Description", "Image", "Folder Id"]);
for (let i = 0; i < 3; i++) {
let folder = DriveApp.getFolderById(evlist[i]);
let contents = folder.getFiles();
while (contents.hasNext()) {
let file = contents.next();
sh1.appendRow([file.getName(),file.getDateCreated(),file.getSize(),file.getUrl(),"https://docs.google.com/uc?export=download&confirm=no_antivirus&id=" + file.getId(),file.getDescription(),"=image(\"https://docs.google.com/uc?export=download&id=" + file.getId() + "\")",evlist[i]]);
};
}
}
如果您必须使用“A2:A”之类的范围,则始终使用“A2:A”+ sheet.getLastRow() 的形式,否则您始终必须删除插入的空值从 getLastRow() 到 getMaxRows() 的范围很浪费时间。在这种情况下,使用固定范围实际上效果更好,因为您只使用了三行。
您可以将所有图像存储在 Google 图片库中,然后将其与 API 一起删除。
根据您在回复中的解释,
I didn't copy the whole code because the rest is just 4 more loops just like the one that i copied but for the other folders. So 4 loops in total pull the pictures from 13 different folders on google drive, and each loop pulls the pictures from 3-4 folders.
We have 13 folders on google drive which hold pictures from 2019-2022, and I made a loop that pulls the pictures from each folder that holds pictures for that year. Therefore the script has 4 for loops (only showing the first one above, which pulls the pictures from folders in rows 6 to 8, which are the folders for year 2018) that pull pictures from the folders on google drive.
我相信你的现状和目标如下。
- 您在“carpetas”的“A”列中有 13 个文件夹 ID sheet。
- 在您的脚本中,您想使用“carpetas”的“A6:A8”中的值sheet。
- 通过从“carpetas”的“A7:A9”检索到的文件夹 ID 的文件夹中检索文件元数据sheet,您想将检索到的文件元数据放入“数据”sheet .
- 您想降低脚本的处理成本。
修改点:
- 当您想从单元格“A6:A8”中检索文件夹 ID 时,当我看到您的脚本时,您的脚本似乎从单元格“A7:A9”中检索值。
- 在您的脚本中,循环中使用了
appendRow
。在这种情况下,工艺成本变高。 Ref var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("data")
可以出循环season
未使用。所以var season1 = SpreadsheetApp.getActive().getSheetByName("carpetas").getRange("B2:B").getValues()
可以去掉。
当这些点反映在你的脚本中,就变成了下面这样。
修改后的脚本:
function Iteration() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var carpetasSheet = ss.getSheetByName("carpetas");
var lista_carpetas = carpetasSheet.getRange("A2:A" + carpetasSheet.getLastRow()).getValues();
var lista_carpetas_ok = lista_carpetas.filter(([a]) => a);
var sheet = ss.getSheetByName("data");
sheet.clear();
var files = [["Name", "Date", "Size", "URL", "Download", "Description", "Image", "Folder Id"]];
for (var i = 4; i < 7; i++) {
console.log(lista_carpetas_ok[i][0]) // Here, you can see the folder ID in the log.
var folderId = lista_carpetas_ok[i][0];
try {
var folder = DriveApp.getFolderById(folderId);
var contents = folder.getFiles();
while (contents.hasNext()) {
var file = contents.next();
var id = file.getId();
data = [
file.getName(),
file.getDateCreated(),
file.getSize(),
file.getUrl(),
"https://docs.google.com/uc?export=download&confirm=no_antivirus&id=" + id,
file.getDescription(),
"=image(\"https://docs.google.com/uc?export=download&id=" + id + "\")",
folderId,
];
files.push(data);
};
} catch (e) {
// In this modification, when your folder ID cannot be used, that folder ID is skipped. At that time, an error message can be seen in the log.
console.log(e.message);
}
}
if (files.length == 0) return;
sheet.getRange(1, 1, files.length, files[0].length).setValues(files);
}
注:
- 由于您的回复
only showing the first one above, which pulls the pictures from folders in rows 6 to 8, which are the folders for year 2018
,此修改后的脚本从单元格“A6:A8”中检索文件夹 ID。但如果你想从“A7:A9”中检索文件夹ID,请将for (var i = 4; i < 7; i++) {
修改为for (var i = 5; i < 8; i++) {
。