Display all files within every subdirectory located in a specified folder on Google Drive

Recently, I stumbled upon a script located at https://github.com/bluexm/snipets/blob/master/list%20Gdrive%20files%20and%20folders. The challenge I encountered was that the script was not capable of handling folders with identical names. As a result, I made some modifications to restrict the search to a specific folder. Unfortunately, the script only delves into one level of subfolders, failing to explore deeper levels such as 'Client Documents'/'2021-01-25'/'Subfolder1'/'Sub-Subfolder2'.

I'm perplexed as to why the script is unable to proceed to Sub-Subfolder1. Any insights or suggestions on this issue would be greatly appreciated.

function ListFilesandFolders(){
  var sheet = ss.getActiveSheet();
  var fileno = sheet.getSheetName();
  var filenoFolders = DriveApp.searchFolders("title contains '"+fileno.replace("'","\'")+"' and trashed = false and hidden = false");
  var filenoFolder = filenoFolders.next().getFoldersByName("Internal Documents").next();
  var clientdocsFolders = filenoFolder.getFoldersByName("Disclosure").next().getFoldersByName("Our Client").next().getFolders();
  var clientdocsFolder = filenoFolder.getFoldersByName("Disclosure").next().getFoldersByName("Our Client").next();
  var aorFolder = clientdocsFolder.getFoldersByName("Affidavit of Records").next();
  var tz = SpreadsheetApp.getActive().getSpreadsheetTimeZone();
  var date = Utilities.formatDate(new Date(), tz, "yyyy-MM-dd");

  // Find or Create doclist
  var aorFolderlist = aorFolder.getFiles();
  var doclist = "new"
  while (aorFolderlist.hasNext()) {
    var aorFile = aorFolderlist.next();
    if (aorFile.getName().includes("Document List")) {
      var doclist = SpreadsheetApp.open(aorFile);
      // doclist.duplicateActiveSheet().activate();
      // doclist.renameActiveSheet(date);
      // doclist.moveActiveSheet(0)
    }
  }
  if (doclist == "new") {
    var doclist = SpreadsheetApp.create(date + " Document List");
    doclist.renameActiveSheet(date);
    doclist.appendRow(["Document No.", "Document Date", "Document Title", "File Name", "URL", "Folder", "Date Created", "File ID", "File Name (No Date)", "Producible"]);
    DriveApp.getFileById(doclist.getId()).moveTo(aorFolder);
  }

  ListFilesandFolders1F(clientdocsFolders,'',doclist)
}

function ListFilesandFolders1F(fn,rfn,sheet) {
 
  // declare an array to push data into the spreadsheet
  var data = [];
  var count = 1;

  var foldersnext = fn.next();
  Logger.log("THE FOLDER IS "+foldersnext);// DEBUG

  // list files in this folder
  // myfiles is a File Iterator
  var myfiles = foldersnext.getFiles();

  Logger.log("FILES IN THIS FOLDER"); //DEBUG

  // loop through files in this folder
  while (myfiles.hasNext()) {
    var myfile = myfiles.next();
    count = Number(count) + 1;
    var shno = "#";
    var shdate = '=LEFT(D' + count + ',FIND(" ",D' + count + ')-1)';
    var shtitle = '=LEFT(I' + count + ',FIND(".",I' + count + ')-1)';
    var shfilename = '=RIGHT(D' + count + ',LEN(D' + count + ')-FIND(" ",D' + count + '))'; 
    var fname = myfile.getName();
    var fdate = myfile.getDateCreated();
    var fid = myfile.getId();
    var furl = myfile.getUrl();
    // Populate the array for this file
    data = [ 
      shno,
      shdate,
      shtitle,
      fname,
      furl,
      foldersnext,
      fdate,
      fid,
      shfilename
    ];
    //Logger.log("data = "+data); //DEBUG
    sheet.appendRow(data);
  } // Completes listing of the files in the named folder

  // Now get the subfolder
  // subfolders is a Folder Iterator
  var subfolders = foldersnext.getFolders();
  Logger.log("THE SUBFOLDER(S) ARE"); //DEBUG HEADING

  // now start a loop on the SubFolder list
  while (subfolders.hasNext()) {
    var subfolderdata = [];
    var mysubfolders = subfolders.next().getFolders();
    var mysubfolder = mysubfolders.next();  
    
    ListFilesandFolders1F(mysubfolders,rfn +'/'+ mysubfolder,sheet)
  
  }
}

Answer №1

Here is the provided solution:

/* This code snippet has been modified from the original written by @hubgit https://gist.github.com/hubgit/3755293
It has been updated due to the deprecation of DocsList  https://ctrlq.org/code/19854-list-files-in-google-drive-folder

Bluexm: implemented recursion for subfolders */

// Function to list all files and sub-folders in a specified folder and its subfolders on Google Drive

// main function 
function ListFilesandFolders(){
  var sheet = ss.getActiveSheet();
  var fileno = sheet.getSheetName();
  var filenoFolders = DriveApp.searchFolders("title contains '"+fileno.replace("'","\'")+"' and trashed = false and hidden = false");
  var filenoFolder = filenoFolders.next().getFoldersByName("Internal Documents").next();
  var clientdocsFolder = filenoFolder.getFoldersByName("Disclosure").next().getFoldersByName("Our Client").next();
  var aorFolder = clientdocsFolder.getFoldersByName("Affidavit of Records").next();
  var tz = SpreadsheetApp.getActive().getSpreadsheetTimeZone();
  var date = Utilities.formatDate(new Date(), tz, "yyyy-MM-dd");
  
  // Check if doclist exists or create one
  var aorFolderlist = aorFolder.getFiles();
  var doclist = "new"
  while (aorFolderlist.hasNext()) {
    var aorFile = aorFolderlist.next();
    if (aorFile.getName().includes("Document List")) {
      var doclist = SpreadsheetApp.open(aorFile);
      // doclist.duplicateActiveSheet().activate();
      // doclist.renameActiveSheet(date);
      // doclist.moveActiveSheet(0)
    }
  }
  if (doclist == "new") {
    var doclist = SpreadsheetApp.create(date + " Document List");
    doclist.renameActiveSheet(date);
    doclist.appendRow(["Document No.", "Document Date", "Document Title", "File Name", "URL", "Folder", "Date Created", "File ID", "File Name (No Date)", "Producible"]);
    DriveApp.getFileById(doclist.getId()).moveTo(aorFolder);
  }

  ListFilesandFolders1F(clientdocsFolder,'',doclist)
}

function ListFilesandFolders1F(fn,rfn,sheet) {
 
  // Initialize an array to store data for spreadsheet
  var data = [];
  var count = 1;

  var foldersnext = fn;
  Logger.log("THE FOLDER IS "+foldersnext);// DEBUG

  // Get list of files in this folder
  // myfiles is a File Iterator
  var myfiles = foldersnext.getFiles();

  Logger.log("FILES IN THIS FOLDER"); //DEBUG

  // Loop through files in this folder
  while (myfiles.hasNext()) {
    var myfile = myfiles.next();
    count = Number(count) + 1;
    var shno = "#";
    var shdate = '=LEFT(D' + count + ',FIND(" ",D' + count + ')-1)';
    var shtitle = '=LEFT(I' + count + ',FIND(".",I' + count + ')-1)';
    var shfilename = '=RIGHT(D' + count + ',LEN(D' + count + ')-FIND(" ",D' + count + '))'; 
    var fname = myfile.getName();
    var fdate = myfile.getDateCreated();
    var fid = myfile.getId();
    var furl = myfile.getUrl();
    // Populate the array for this file
    data = [ 
      shno,
      shdate,
      shtitle,
      fname,
      furl,
      foldersnext.getName(),
      fdate,
      fid,
      shfilename
    ];
    //Logger.log("data = "+data); //DEBUG
    sheet.appendRow(data);
  } // Finished listing files in the folder

  // Now get the subfolder
  // subfolders is a Folder Iterator
  var subfolders = foldersnext.getFolders();
  Logger.log("THE SUBFOLDER(S) ARE"); //DEBUG HEADING

  // Start loop on the SubFolder list
  while (subfolders.hasNext()) {
    var subfolderdata = [];
    var mysubfolders = subfolders.next(); 

    ListFilesandFolders1F(mysubfolders,rfn +'/'+ fn,sheet)
  
  }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What sets Express.js apart from koa2.js in handling asynchronous functions?

I've encountered a situation where I had to set up the router using Express, and it was functioning correctly with the following code: router.get('/',(req,res)=>{ queries.getAll().then(stickers=>{ res.json(stickers) }) ...

Having trouble embedding Hangouts button in HTML template using script tags

When I include a Hangouts button on my index page, it is visible and functional as expected: <body ng-app="sampleApp" ng-controller="MainCtrl"> <div class="row"> <div class="col-md-12 m-body"> <div class="m ...

Manipulating HTML output with JavaScript

I am in the process of creating a website that retrieves and displays data from a mySQL database using PHP. When I toggle a switch, I want the displayed data to be refreshed with a new search query. Below is the Javascript function for the switch: functi ...

Instructions on including a directory in the package.json file for publication on npm

I am facing an issue when attempting to publish a module in the npm repository as it is not recognizing the 'lib' folder. Even though I have included it in the package.json file as shown below, the 'lib' folder contents are not being re ...

Execute a JavaScript function prior to initiating an AJAX request

To streamline the process of making AJAX calls in my .NET project, I have developed a function called checkConnection that checks for internet connectivity before each call. However, currently, I am manually calling this function on every button click that ...

Inject some content into the page with the power of jQuery

Currently working with jQuery, I have a div containing H2 tags. <div id="preload"><h2></h2></div> I'm looking to understand how to use jQuery to insert text inside the <h2> tags The expected outcome should be: <div ...

Utilizing Web Worker threads to enhance performance in Google Maps

Currently, I am experimenting with web worker threads to retrieve directions between various pairs of locations simultaneously and save the data in a file at the end. The process worked smoothly when attempted sequentially. I am using npm live-server to sh ...

Retrieve the server code periodically and automatically refresh the form elements

Let's kick things off by explaining how the application functions: (please note there are multiple users on the page such as Patient M, Patient E, and so forth) 1) Check In: Next to Patient X's name, you will find a button labeled Check In. This ...

Modifying properties through JavaScript is not possible

I created an HTML form and I'm trying to change the attributes of a div and a button but for some reason, it's not working <form> <button type='button' id='other'>Sub</button> <select id="prop"> &l ...

Leveraging various routes to access data with a shared VueJS 3 component

Could you please review this code snippet: It displays two routes that utilize the same component to fetch content from an API. Main.js const router = createRouter({ history: createWebHistory(), routes: [ { path: "/route1& ...

The usage of Arrow Functions within Object Literal Syntax

I can't seem to understand why an arrow function within an object literal is invoked with window as the context for this. Any insights on this would be greatly appreciated. var arrowObject = { name: 'arrowObject', printName: () => { ...

Using the onMessage event in React Native WebView does not seem to have any functionality

I'm having trouble with the onMessage listener in React Native's WebView. The website is sending a postMessage (window.postMessage("Post message from web");) but for some reason, the onMessage listener is not working properly. I can't figure ...

Video background in webflow not currently randomizing

I want to add a dynamic video background to my website created with Webflow. I attempted to achieve this using Javascript by including the following links: "https://s3.amazonaws.com/webflow-prod-assets/63e4f3713963c5649a7bb382/63f787b42f81b8648e70fed ...

Fixing the error message "page attempting to load scripts from an unauthenticated source"

Can you help me troubleshoot an issue on my PHP page with ad scripts? I recently switched my site from HTTP to HTTPS and now the scripts are not appearing. Here is the error I found in the dev console: Failed to load resource: the server responded with ...

Exploring the World with the vue-i18n Plugin

Recently, I have integrated translation into my app and now I am looking to implement a button event that allows users to change the language on the home page. For this task, I referred to two tutorials: Localization with Vue and Localization with Vue Tut ...

Please be patient until setInterval() completes its task

In order to add a dice-rolling effect to my Javascript code, I am considering using the setInterval() method. To test this out, I have come up with the following code: function rollDice() { var i = Math.floor((Math.random() * 25) + 5); var j = i; ...

Suggestions for managing AngularJS within ASP.NET Web Forms?

Recently, I integrated AngularJs into a website that is built with asp.net webforms. I discovered that when using ng-Submit on a button, the form also triggers a Post call. How can I prevent the form from automatically submitting so that Angular can perf ...

Jquery animate - callback is triggered before animation finishes running

Is there a way for the element to first expand in height and then apply a background image once the height change is complete? Currently, I am experiencing laggy performance as the background image is applied before the height animation finishes. Can som ...

Combining arrays of objects into one single array

I possess a large array of intricately nested objects, akin to this (imagine adding 76 more products for a clearer picture): [ { "ProductID": 11, "ProductName": "Queso Cabrales", "SupplierID": 5, "CategoryID": 4, "QuantityPerUnit": " ...

Puppeteer throwing an error when querying selectors cannot be done (TypeError: selector.startsWith is not a supported function)

I recently installed Puppeteer and ran into an issue when trying to query a selector. I keep receiving a TypeError: selector.startsWith is not a function error. I attempted to resolve the problem by tweaking the core code and adding toString(), but unfort ...