Can I use IMPORTRANGE on a Google Drive folder? - google-apps-script

This code works for me if I am importing two sheets:
={IMPORTRANGE("Sheet1Key","SheetName!A2:A500");IMPORTRANGE("Sheet2Key","SheetName!A2:A500")}
However, I have multiple sheets, all in the same folder, all with the data in the first sheet and all with the data in the same cells.
Is it possible to somehow either import from a folder or somehow add the IDs or names of all files within that folder automatically?

I am not sure what you mean by import all the files within that folder automatically. But what you could do is use the following code that I made a while ago. (You need to make it under scripts.google.com and you need to run the code)
The only thing you would need to change is the folder name where I wrote “type name of folder”
function listFolderContents() {
var foldername = 'type name of folder';
var folderlisting = 'URL listing for folder ' + foldername;
var folders = DriveApp.getFoldersByName(foldername)
var folder = folders.next();
var contents = folder.getFiles();
var ss = SpreadsheetApp.create(folderlisting);
var sheet = ss.getActiveSheet();
sheet.appendRow( ['name', 'link'] );
var file;
var name;
var link;
var row;
while(contents.hasNext()) {
file = contents.next();
name = file.getName();
link = file.getUrl();
sheet.appendRow( [name, link] );
}
};
It will create a google spreadsheet called “URL listing for folder (name of folder) located inside the folder you are trying to get the files for. The spreadsheet will contain an array of all the file URL’s. It should be relatively easier to create the import range given the URL’s. You may be able to pick my code apart and use parts that help you with your goal. Hope this helps.

You just need to use an array:
=query(arrayformula({importrange(sheet1!A1:Z100);importrange(sheet2!A1:Z100)}), "SELECT *",1)
This does assume that all data is structured the same.

Related

Google Script Question: Is there a way to create copies of files into multiple folders at once?

I have a spreadsheet from which I've written code to populate with the names of folders (column 1) and their IDs (column 2).
I would like to populate each of the folders listed in that spreadsheet with a copy of each of the documents contained a separate folder (a Shared Drive folder, if that matters). When I execute the code below, a copy of each document is created in the source folder (the Shared Drive folder) instead of in the destination folder (aka the folders whose IDs are captured in the spreadsheet). If it matters, each copy is labelled with a folderID from the spreadsheet. Can someone please tell me how I can get this code to create the copies inside the appropriate destination folders instead of in the source folder?
function CopiestoFolder() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var data = ss.getDataRange() //Get all non-blank cells
.getValues() //Get array of values
.splice(1); //Remove header line
//Define column numbers for data. Array starts at 0.
var NAME = 0;
var FOLDERID = 1;
//For each folder ID listed in spreadsheet, create a copy of
//each item in the Resume Resources folder.
for (var i = 0; i < data.length; i++) {
var name = data[i][NAME];
var folderId = data[i][FOLDERID];
var srcFolder = DriveApp.getFolderById("folder ID");
var dstFolder = folderId;
var files = srcFolder.getFiles();
while (files.hasNext()) {
var file = files.next();
var f = file.makeCopy(dstFolder);
if (file.getMimeType() == MimeType.GOOGLE_APPS_SCRIPT) {
dstFolder.addFile(file);
f.getParents().next().removeFile(file);
}
}
}
}
I had this problem with Script Files. Here's how I fixed. Or I should say here's how Tanaike fixed it. You will need to enable Drive API.
var res=file.makeCopy(copyName,subFldr);
if (file.getMimeType() == MimeType.GOOGLE_APPS_SCRIPT) {
Drive.Files.update({"parents": [{"id": subFldr.getId()}]}, res.getId(), null, {"supportsTeamDrives":true}); // Added
}
The file.makeCopy() method has 3 overloads:
//Accepts no parameters
file.makeCopy();
//Accepts a name parameter as a string
file.makeCopy(name);
//Accepts a destination parameter as an instance of a Folder class
file.makeCopy(destination);
//Accepts 2 parameters, the first of which is name (String) and the second one is destination (Folder).
file.makeCopy(name, destination);
You are trying to pass folder id instead of the actual folder, which gets interpreted as a folder name (not destination). Also, the following code means that your 'dstFolder' parameter is a string but you try to call the 'addFile()' method on it:
var folderId = data[i][FOLDERID];
var dstFolder = folderId;
dstFolder.addFile(file);
If you want to copy a file to another folder via makeCopy, you should pass a Folder as a parameter, not a folder id (a string). If you provide a string (your id) as a parameter, the script will interpret this id as the name you want the copied file to have. So you should first get the Folder out of its id, via getFolderById(id). So you should change this line:
var dstFolder = folderId;
To this one:
var dstFolder = DriveApp.getFolderById(folderId);
You are making a copy of the file before checking if the file is a Google Apps Script project. I assume you just want GAS projects to be copied, so this should be included inside the if block. Also, inside the if block you are using addFile which can also be used to copy a file to another folder (it adds the file to the desired folder). So you don't need to use both functions, they are doing basically the same (copying your file to the desired folder).
You are using removeFile, which is not necessary if you want to keep the original files in the original folders.
So the while block could be something like:
while (files.hasNext()) {
var file = files.next();
if (file.getMimeType() == MimeType.GOOGLE_APPS_SCRIPT) {
dstFolder.addFile(file);
}
}
Finally, your full code could be like:
function CopiestoFolder() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var data = ss.getDataRange() //Get all non-blank cells
.getValues() //Get array of values
.splice(1); //Remove header line
//Define column numbers for data. Array starts at 0.
var NAME = 0;
var FOLDERID = 1;
//For each folder ID listed in spreadsheet, create a copy of
//each item in the Resume Resources folder.
for (var i=0; i<data.length; i++) {
var name = data[i][NAME];
var folderId = data[i][FOLDERID];
var srcFolder = DriveApp.getFolderById("folder ID");
var dstFolder = DriveApp.getFolderById(folderId);
var files = srcFolder.getFiles();
while (files.hasNext()) {
var file = files.next();
if (file.getMimeType() == MimeType.GOOGLE_APPS_SCRIPT) {
dstFolder.addFile(file);
}
}
}
}
I hope this is of any help.

How to create a file in the active Directory

The problem I have is that the file is created in the root and I cannot find the right instruction to change to a named directory!
// Create a new Spreadsheet and copy the current sheet into it.
var newSpreadsheet = SpreadsheetApp.create( invNo );
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
invtoSend.copyTo(newSpreadsheet);
just create the spreadSheet, get its ID and then use DriveApp to move it (and to remove it from root otherwise it will be available in both !)
var newSpreadsheet = SpreadsheetApp.create( invNo );
var file = DriveApp.getFileById(newSpreadsheet.getId());
DriveApp.getFolderById('0B3°°°°°°°1lXWkk').addFile( file );
DriveApp.getRootFolder().removeFile(file);
EDIT
I reallize that your question can be understood differently : you might want that the destination folder would be the "current spreadsheet" folder, in this case here is the appropriate code :
function xxxx(){
var newSpreadsheet = SpreadsheetApp.create( "invNo" );
var file = DriveApp.getFileById(newSpreadsheet.getId());
var folders = DriveApp.getFileById(SpreadsheetApp.getActiveSpreadsheet().getId()).getParents();
while(folders.hasNext()){ // a file might be in multiple folders, include it in all of them except root
var folder = folders.next();
if(folder.getName()!=DriveApp.getRootFolder().getName()){ // root folder name changes with user's locale
folder.addFile(file);
DriveApp.getRootFolder().removeFile(file);
Logger.log('destination folder name = '+folder.getName());
}
}
}

Searching for file by name within a folder in google Drive using google scripts

In Google Drive I'm trying to search for a file in the current directory. The script is linked to a spreadsheet, so it finds the spreadsheet's parent directory, then uses its id to specify a search within the folder for a file named Title.
The code I have so far is:
function searchFolder(){
//get current folder id
var ss = SpreadsheetApp.getActive(); //current spreadsheet
var directParents = DriveApp.getFileById(ss.getId()).getParents();
while( directParents.hasNext() ) {
var folder = directParents.next();
var folderId = folder.getId();
Logger.log(folder.getName() + " has id " + folderId);
}
//get files in folder
var parent = DriveApp.getFolderById(folderId); // folder Id
var search = 'name contains "Title"';
var specificFolder = parent.searchFiles(search);
while (specificFolder.hasNext()) {
var file = specificFolder.next();
Logger.log(file.getName());
Logger.log(file.getId());
}
}
I get the error "Invalid argument: query" at the beginning of the while loop, which suggests that no files were found.
This error seems to only occur when I search by name. If I change the search variable to 'fullText contains "hello"' (the file Title has 'hello' in it) then there are no problems. What can be done to make the search by name work?
To replicate the error, make two spreadsheets in a folder on google drive. One spreadsheet has the script linked to it, the other is named "Title" and is being searched. Thanks.
As Srikanth pointed, it is title contains not name contains. The code could be made simpler, please try the following code. You don't need a spreadhseet for this, just use simple Google Apps Script project file. Right click on empty space of your Drive ---> More ---> Google Apps Script
function SearchFiles() {
//Please enter your search term in the place of Letter
var searchFor ='title contains "Letter"';
var names =[];
var fileIds=[];
var files = DriveApp.searchFiles(searchFor);
while (files.hasNext()) {
var file = files.next();
var fileId = file.getId();// To get FileId of the file
fileIds.push(fileId);
var name = file.getName();
names.push(name);
}
for (var i=0;i<names.length;i++){
Logger.log(names[i]);
Logger.log("https://drive.google.com/uc?export=download&id=" + fileIds[i]);
}
}
Also check these links:
1) Search all documents in a folder
2)Search Drive Files

How to Create a Spreadsheet in a particular folder via App Script

Can anybody help me out,
I want to create a Spreadsheet through App Script in a particular folder. How to do that.
Presently I am doing as follow:
var folder = DocsList.getFolder("MyFolder");
var sheet = SpreadsheetApp.create("MySheet");
var file = DocsList.getFileById(sheet.getId());
file.addToFolder(folder);
file.removeFromFolder(file.getParents()[0]);
It is not working.......
As suggested by #Joshua, it's possible to create a Spreadsheet (in a specific folder) with the Advanced Drive Service (you'll need to activate this if you haven't already, by going into Services +, find Drive API and click Add).
var name = 'your-spreadsheet-name'
var folderId = 'your-folder-id'
var resource = {
title: name,
mimeType: MimeType.GOOGLE_SHEETS,
parents: [{ id: folderId }]
}
var fileJson = Drive.Files.insert(resource)
var fileId = fileJson.id
No need to move files around with this method !
folder = DriveApp.getFolderById("FOLDER_ID")
var ss = SpreadsheetApp.create("SPREADSHEET_NAME")
DriveApp.getFileById(ss.getId()).moveTo(folder);
You may use the above code to achieve the same without using advanced drive services
Since you can no longer create Google Docs (Docs or SpreadSheets) using DriveApp, nor use addToFolder because DocList is deprecated. There is only one way to create or "move" Google Docs or Google SpreadSheets..
//"Move" file to folder-------------------------------//
var fileID = '12123123213321'
var folderID = '21321312312'
var file = DriveApp.getFileById(fileID).getName()
var folder = DriveApp.getFolderById(folderID)
var newFile = file.makeCopy(file, folder)
//Remove file from root folder--------------------------------//
DriveApp.getFileById(fileID).setTrashed(true)
As you can see this DOES NOT move the file, it makes a copy with the same name in the folder you want and then moves the original file to the trash. I'm pretty sure there is no other way to do this.
The other answer is a bit short (and not very explicit).
While your approach is logic and should work if you replace
file.removeFromFolder(file.getParents()[0]);
with
file.removeFromFolder(DocsList.getRootFolder());
there is a better way to do the same job using the new Drive app and the Folder Class, Folder has a method to create a file and you can specify the file type using the mimeType enum.
Code goes like this :
function myFunction() {
var folders = DriveApp.getFoldersByName('YOUR FOLDER NAME'); // replace by the right folder name, assuming there is only one folder with this name
while (folders.hasNext()) {
var folder = folders.next();
}
folder.createFile('new Spreadsheet', '', MimeType.GOOGLE_SHEETS); // this creates the spreadsheet directly in the chosen folder
}
In July 27, 2020 there have been these updates:
The File class now has the following methods:
file.getTargetId(): Gets a shortcut's file ID.
file.getTargetMimeType(): Returns the mime type of the item a shortcut points to.
file.moveTo(destination): Moves a file to a specified destination folder.
The Folder class now has the following methods:
folder.createShortcut(targetId): Creates a shortcut to the provided Drive item ID, and returns it.
folder.moveTo(destination): Moves an item to the provided destination folder.
The following Folder class methods have been deprecated:
addFile(File)
addFolder(Folder)
removeFile(File)
removeFolder(Folder)
https://developers.google.com/apps-script/releases/#july_27_2020
So you can create a Spreadsheet file in a folder using file.moveTo(destination) method:
function createSpreadSheetInFolder(ss_new_name, folder_dest_id) {
var ss_new = SpreadsheetApp.create(ss_new_name);
var ss_new_id = ss_new.getId();
var newfile = DriveApp.getFileById(ss_new_id);
newfile.moveTo(DriveApp.getFolderById(folder_dest_id))
return ss_new_id;
}
var file_name = 'SPREADSHEET NAME';
var folder_id = 'DESTINATION FOLDER ID';
var new_ssId = createSpreadSheetInFolder(file_name, folder_id)
You can create a spreadSheet and then add it to the folder.
function createSpreadSheetInFolder(name,folder){
var ss = SpreadsheetApp.create(name);
var id = ss.getId();
var file = DriveApp.getFileById(id);
folder.addFile(file);
return ss;
}
folderId='your_folder_id'
name='my_new_ss'
folder=DriveApp.getFolderById(folderId)
createSpreadSheetInFolder(name,folder)
By using the folder.addFile method there's no need to use a temp file (no need to duplicate and remove file). Pretty straightforward !
I finally got the answer to my question. The following works
var file = DocsList.getFileById(sheet.getId());
var folder = DocsList.getFolder("MyFolder");
file.addToFolder(folder);
// remove document from the root folder
folder = DocsList.getRootFolder();
file.removeFromFolder(folder);
What is not working? Use getRootFolder in the last line.
Creating a new spreadsheet in a file can be done using this link as a reference.
createFile(name, content, mimeType)
Therefore using the enum MimeType we can do:
var folder = DriveApp.getFolderById("your-folder-id");
folder.createFile("My File Name","",MimeType.GOOGLE_SHEETS)

How can I pull information from spreadsheets in multiple folders in google script?

I already have a script which references all documents in ONE folder, but I need to reference multiple folders...
Script that works for one folder is:
var folder = DocsList.getFolder("My Spreadsheets");
var contents = folder.getFiles();
What I WANT to do is either
var masterfolder = DocsList.getFolder("My Folder that has multiple folders");
var folder = DocsList.getFolders(masterfolder)
var contents = folder.getFiles();
or
var folder = DocsList.getFolder("My Spreadsheets", "My Other Spreadsheets");
var contents = folder.getFiles();
I am quite newbye in this, but I think you'll have to do an iteration throught the subfolders:
var folder = DocsList.getFolders(masterfolder)
Here you dont't get one single folder; you get a set of them and you have to iterate trhout it with a for bucle. Something like:
for f in folders {
f.getfiles......
...
}
SURE you will get more precise answer.
Enrique