用于列出文件的 Apps 脚本函数仅扫描任何给定文件夹的第一个子文件夹

Apps Script Function to list files only scans 1st subfolder of any given Folder

我一直在整个互联网上寻找如何列出我的共享驱动器文件的方法或代码。一开始我发现一个似乎有效,但在进一步测试后它扫描文件夹的方式存在重大缺陷。

现在我显然又找到了一些代码,我必须修改这些代码才能使其与 Shared Drives 一起使用,但我设法做到了。我唯一的问题是,它似乎只列出它找到的第一个 folder/subfolder 内的文件,并且不会循环。我的问题是它太快了,我无法诊断,而且在我的电子表格设置了整个周末之后,我没有时间也没有知识自己修复它。

这是我为使用共享驱动器而改编的代码:

    function ListarTodo() {
  /* Adapted from Adapted Code written by @Andres Duarte and Adapted by @Eric Aya in this link:
    
  */

  // Lista todos los archivos de una carpeta y de sus sub carpetas, y toma el nombre de la carpeta a analizar del nombre de la hoja activa.
  // List all files and sub-folders in a single folder on Google Drive, and get the name of the activesheet to know the folder desired.
  var parentFolder = DriveApp.getFolderById("INSERT YOUR FOLDER ID HERE");

  // Declaramos la hoja // declare this sheet
  var sheet = SpreadsheetApp.getActive().getSheetByName('INSERT YOUR SHEET NAME HERE');
  // Borramos los datos de la hoja // clear any existing contents
  sheet.clear();
  // Agregamos una linea con los titulos // append a header row
  sheet.appendRow(["Carpeta","Nombre Archivo", "Fecha ultima modificacion", "Tamaño MB", "URL", "ID", "Descripción", "Tipo archivo"]);

  // getFoldersByName = obtener una coleccion de todas las carpetas en la unidad Drive que tienen el nombre buscado "foldername".
  // folders es un "iterador de carpetas" pero hay solo una carpeta para llamar por el nombre, por eso tiene un solo valor (next)
  // getFoldersByName = Gets a collection of all folders in the user's Drive that have the given name.
  // folders is a "Folder Iterator" but there is only one unique folder name called, so it has only one value (next)
  var folders = parentFolder.getFolders();
  var foldersnext = folders.next();
  var lintotal = 2;

  //Iniciamos la funcion recursiva // Initiate recursive function
  lintotal = SubCarpetas(foldersnext, parentFolder.getName(), lintotal);  
}

function SubCarpetas(folder, path, cantlineas) {
  cantlineas = ListarArchivos(folder, path, cantlineas);
  var subfolders = folder.getFolders();

  while (subfolders.hasNext()) {
    var mysubfolders = subfolders.next();
    var mysubfolderName = mysubfolders.getName(); 
    var newpath = "";
    newpath = path + "/" + mysubfolderName;
    cantlineas = SubCarpetas(mysubfolders, newpath, cantlineas);
  }
  return(cantlineas) 
}

function ListarArchivos(mifoldersnext, mipath, milintotal) {
  var datos = []; //array temporal que vamos a usar para grabar en la hoja
  var files = []; //array con todos los archivos que encontramos en la carpeta que estamos evaluando
  var file = []; //array que usamos para volcar los datos de cada archivo antes de guardarlo
  var total = 0;
  var sheet = SpreadsheetApp.getActiveSheet();
  var myfiles = mifoldersnext.getFiles();

// Creamos un array con los datos de cada archivo y guardamos el total de archivos
while (myfiles.hasNext()) {
    files.push(myfiles.next());
    total++;
}
//ordenamos el array por nombre de archivo alfabeticamente  //sorts the files array by file names alphabetically
files = files.sort(function(a, b){
   var aName = a.getName().toUpperCase();
   var bName = b.getName().toUpperCase();
   return aName.localeCompare(bName);
});

////
var vuelta = 0;
var bulk = 10; //Definimos la cantidad de lineas a grabar cada vez, en la hoja de la planilla GoogleDoc
var linea = milintotal; //definimos en que linea vamos a grabar en la planilla
for (var i = 0; i < files.length; i++) { //recorremos el array de archivos y formateamos la informacion que necesitamos para nuestra planilla
    file = files[i];
    var fname = file.getName(); //nombre del archivo
    var fdate = file.getLastUpdated(); //fecha y hora ultima modificacion
    var fsize = file.getSize(); //tamaño del archivo, lo pasamos de byte a Kbyte y luego a Mb
    fsize = +fsize.toFixed(2); //lo formateamos a dos decimales
    var furl = file.getUrl(); //url del archivo
    var fid = file.getId(); //id del archivo
    var fdesc = file.getDescription(); //descripcion
    var ftype = file.getMimeType(); //tipo de archivo
    datos[vuelta] = [mipath+" ("+total+")", fname, fdate, fsize, furl, fid, fdesc, ftype]; //ponemos todo dentro de un array temporal
    vuelta++;
    if (vuelta == bulk) {//cuando alcanza la cantidad definida, guarda este array con 10 lineas y lo vacía
      linea = milintotal;
//      Logger.log("linea = "+linea); //DEBUG
//      Logger.log("vuelta = "+vuelta); //DEBUG
//      Logger.log("total = "+total); //DEBUG
//      Logger.log("lintotal = "+milintotal); //DEBUG
//      Logger.log("registros en datos = "+datos.length); //DEBUG
//      Logger.log("data = "+datos); //DEBUG
      sheet.getRange(linea, 1, bulk,8).setValues(datos); //guardamos los datos del array temporal en la hoja
      SpreadsheetApp.flush(); //forzamos que aparezcan los datos en la hoja - sin esto los datos no aparecen hasta terminar (genera mucha impaciencia)
      milintotal = milintotal + vuelta;
      datos = []; //vaciamos el array temporal
      vuelta = 0;
      }
    }

if (datos.length>0) {//Al salir del bucle grabamos lo que haya quedado en el array datos
      linea = milintotal;
//      Logger.log("linea = "+linea); //DEBUG
//      Logger.log("vuelta = "+vuelta); //DEBUG
//      Logger.log("total = "+total); //DEBUG
//      Logger.log("lintotal = "+milintotal); //DEBUG
//      Logger.log("registros en datos = "+datos.length); //DEBUG
//      Logger.log("data = "+datos); //DEBUG
      sheet.getRange(linea, 1, datos.length,8).setValues(datos);
      SpreadsheetApp.flush(); //ansiolítico
      milintotal = milintotal + datos.length;
      datos = [];
      vuelta = 0;
    }
return (milintotal)
}

这里是 到原来的 comment/code。

我是 Whosebug 的新手,所以我会尽力标记解决方案并就答案提供反馈。

根据您的评论,我认为您的目标如下。

  • 您想从特定文件夹中检索文件和文件夹列表。
  • 您想检索“名称”、“大小”、“添加日期”、“修改日期”、“url”的元数据。
  • 您想使用 Google Apps 脚本实现此目的。
  • 您想降低脚本的处理成本以实现此目的。

当我看到你的展示脚本时,循环中使用了setValues。在这种情况下,工艺成本变高。那么,在这种情况下,下面的示例脚本怎么样?

在此示例脚本中,使用了 Google Apps 脚本库。 Ref 我创建了这个库,用于使用 Google Apps 脚本以低处理成本检索文件和文件夹列表。

用法:

1。安装 Google Apps 脚本库。

库的安装方法见here

2。启用驱动器 API.

此库使用驱动器 API。所以 please enable Drive API at Advanced Google services.

3。示例脚本。

function sample() {
  const folderId = "###"; // Please set the top folder ID.

  // 1. Retrieve file and folder list under the specific folder.
  const { files } = FilesApp.createTree(folderId, null, "files(name,modifiedTime,createdTime,size,quotaBytesUsed,webViewLink,description)");

  // 2. Parse the list and create an array for putting to Spreadsheet.
  if (files.length == 0) return;
  const header = ["Name", "size", "added date", "modification date", "url", "description"];
  const values = [header, ...files.flatMap(({ filesInFolder }) => filesInFolder.map(e => [e.name, Number(e.quotaBytesUsed || e.size), new Date(e.createdTime), new Date(e.modifiedTime), e.webViewLink, e.description]))];

  // 3. Put the values to the Spreadsheet.
  const sheetName = "Sheet2"; // Please set the sheet nane.
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
  sheet.clearContents();
  sheet.getRange(1, 1, values.length, values[0].length).setValues(values);
}
  • 在此脚本中,folderId 可以同时使用您的云端硬盘和共享的云端硬盘。
  • 当此脚本为 运行 时,将从 folderId 检索文件和文件夹列表并将 "Name", "size", "added date", "modification date", "url" 的值放入电子表格。

参考: