Get File by name at specific folder - google-apps-script

Trying to replicate this code to fine a specific file by name, by I got error at var files = DriveApp.getFilesByName(fileName); as Exception: Invalid argument at fileName, but if I entered the fileNamemanually as string "10504-China-ReflectiveTape-NA.jpg"` it is running correctly!
Below the full code:
// ****EXAMPLE****
//My arguments for the function
var myFileName = "10504-China-ReflectiveTape-NA.jpg";
var myFileParentFolderName = "Catalog";
//Run the function
var getFileID = getFileByName(myFileName, myFileParentFolderName);
//Check if folder exists
if(getFileID.id === false){ //if file cannot be accurately found.
Logger.log(getFileID.error); //alert or log error. Give option to try another FileName
}else{
// If the file ID exists then proceed with the program.
Logger.log(getFileID.id);
};
/*
* ****Get File By Name***
*
*param 1: File Name
*param 2: Parent Folder of File (optional)
*
*returns: Dictionary of file "id" and "error" message {"id": ,"error": }
* -if there is no error, "id" returns file id and "error" returns false
* -if there is an error, "id" returns false and "error" returns type of error as a string for user to display or log.
*/
function getFileByName(fileName, fileInFolder){
var filecount = 0;
var dupFileArray = [];
var folderID = "";
var files = DriveApp.getFilesByName(fileName);
while(files.hasNext()){
var file = files.next();
dupFileArray.push(file.getId());
filecount++;
};
if(filecount > 1){
if(typeof fileInFolder === 'undefined'){
folderID = {"id":false,"error":"More than one file with name: "+fileName+". \nTry adding the file's folder name as a reference in Argument 2 of this function."}
}else{
//iterate through list of files with the same name
for(fl = 0; fl < dupFileArray.length; fl++){
var activeFile = DriveApp.getFileById(dupFileArray[fl]);
var folders = activeFile.getParents();
var folder = ""
var foldercount = 0;
//Get the folder name for each file
while(folders.hasNext()){
folder = folders.next().getName();
foldercount++;
};
if(folder === fileInFolder && foldercount > 1){
folderID = {"id":false,"error":"There is more than one parent folder: "+fileInFolder+" for file "+fileName}
};
if(folder === fileInFolder){
folderID = {"id":dupFileArray[fl],"error":false};
}else{
folderID = {"id":false,"error":"There are multiple files named: "+fileName+". \nBut none of them are in folder, "+fileInFolder}
};
};
};
}else if(filecount === 0){
folderID = {"id":false,"error":"No file in your drive exists with name: "+fileName};
}else{ //IF there is only 1 file with fileName
folderID = {"id":dupFileArray[0],"error":false};
};
return folderID;
};

I wasn't able to replicate your issue where you passed a parameter and it fails vs you passed a string and it works.
But it seems that you are running getFileByName() directly by default thus it errors out like that.
Place everything else inside a main function and run that function instead.
I'm getting the expected output when I do that using your code.
It should look like this:
make sure that the chosen function is your main function that calls the getFileByName and just run the code.

Related

Is it possible to get the names of all the folders and create from each folder a custom script file for that folder

I made a code that renames multiple files in Google Drive (taken from Here) and here is the content
function renamejpgs() {
/*
// A given Goiogle Drive folder contains jpg files.
// The files have a consistent naming structure:
// "AA123_y.jpg, where y is a single or multi-digit sequence number.
//
// The function renames the files by removing the third, fourth, fifth and sixth characters of the file name and substituting a single"underscore"
// For example, "AA123_1.jpg" -> "AA_1.jpg"
*/
// set the mime type/file type to be renamed
var mimetype = 'image/jpeg';
// get the folder ID; note the id is a string
var folderid = "<<insert your folder ID>>"
// getFoldersById = Gets a specific folders in the user's Drive
var folder = DriveApp.getFolderById(folderid)
// get files in this folder
// myfiles is a File Iterator
var myfiles = folder.getFiles();
// loop through files in this folder
while (myfiles.hasNext()) {
var myfile = myfiles.next();
var myname = myfile.getName();
var ftype = myfile.getMimeType();
// find the next file that matches the mime type
var indexOfFirst = ftype.indexOf(mimetype);
if (indexOfFirst != -1){
// the next file was an image
// edit the file name
var fname = myname.replace("123_", "_");
// update the file name
myfile.setName(fname);
} //end if
} // end while loop through main folder
return false;
}
My problem is that it only works on the root folder and not on subfolders
I tried to ask in this place if subfolders could be included and they helped me change the name there. But then there was a problem of a longer time than the Google limit.
My question is Is it possible to get the names of all the folders and create from each folder a custom script file for that folder in Google Drive
function renamejpgs() {
/*
// A given Goiogle Drive folder contains jpg files.
// The files have a consistent naming structure:
// "AA123_y.jpg, where y is a single or multi-digit sequence number.
//
// The function renames the files by removing the third, fourth, fifth and sixth characters of the file name and substituting a single"underscore"
// For example, "AA123_1.jpg" -> "AA_1.jpg"
*/
// set the mime type/file type to be renamed
var mimetype = 'image/jpeg';
// get the folder ID; note the id is a string
var folderid = "<<insert your folder ID>>"
// getFoldersById = Gets a specific folders in the user's Drive
var folder = DriveApp.getFolderById(folderid)
// get files in this folder
// myfiles is a File Iterator
var myfiles = folder.getFiles();
// loop through files in this folder
while (myfiles.hasNext()) {
var myfile = myfiles.next();
var myname = myfile.getName();
var ftype = myfile.getMimeType();
// find the next file that matches the mime type
var indexOfFirst = ftype.indexOf(mimetype);
Utilities.sleep(10);
if (indexOfFirst != -1){
// the next file was an image
// edit the file name
var fname = myname.replace("123_", "_");
// update the file name
myfile.setName(fname);
} //end if
} // end while loop through main folder
return false;
}
I believe this will help stop the code from timing out.
I added a sleep function to pause it and stop it from exhaustion.
This is my basis of research for using the sleep function: https://webapps.stackexchange.com/questions/116041/how-to-set-up-delays-in-google-apps-script
In this implementation, I've decided to use Drive API service on Apps Scripts in order to use the filter functionality (q parameter) of Drive API queries.
Given that, make sure to add Drive API on the service list on your Apps Scripts project.
The code below will "scan" for a file name that includes MATCH_PATTERN set on a given starting folder ID including sub-folders.
Make sure to customize the constants in the beginning to adapt to your use case.
The function main() is a sample start point for this script.
Sample Code:
const MATCH_PATTERN = "[replace]"; //file name pattern to be renamed
const REPLACE_PATTERN = "[123456789]"; //pattern to replace MATCH_PATTERN from file name
const MIMETYPE_TARGET_FILES = "image/jpeg"; //mimetype of target files
function listFoldersIn(parentId = "root") {
/**
* Lists sub-folders in the user's Drive for a given folder ID.
* Slightly modified script from https://developers.google.com/apps-script/advanced/drive#listing_folders
*/
var query = '"'+ parentId +'" in parents and trashed = false and ' +
'mimeType = "application/vnd.google-apps.folder"';
var folders;
var pageToken;
var folderIdList = [];
do {
folders = Drive.Files.list({
q: query,
maxResults: 100,
pageToken: pageToken
});
if (folders.items && folders.items.length > 0) {
for (var i = 0; i < folders.items.length; i++) {
var folder = folders.items[i];
folderIdList.push(folder.id);
}
}
pageToken = folders.nextPageToken;
} while (pageToken);
return folderIdList;
};
function listTargetFilesForParent(parentId = "root", mime = MIMETYPE_TARGET_FILES) {
/**
* Lists files on a given folder ID matching the MIME type set.
* Slightly modified script from https://developers.google.com/apps-script/advanced/drive#listing_folders
*/
var query = '"'+ parentId +'" in parents and trashed = false and ' +
'mimeType = "'+ mime +'"';
var files;
var pageToken;
var fileIdList = [];
do {
files = Drive.Files.list({
q: query,
maxResults: 100,
pageToken: pageToken
});
if (files.items && files.items.length > 0) {
for (var i = 0; i < files.items.length; i++) {
var file = files.items[i];
fileIdList.push({title: file.title, id: file.id});
}
}
pageToken = files.nextPageToken;
} while (pageToken);
return fileIdList;
};
function renameFilesInFolders(folderList) {
if (folderList.length > 0) { //if folder ID list provided is empty, exit method;
for (folder of folderList) { //loop for folder ID list provided.
//Fetch target files in current folder
var filesList = listTargetFilesForParent(parentId = folder);
renameTargetFiles(filesList); // Rename files if applicable;
//Check for sub folders
var subFolders = listFoldersIn(folder);
if (subFolders.length > 0) { //It has subfolders?
renameFilesInFolders(subFolders); //call this same method recursively
} else { //if current folder does not have sub-folders, then do nothing and continue loop;
continue;
}
}
} else {
return;
}
}
function renameTargetFiles(filesList){
for (file of filesList) { //loop through file list provided
if (file.title.includes(MATCH_PATTERN)) { //is current file applicable to be renamed? In other words, does the current file name contain the MATCH_PATTERN?
var newName = file.title.replace(MATCH_PATTERN, REPLACE_PATTERN); //replace MATCH_PATTERN from file name for REPLACE_PATTERN
Drive.Files.patch({title: newName}, file.id); //Call Drive API patch to modify file name.
}
}
}
function main() {
/**
* Make sure to set up constants in the beginning of this file to adapt to your use case
* When calling renameFilesInFolders() without passing parameters, it will scan starting from the root of My Drive.
* Passing an array of a single Drive Folder ID, sets the root level for the scan
*/
renameFilesInFolders(["<STARTING_FOLDER_ID>"]);
}

DriveApp: Get File ID with Parent Folder ID/Name and File Name

I'm trying to use DriveApp to determine a file ID utilizing:
Either the parent folder name, or the parent folder ID
The file name in question
I thought I'd use this:
https://yagisanatode.com/2018/10/05/google-apps-script-get-file-by-name-with-optional-parent-folder-crosscheck/
But it always returns:
There are multiple files named: (filename). But none of them are in folder, (foldername).
...which is not true. Any ideas or any easier way to do this?
Thanks in advance.
Here's a minimal example:
/*
* ****Get File By Name***
*
*param 1: File Name
*param 2: Parent Folder of File (optional)
*
*returns: Dictionary of file "id" and "error" message {"id": ,"error": }
* -if there is no error, "id" returns file id and "error" returns false
* -if there is an error, "id" returns false and "error" returns type of error as a string for user to display or log.
*/
function getFileByName(fileName, fileInFolder){
var filecount = 0;
var dupFileArray = [];
var folderID = "";
var files = DriveApp.getFilesByName(fileName);
while(files.hasNext()){
var file = files.next();
dupFileArray.push(file.getId());
filecount++;
};
if(filecount > 1){
if(typeof fileInFolder === 'undefined'){
folderID = {"id":false,"error":"More than one file with name: "+fileName+". \nTry adding the file's folder name as a reference in Argument 2 of this function."}
}else{
//iterate through list of files with the same name
for(fl = 0; fl < dupFileArray.length; fl++){
var activeFile = DriveApp.getFileById(dupFileArray[fl]);
var folders = activeFile.getParents();
var folder = ""
var foldercount = 0;
//Get the folder name for each file
while(folders.hasNext()){
folder = folders.next().getName();
foldercount++;
};
if(folder === fileInFolder && foldercount > 1){
folderID = {"id":false,"error":"There is more than one parent folder: "+fileInFolder+" for file "+fileName}
};
if(folder === fileInFolder){
folderID = {"id":dupFileArray[fl],"error":false};
}else{
folderID = {"id":false,"error":"There are multiple files named: "+fileName+". \nBut none of them are in folder, "+fileInFolder}
};
};
};
}else if(filecount === 0){
folderID = {"id":false,"error":"No file in your drive exists with name: "+fileName};
}else{ //IF there is only 1 file with fileName
folderID = {"id":dupFileArray[0],"error":false};
};
return folderID;
};
function test() {
//My arguments for the function
var myFileName = "Invoices";
var myFileParentFolderName = "testing";
//Run the function
var getFileID = getFileByName(myFileName, myFileParentFolderName);
//Check if folder exists
if(getFileID.id === false){ //if file cannot be accurately found.
Logger.log(getFileID.error); //alert or log error. Give option to try another FileName
}else{
// If the file ID exists then proceed with the program.
Logger.log(getFileID.id);
};
}
The solution is much simpler than you think.
In the following script, adjust the folderID and fileName to your
particular case and it will store in an array all the IDs if multiple
files exist in this folder with the selected name.
If the file exists only one, then you will get an array of a single element.
Solution:
function findFilesInfo() {
const folderId = 'folderID';
const fileName = 'fileName';
const folder = DriveApp.getFolderById(folderId);
const files = folder.getFilesByName(fileName);
const fileIDs = [];
while (files.hasNext()) {
var file = files.next();
fileIDs.push(file.getId());
}
Logger.log(fileIDs);
}
fileIDs has the list of IDs of the particular fileName under the folder with ID folderID.

Checking a folder for a filename, and exporting as PDF if it is not found

I am quite new to scripting and has attempted this for embarrassingly many hours now, so I hope you can help me.
I have a dashfolder that contains Google Sheets called "X", and I have a pdffolder containing pdfs that are called "X.pdf". I am trying to loop through the names of my dashfiles + ".pdf" to find those which are missing, and finally create its pdf in that same folder. My script, however, loops too many times. I want it to skip the dashfile if a file with the name+".pdf" are already in the pdffolder. Here is my code
function createPdf() {
var pdfFolder = DriveApp.getFolderById("ID")
var pdfFiles = pdfFolder.getFiles();
var dashFolder = DriveApp.getFolderById('ID');
var dashFiles = dashFolder.getFiles();
var pdfNames = [];
var dashNames = [];
while (pdfFiles.hasNext()) {
var currentFile2 = pdfFiles.next();
var fileName2 = currentFile2.getName();
pdfNames.push(fileName2);
}
while (dashFiles.hasNext()) {
var currentFile = dashFiles.next();
var fileName = currentFile.getName();
dashNames.push(fileName);
for (p in pdfNames) {
if((fileName + ".pdf") == pdfNames[p]) {
Logger.log("YES");
}
else {
var xlsBlob = currentFile.getBlob(); // Blob source of Excel file for conversion
var xlsFilename = currentFile.getName(); // File name to give to converted file; defaults to same as source file
pdfFolder.createFile(currentFile.getAs(MimeType.PDF));
Logger.log("pdf Created");
}
}
}
}
My real problem stems from the fact that I will have 100+ sheets that needs to be converted to pdf's and that will exceed the 6 minutes limit. So I am trying to build a script that can trigger itself and continue where it left off, skipping sheets that are already in the pdffolder and creating those that are missing.
I might be way over my head here, so I hope someone can give me some hints :-)
You wrong use loops. Currently you create more pdfs of same sheet, because when you traversating over dashFiles, you create PDF one more pdf for each exists PDF.
Change part of code like this:
var pdfNames = {}; //Object instead of array
while (pdfFiles.hasNext()) {
var currentFile2 = pdfFiles.next();
var fileName2 = currentFile2.getName();
pdfNames[fileName2] = true; // use PDF name as key for faster searching
}
while (dashFiles.hasNext()) {
var currentFile = dashFiles.next();
var fileName = currentFile.getName();
if(pdfNames[fileName + ".pdf"]) { // is exists pdf?
Logger.log("YES");
}
else {
var xlsBlob = currentFile.getBlob(); // Blob source of Excel file for conversion
var xlsFilename = currentFile.getName(); // File name to give to converted file; defaults to same as source file
pdfFolder.createFile(currentFile.getAs(MimeType.PDF));
Logger.log("pdf Created");
}
}
You can create an object of file names with a value of true, and then check for the existence of the file name in the object. If the file name exists, then continue to loop.
var pdfNames = {};//Create an object - not an array
pdfNames[fileName2] = true;//Put the file name into the object
if (pdfNames[fileName]) {//Test for file name in the object
Code:
function createPdf() {
var currentFile,fileName,xlsBlob,xlsFilename;
var pdfFolder = DriveApp.getFolderById("ID")
var pdfFiles = pdfFolder.getFiles();
var dashFolder = DriveApp.getFolderById('ID');
var dashFiles = dashFolder.getFiles();
var pdfNames = {};
var dashNames = [];
while (pdfFiles.hasNext()) {
var currentFile2 = pdfFiles.next();
var fileName2 = currentFile2.getName();
pdfNames[fileName2] = true;//Put the file name into the object
}
while (dashFiles.hasNext()) {
currentFile = dashFiles.next();
fileName = currentFile.getName();
dashNames.push(fileName);
if (pdfNames[fileName]) {//The file name was found in the object of pdf files
Logger.log("YES");
continue;
}
xlsBlob = currentFile.getBlob(); // Blob source of Excel file for conversion
xlsFilename = currentFile.getName(); // File name to give to converted file; defaults to same as source file
pdfFolder.createFile(currentFile.getAs(MimeType.PDF));
Logger.log("pdf Created");
}
}
Original Answer:
Test for the existence of the file name in the pdf array in a different way.
pdfNames.indexOf(fileName + ".pdf") !== -1
If a value is not found in an array, then indexOf() returns minus one.
So, if the return value is not minus one, then a file name was found. If a file name was found, you don't want a new file created, so continue.
function createPdf() {
var currentFile,fileName,xlsBlob,xlsFilename;
var pdfFolder = DriveApp.getFolderById("ID")
var pdfFiles = pdfFolder.getFiles();
var dashFolder = DriveApp.getFolderById('ID');
var dashFiles = dashFolder.getFiles();
var pdfNames = [];
var dashNames = [];
while (pdfFiles.hasNext()) {
var currentFile2 = pdfFiles.next();
var fileName2 = currentFile2.getName();
pdfNames.push(fileName2);
}
while (dashFiles.hasNext()) {
currentFile = dashFiles.next();
fileName = currentFile.getName();
dashNames.push(fileName);
if (pdfNames.indexOf(fileName + ".pdf") !== -1) {//The file name was found in the array of pdf files
Logger.log("YES");
continue;
}
xlsBlob = currentFile.getBlob(); // Blob source of Excel file for conversion
xlsFilename = currentFile.getName(); // File name to give to converted file; defaults to same as source file
pdfFolder.createFile(currentFile.getAs(MimeType.PDF));
Logger.log("pdf Created");
}
}

DocumentApp.openById() fails with “Service unavailable”

I am trying to read the contents of a spreadsheet which contains some folderId, fileName and targetFile and then based on the data entered in the spreadsheet.
I am finding the latest fileId in the drive for the same fileName as multiple files with the same name are getting added into the folder daily (this is done by the function mostRecentFiIeInFolder) and then I am trying to copy the contents of the latest file with ID dociIdSource into a different file with ID docIdTarget (which is done by the function docCopy).
But when I tried Implementing this using DocumentApp, I am getting a weird error which says
Service unavailable: Docs
for the code var baseDoc = DocumentApp.openById(docID);.
May I know where I am going wrong?
// Test function to call applyDocCopytoList.
function test(){
applyDocCopytoList();
}
// Read the values from the spreadsheet.
function applyDocCopytoList(){
var originalSpreadsheet = SpreadsheetApp.openById('sheet Id goes here').getSheetByName("sheet name goes here");
var getRange = originalSpreadsheet.getDataRange();
var data = originalSpreadsheet.getDataRange().getValues();
for (var i = 1; i < data.length; i++) {
var folderId = data[i][1];
var fileName = data[i][2];
var targetFile = data[i][3];
Logger.log('****************Record No: ' + i);
Logger.log('folderId: ' + data[i][1]);
Logger.log('fileName: ' + data[i][2]);
Logger.log('targetFile: ' + data[i][3]);
var latestFileId = mostRecentFiIeInFolder(folderId, fileName);
if(latestFileId!= undefined){
docCopy(latestFileId, targetFile);
}
}
}
// Log the id of the latest file with a particular name in the folder.
function mostRecentFiIeInFolder(folderId, fileName) {
var folder = DriveApp.getFolderById(folderId);
Logger.log(folder);
var files = DriveApp.getFilesByName(fileName);
Logger.log(fileName);
var result = [];
// Checks whether the given file is in the folder or not
if(!files.hasNext()){
Logger.log('No such file in the folder with the given name');
}
else{
while (files.hasNext()) {
var file = files.next();
result.push([file.getDateCreated(), file.getId()]);
}
Logger.log('************All the file ids with the same file name and their dates created************');
Logger.log(result);
result.sort(function (x, y){
var xp = x[0];// get first element in inner array
var yp = y[0];
return xp == yp ? 0 : xp > yp ? -1 : 1;// choose the sort order, here its in descending order of created date
});
var id = result[0][1];
Logger.log(id);
return id;
}
}
// Copy the contents of the latest file in the target file.
function docCopy(dociIdSource, docIdTarget){
Logger.log('The file with id: ' + dociIdSource + ' will be copied to the target id: ' + docIdTarget);
var docID = docIdTarget;
var baseDoc = DocumentApp.openById(docID); //Service unavailable: Docs error is thrown for this line of code
var body = baseDoc.getBody();
var otherBody = DocumentApp.openById(dociIdSource).getBody();
var totalElements = otherBody.getNumChildren();
for( var j = 0; j < totalElements; ++j ) {
var element = otherBody.getChild(j).copy();
var type = element.getType();
if( type == DocumentApp.ElementType.PARAGRAPH )
body.appendParagraph(element);
else if( type == DocumentApp.ElementType.TABLE )
body.appendTable(element);
else if( type == DocumentApp.ElementType.LIST_ITEM )
body.appendListItem(element);
else if( type == DocumentApp.ElementType.INLINE_IMAGE )
body.appendImage(element);
else if( type == DocumentApp.ElementType.TEXT )
body.setText(element);
else
throw new Error("According to the doc this type couldn't appear in the body: " + type);
}
}
Note that your mostRecentFiIeInFolder function never actually uses the folder, and doesn't ever check that the files are of the correct type - i.e., are actually Google Docs files. Thus if your searched name should have found nothing (i.e. there is no recent file with that name in your target folder), but you had some alternate file elsewhere in your Drive, one that is not a Google Docs file, your script will find it and treat it as something it is not.
The solution is to restrict your search to your desired folder, and again by actual Google Docs mimetype:
function testIt() {
var folderIds = [
"", // Search all of Drive
"123428349djf8234", // Search that specific folder
];
// Log (in Stackdriver) the file id of the most recently created Google Docs file with the name "some name" in the various folders:
folderIds.forEach(function (folderId) {
console.log(getMostRecentFileIdWithName("some name", folderId, MimeType.GOOGLE_DOCS));
});
}
function getMostRecentFileIdWithName(fileName, folderId = "", mimeType = "") {
// If a folder was given, restrict the search to that folder. Otherwise, search with
// DriveApp. (Throws an error if the folderId is invalid.)
var parent = folderId ? DriveApp.getFolderById(folderId) : DriveApp;
// I assume your fileName variable does not contain any unescaped single-quotes.
var params = "name='" + fileName + "'";
// If a mimetype was given, search by that type only, otherwise search any type.
if (mimeType)
params += " and mimeType='" + mimeType + "'";
var matches = parent.searchFiles(params),
results = [];
// Collect and report results.
while (matches.hasNext())
results.push(matches.next());
if (!results.length)
throw new Error("Bad search query \"" + params + "\" for folder id = '" + folderId + "'.");
// Sort descending by the creation date (a native Date object).
// (a - b sorts ascending by first column).
results.sort(function (a, b) { return b.getDateCreated() - a.getDateCreated(); });
return results[0].getId();
}
You can read more about the acceptable search parameters in the Drive REST API documentation, and more about the Apps Script native implementation in the DriveApp documentation.

Skip processing .xls to Google Sheets script if the file already exists in Google Drive

I am currently using this code to automatically convert all uploaded .xls files in Google Drive to Google Sheets.
function importXLS(){
var files = DriveApp.searchFiles('title contains ".xls"');
while(files.hasNext()){
var xFile = files.next();
var name = xFile.getName();
if (name.indexOf('.xls')>-1){
var ID = xFile.getId();
var xBlob = xFile.getBlob();
var newFile = { title : name,
key : ID,
'parents':[{"id":"12FcKokB-ppW7rSBtAIG96uoBOJtTlNDT"}]
}
file = Drive.Files.insert(newFile, xBlob, {
convert: true
});
}
}
}
It works perfectly, but fails if there is already a file in the output folder with the same name. Even though I never technically get to see this error below (since it runs on a schedule and not fired manually like in the screenshot), I would prefer to simply skip the conversion process if the file already exists.
If possible, I would also like to avoid overwriting it each time, as I feel that would be a waste of processing time. How would I edit this code to say that if the file name already exists in that folder, skip the entire code completely?
Thanks!
Two things you can try:
Get the files names that are already in the destination folder and check if the file exists before you try copying.
Wrap the section of your code that does the copying in a try..catch statement.
Both of these should work independently, but using the try..catch statement will catch all errors, so it would be best to combine them. (You can review the error logs in the Developer Console.) Doing this you'll be able to skip files that have the same name as those already in your destination folder and any other error that might come up will not terminate your script from completing.
function importXLS(){
var files = DriveApp.searchFiles('title contains ".xls"');
var destinationFolderId = "12FcKokB-ppW7rSBtAIG96uoBOJtTlNDT";
var existingFileNames = getFilesInFolder(destinationFolderId);
while(files.hasNext()){
var xFile = files.next();
var name = xFile.getName();
try {
if (!existingFileNames[name] && (name.indexOf('.xls')>-1)) {
var ID = xFile.getId();
var xBlob = xFile.getBlob();
var newFile = { title : name,
key : ID,
'parents':[{"id": destinationFolderId}]
}
file = Drive.Files.insert(newFile, xBlob, {
convert: true
});
}
} catch (error) {
console.error("Error with file " + name + ": " + error);
}
}
}
/**
* Get an object of all file names in the specified folder.
* #param {string} folderId
* #returns {Object} files - {filename: true}
*/
function getFilesInFolder(folderId) {
var folder = DriveApp.getFolderById(folderId);
var filesIterator = folder.getFiles();
var files = {};
while (filesIterator.hasNext()) {
var file = filesIterator.next();
files[file.getName()] = true;
}
return files;
}