Reputation: 533
This is a follow-up question for this thread.
Is there a way for me to get the IDs of the file in a different folder? Below is the directory of what I'm working on.
And this is the code that I'm using.
function myFunction() {
const ss = SpreadsheetApp.getActive();
var SSID = ss.getId(); //sheet id
var spreadsheetFile = DriveApp.getFileById(SSID);
var folderId = spreadsheetFile.getParents().next().getId();
const sh = ss.getSheetByName('Sheet4'); // change that to the name of your sheet
const filenames = sh.getRange('B3:B').getValues().flat().filter(r=>r!='');
const IDs = [];
const Folder = DriveApp.getFolderById(folderId);
filenames.forEach(fn=>{
let Files = Folder.getFilesByName(fn);
while(Files.hasNext()){
let file = Files.next();
IDs.push([file.getId()]);
}
});
sh.getRange(3,3,IDs.length,1).setValues(IDs);
}
This code works fine if the files are located in a folder, but it doesn't work for subfolders or a different folder.
Below is the sheet that I'm working on.
Upvotes: 0
Views: 1190
Reputation: 3251
There are a few options here. First there is the DriveApp.getFoldersByName(name)
method which will return the list of all folders in your drive which match the given name You will of course need to know the name of the folder before runtime and you cannot have any other folders with the same name, or you risk taking the id of the wrong folder.
If you know the id of some folder higher up the folder tree (such as the scripts direct parent as seen in the example above, see File.getParents()
) you can limit the impact of the above method by using Folder.getFoldersByName(name)
. The same restrictions as above apply here, but will be faster (less files to iterate over), but requires you to have the id of a parent folder.
You could also simply copy the folder id from the url if you know which file to access and will remain constant across script executions, and store it as a constant variable. This method is of course more rigid as you'll need to construct the file prior to runtime; however, you will not need to iterate overt he directory tree and will therefore be faster.
Upvotes: 1
Reputation: 201378
In this case, in order to achieve your goal, how about the following flow?
folderId
.When your script is modified, it becomes as follows.
const IDs = [];
const Folder = DriveApp.getFolderById(folderId);
filenames.forEach(fn=>{
let Files = Folder.getFilesByName(fn);
while(Files.hasNext()){
let file = Files.next();
IDs.push([file.getId()]);
}
});
To:
const Folder = DriveApp.getFolderById(folderId);
// 1. Retrieve the file list of all files in `folderId`.
const getFileList = (f, folders = [], fileList = {}) => {
const fs = f.getFiles();
while (fs.hasNext()) {
const file = fs.next()
fileList[file.getName()] = file.getId();
}
const fols = f.getFolders();
const folderObjs = [];
while (fols.hasNext()) folderObjs.push(fols.next());
if (folderObjs.length > 0) {
folders.push(folderObjs);
folderObjs.forEach(fol => getFileList(fol, folders, fileList));
}
return fileList;
};
const fileList = getFileList(Folder);
// 2. Create an array for putting values to Spreadsheet.
const IDs = filenames.map(fn => [fileList[fn] || ""]);
Upvotes: 1