Как насчет этой модификации?Пожалуйста, подумайте об этом как один из нескольких ответов.
И, что важно, пожалуйста, протестируйте сценарий, используя тестовую ситуацию, прежде чем приступить к реальной ситуации.
О вашем сценарии:
collectAndExportXLS()
: Что касается названия этой функции, я не изменял collectAndExportXLS()
.Потому что я подумал, что вы можете использовать это имя функции в другом сценарии или триггерах.
- Удалить все файлы в
gsheetFolder
. - Конвертировать таблицу Google в каждой папке ID, полученный из«B2: B53» листа с первым индексом в активной электронной таблице в формате XLSX.
- Имя файла похоже на
sample.xlsx
. - Все преобразованные файлы помещаются в
XLSXfolder
.
- Удалите все файлы во всех идентификаторах папок.
- XLSX-файлы в
XLSXfolder
заносятся в importXLSXfolder
другим скриптом.
importXLSXtoGsheet()
: имя этой функцииЯ не изменил collectAndExportXLS()
.Потому что я подумал, что вы можете использовать это имя функции в других скриптах или триггерах.
- Удалить все файлы в
XLSXfolder
. - Конвертировать все файлы XLSX в
importXLSXfolder
в GoogleSpreadsheet. - Имя файла похоже на
sample.xlsx
. - Преобразованные таблицы Google помещаются в
gsheetFolder
.
- Удалите все файлы в
importXLSXfolder
.
sortGsheetFiles()
- Переместите электронные таблицы Google в
gsheetFolder
в каждый идентификатор папки, полученный из «B2: B53» листа с 1-миндекс в активной электронной таблице. - Чтобы сопоставить идентификатор папки, имена файлов электронной таблицы Google и значения, полученные из "A2: A53".
- Удалить все файлы в
importXLSXfolder
.
Я понял, что из вашего вопроса имена файлов столбца "A2: A53" активной электронной таблицы совпадают с именами файлов электронных таблиц Google, которые были помещены в папкиидентификаторов папок столбца «B2: B53».
- Я понял, что количество всех файлов меньше 100.
Я понимаю, как выше.Если мое понимание верно, как насчет этой модификации?В моей модификации я использовал пакетный запрос Drive API и метод fetchAll UrlFetchApp с типом multipart/form-data
для вашей ситуации.Пакетный запрос и метод fetchAll могут работать с асинхронным процессом.Таким образом я подумал, что стоимость вашего процесса может быть уменьшена.
Чтобы использовать эти методы, я использовал 2 библиотеки GAS.Прежде чем запускать скрипт, пожалуйста, установите эти 2 библиотеки для вашего скрипта.Вы можете увидеть, как установить библиотеку, следующим образом.
- Установить библиотеку для запуска метода fetchAll UrlFetchApp с типом
multipart/form-data
. - Установить библиотеку для запуска пакетного запроса.
Точки изменения:
collectAndExportXLS()
- Идентификаторы файлов в каждой папке извлекаются с помощью пакетного запроса.
- Капли (в формате XLSX) из каждого идентификатора файла извлекаются методом fetchAll в UrlFetchApp.
- Файлы формата XLSX создаются FetchApp..
importXLSXtoGsheet()
- Список файлов извлекается с помощью метода files.list Drive API.
- ФайлыФормат XLSX преобразуется в электронную таблицу Google с помощью пакетного запроса.
sortGsheetFiles()
- Список файлов извлекается методом files.list изDrive API.
- Файлы электронной таблицы Google перемещаются в каждый идентификатор папки, полученный из столбца «B2: B53» активного Sпредварительный лист с использованием пакетного запроса.
deleteFolder()
- Файлы в папке удаляются пакетным запросом.
Когда в вашем сценарии отражены вышеуказанные точки, он становится следующим:
Модифицированный скрипт:
После установки 2 библиотек, пожалуйста, запустите следующий скрипт.
var gsheetFolder = '###';
var XLSXfolder = '###';
var importXLSXfolder = '###';
// Modified
function deleteFolder(folderId) {
var url = "https://www.googleapis.com/drive/v3/files?q='" + folderId + "'+in+parents+and+trashed%3Dfalse&fields=files%2Fid&access_token=" + ScriptApp.getOAuthToken();
var res = UrlFetchApp.fetch(url);
var obj = JSON.parse(res.getContentText());
var reqs = obj.files.map(function(e) {return {method: "DELETE", endpoint: "https://www.googleapis.com/drive/v3/files/" + e.id}});
var requests = {batchPath: "batch/drive/v3", requests: reqs};
if (requests.requests.length > 0) BatchRequest.Do(requests);
}
// Added
function deleteFiles(files) {
var reqs = files.map(function(e) {return {method: "DELETE", endpoint: "https://www.googleapis.com/drive/v3/files/" + e.id}});
var requests = {batchPath: "batch/drive/v3", requests: reqs};
if (requests.requests.length > 0) BatchRequest.Do(requests);
}
// Added
function getValuesFromSpreadsheet() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
return sheet.getRange("A2:B53").getValues();
}
// Modified
function sortGsheetFiles() {
var url = "https://www.googleapis.com/drive/v3/files?q='" + gsheetFolder + "'+in+parents+and+mimeType%3D'" + MimeType.GOOGLE_SHEETS + "'+and+trashed%3Dfalse&fields=files(id%2Cname)&access_token=" + ScriptApp.getOAuthToken();
var res = UrlFetchApp.fetch(url);
var obj = JSON.parse(res.getContentText());
var values = getValuesFromSpreadsheet();
var reqs = values.reduce(function(ar, e) {
for (var i = 0; i < obj.files.length; i++) {
if (obj.files[i].name == e[0]) {
ar.push({
method: "PATCH",
endpoint: "https://www.googleapis.com/drive/v3/files/" + obj.files[i].id + "?addParents=" + e[1] + "&removeParents=" + gsheetFolder,
});
break;
}
}
return ar;
}, []);
var requests = {batchPath: "batch/drive/v3", requests: reqs};
if (requests.requests.length > 0) BatchRequest.Do(requests);
deleteFolder(importXLSXfolder);
}
// Modified
function importXLSXtoGsheet(){
deleteFolder(XLSXfolder);
var url = "https://www.googleapis.com/drive/v3/files?q='" + importXLSXfolder + "'+in+parents+and+mimeType%3D'" + MimeType.MICROSOFT_EXCEL + "'+and+trashed%3Dfalse&fields=files(id%2Cname)&access_token=" + ScriptApp.getOAuthToken();
var res = UrlFetchApp.fetch(url);
var obj = JSON.parse(res.getContentText());
var reqs = obj.files.map(function(e) {return {
method: "POST",
endpoint: "https://www.googleapis.com/drive/v3/files/" + e.id + "/copy",
requestBody: {mimeType: MimeType.GOOGLE_SHEETS, name: e.name + ".xlsx", parents: [gsheetFolder]},
}
});
var requests = {batchPath: "batch/drive/v3", requests: reqs};
if (requests.requests.length > 0) BatchRequest.Do(requests);
deleteFolder(importXLSXfolder);
}
// Modified
function ConvertBackToXLS(fileList) {
var token = ScriptApp.getOAuthToken();
var reqs1 = fileList.map(function(e) {return {
method: "GET",
url: "https://docs.google.com/spreadsheets/export?id=" + e.id + "&exportFormat=xlsx&access_token=" + token,
}
});
var res = UrlFetchApp.fetchAll(reqs1);
var reqs2 = res.map(function(e, i) {
var metadata = {name: fileList[i].name, parents: [XLSXfolder]};
var form = FetchApp.createFormData(); // Create form data
form.append("metadata", Utilities.newBlob(JSON.stringify(metadata), "application/json"));
form.append("file", e.getBlob());
var url = "https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart";
return {url: url, method: "POST", headers: {Authorization: "Bearer " + token}, body: form};
});
FetchApp.fetchAll(reqs2);
}
// Modified
function collectAndExportXLS() {
deleteFolder(gsheetFolder);
var values = getValuesFromSpreadsheet();
var reqs1 = values.reduce(function(ar, e) {
if (e[0] && e[1]) {
ar.push({
method: "GET",
endpoint: "https://www.googleapis.com/drive/v3/files?q='" + e[1] + "'+in+parents+and+trashed%3Dfalse&fields=files(id%2Cname)",
});
}
return ar;
}, []);
var resForReq1 = BatchRequest.Do({batchPath: "batch/drive/v3", requests: reqs1});
var temp = resForReq1.getContentText().split("--batch");
var files = temp.slice(1, temp.length - 1).map(function(e) {return JSON.parse(e.match(/{[\S\s]+}/g)[0])});
var fileList = files.reduce(function(ar, e) {return ar.concat(e.files.map(function(f) {return f}))}, []);
ConvertBackToXLS(fileList);
deleteFiles(fileList);
}
Примечание:
- В этой модификации обработка ошибок не отражается, потому что я не смог проверить вашу ситуацию.Поэтому, пожалуйста, добавьте его, если вам необходимо.
- Если размер файла XLSX большой, может возникнуть ошибка.
Ссылки: