So here is my problem, I have a script for copying a bunch of independent one sheet google spreadsheets into one master spreadsheet as tabs, but because I'm using "title contains" it creates sheets (tabs) for non existent spreadsheets (in the example below: it will make "ADC Lunch" even though that sheet doesn't exist). I have about 50 of these in a script, what is the best way to ensure that only the sheets that have actual spreadsheet files correspondent to their name exist in my master spreadsheet? I was thinking maybe a "if then" like IF(ID=true, sheet.copyTo(destination).setName("ADC Breakfast")) but I don't have much experience in api script yet so I don't know how to formulate it around this function. Any help would be appreciated, thank you.
Illustration:
"Spreadsheet 1"
"Spreadsheet 2" --> compiled --> Master Spreadsheet (with 3 sheets)
"Spreadsheet 3"
Problem:
Master Spreadsheet searches for Spreadsheet X by "title contains" search, if it doesn't find one of the spreadsheets with the specific requirements, it just copies another spreadsheet that is close enough into the master spreadsheet as Spreadsheet X. How can I make it so it will only copy a spreadsheet to the master spreadsheet (as a tab) if it actually exists and fulfills the "title contains" parameters? I hope this clarifies things, sorry for my poor description.
function ArrayBuilder() {
var filesource = DriveApp.searchFiles('title contains "ADC Breakfast" and parents in "File_ID"');
while(filesource.hasNext()){
var File = filesource.next();
var ID = File.getId();
}
var name = File.getName()
var source = SpreadsheetApp.openById(ID);
var sheet = source.getSheets()[0];
var destinationID = "File_ID";
var destination = SpreadsheetApp.openById(destinationID);
sheet.copyTo(destination).setName("ADC Breakfast");
Finding Spreadsheets that have only one sheet
I know this isn't the answer to your question but perhaps it will help you think about it another way. This function finds Spreadsheets that only have 1 sheet and it appends the file name, file id and sheet name to a spreadsheet. It also adds an extension to the file name like (n) where n is an integer indicating how many files have had that name. With the information in the spreadsheet you could probably figure out which ones you would like to copy into your master spreadsheet or if you wish assistance in modifying it please let me know.
function findSpreadsheetsWithOnlyOneSheet() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('File Data Sheet');
var nA=[];
var nObj={};
var files=DriveApp.getFolderById('Folder Id').getFilesByType(MimeType.GOOGLE_SHEETS);
while(files.hasNext()) {
var file=files.next();
var id=file.getId();
var name=file.getName();
if(Sheets.Spreadsheets.get(id).sheets.length==1) {
var sheetname=Sheets.Spreadsheets.get(file.getId()).sheets[0].properties.title;
if(nA) {
if(nA.indexOf(name)==-1) {
nA.push(name);
sh.appendRow([name,id,sheetname]);
}else{
if(nObj.hasOwnProperty(name)) {
nObj[name]+=1;
}else{
nObj[name]=1;
}
sh.appendRow([name + '(' + nObj[name] + ')',id,sheetname])
}
}else{
sh.appendRow([name,id,sheetname]);
}
}
}
}
This is what my spreadsheet looks like:
Sheets API version 4
DriveApp Class
Related
im new to this and have been looking every where how to do this:
Create new Google Spread Sheet.
Open new Google Spread Sheet.
Add code to new Google Spread Sheet.
Ive seen this code, but dont really understand it much. Can somebody explain or help me with this task?
var files = DriveApp.searchFiles(
'starred = true and mimeType = "' + MimeType.GOOGLE_SHEETS + '"');
while (files.hasNext()) {
var spreadsheet = SpreadsheetApp.open(files.next());
var sheet = spreadsheet.getSheets()[0];
Logger.log(sheet.getName());
Would duplicating a blank spreadsheet that already has App Script code attached to it work in your situation?
Steps Needed:
Create a blank Spreadsheet.
Add your code to the blank Spreadsheet.
Use the following code to make a copy of the blank spreadsheet. The App Script file will also be on the newly copied file.
To make a copy of the blank Spreadsheet, use this:
function copySpreadsheet() {
var templateSpreadsheetID = [Enter the Spreadsheet ID]
var newSheetName = [Enter the name you want the copied Spreadsheet to be]
var newSheet = SpreadsheetApp.openById(templateSpreadsheetID).copy(newSheetName)
console.log(newSheet.getUrl())
}
Notes:
You'll need to replace [Enter the Spreadsheet ID] with the Spreadsheet ID from the blank sheet you created in Step 1
You'll need to replace [Enter the name you want the copied Spreadsheet to be] with what ever name the new copied spreadsheet should be. It's optional, so you could remove it.
If you'd like to do further actions to the spreadsheet after it has been duplicated, you can use the newSheet variable to run your sheet actions
Can somebody explain or help me with this task?
The code you shared is a script that extract the first sheet name of each starred Spreadsheet.
//Returns all the starred files that are a Google Sheet file type:
var files = DriveApp.searchFiles('starred = true and mimeType = "' + MimeType.GOOGLE_SHEETS + '"');
//Loops through all of the files that were returned:
while (files.hasNext()) {
//Opens the current sheet from the loop
var spreadsheet = SpreadsheetApp.open(files.next());
//Returns the first sheet from the spreadsheet (position 0)
var sheet = spreadsheet.getSheets()[0];
//Logs the sheet name
Logger.log(sheet.getName());
}
I've been reading this without making any headway:
https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet-app
Is there a way to programmatically get the Spreadsheet ID and Sheet ID of a particular Google SpreadSheet's sheet without manually typing or copying the URL?
1.) If the script is bound to the spreadsheet then you can just use getID and getSheetID as mentioned by TheMaster in the comments. See codes below:
function getIDs() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var spreadSheetID = ss.getId();
var sheetID = sheet.getSheetId();
console.log(spreadSheetID);
console.log(sheetID);
}
Result:
Take note that the first sheet always has an ID of 0 (gid=0) as the default value.
2.) Otherwise if what you are trying to do is get the Spreadsheet ID and Sheet ID from different spreadsheets it is not possible without copying the URL since there is no way it can identify which spreadsheet to refer to.
3.) Suggestion
What you can do if you need to get IDs of different files is to move them to a folder in your drive, then you can use the code below:
function listFilesInFolder(folderName) {
var sheet = SpreadsheetApp.getActiveSheet();
sheet.getRange(1,1,sheet.getLastRow(),sheet.getLastColumn()).clearContent();
sheet.appendRow(["Name", "Spreadsheet ID", "Sheet ID"]);
//change the folder ID below to reflect your folder's ID (look in the URL when you're in your folder)
var folder = DriveApp.getFolderById("HIS_SHOULD_BE_YOUR_FOLDER_ID");
var contents = folder.getFiles();
var cnt = 0;
var file;
while (contents.hasNext()) {
var file = contents.next();
cnt++;
data = [
file.getName(),
file.getId(),
];
var spreadsheetSheets = SpreadsheetApp.openById(data[1]).getSheetByName("Sheet2").getSheetId();
data.push(spreadsheetSheets);
sheet.appendRow(data);
};
};
Folder:
Result:
Note: In my example code I've made use of Sheet2 to see that it is working as expected. Please set accordingly to the name of the sheet which you are trying to get the ID.
Let me know if this works for you or if you have other questions.
References:
Are Google Spreadsheets' first sheets always given an ID of 0?
Getting all files ID in drive folder
I have many spreadsheets inside a folder and today I have developed a new sheet (tab) inside one of these spreadsheets. I have a code to copy and paste one sheet to another spreadsheet, but for this there is another way without code.
My goal is:
a way to copy one sheet (order number 13) to all other spreadsheets at the same folder.
This is my code for copying one-to-one:
function sendspreadsheet(){
var source = SpreadsheetApp.getActiveSpreadsheet();
var aba = source.getSheets()[13];
var destination = SpreadsheetApp.openByUrl('https:sheetID');
aba.copyTo(destination);}
I have a great help from #Tanaike about similar issue at post: "Array for Google Sheet celarcontet" and I have studied this code and Google Class Sheet, but something is not working.
Code I'm trying to copy one-to-multiple spreadsheets at the same folder:
Function sendtomultiple(){
var source = SpreadsheetApp.getActiveSpreadsheet();
var aba = source.getSheets()[13];
var destination = DriveApp.getFolderById('1o6p-53Q1ntJAVIJt9w4k0UK___XXXXXX');
var sheetDestino = destination.getFilesByType(MimeType.GOOGLE_SHEETS);
while (sheetDestino.hasNext()) {
SpreadsheetApp.open(sheetDestino.next()).getSheets().forEach(aba => {
aba.copyTo(sheetDestino);
});
};
}
I guess this line into while instruction is the problem, I have tried other options, but all them return error message, kind this:
Exception: The parameters (DriveApp.FileIterator) don't match the method signature for SpreadsheetApp.Sheet.copyTo.
Hope someone can help to fix this.
Explanation / Issue:
Your goal is to copy a particular sheet (tab) into multiple spreadsheets within the same folder.
The issue has do to with the fact that sheetDestino.next() is a file object but copyTo(spreadsheet) accepts a spreadsheet object.
You can get the id of the file and then use openById(id) to get the spreadsheet object which you can use to copy the sheet to.
Bonus code:
I added an if condition to make sure the code does not try to copy the sheet to the origin spreadsheet file.
I added a code to rename the copied sheet to the destination sheet to the original name. The default would be copy of Sheet14...
Solution:
function sendtomultiple(){
const source = SpreadsheetApp.getActiveSpreadsheet();
const source_id = source.getId();
const aba = source.getSheets()[13];
const destination = DriveApp.getFolderById('1o6p-53Q1ntJAVIJt9w4k0UK___XXXXXX');
const sheetDestino = destination.getFilesByType(MimeType.GOOGLE_SHEETS);
while (sheetDestino.hasNext()) {
let target_file = sheetDestino.next();
let target_id = target_file.getId();
let target_ss = SpreadsheetApp.openById(target_id);
if(target_id!=source_id){
aba.copyTo(target_ss).setName(aba.getName());
}
};
}
Keep in mind that sheet getSheets()[13] is the 14th sheet in the spreadsheet file. If you want to get the 13th sheet you need to use getSheets()[12].
My objective here is to let multiple users change the file at the same time without disrupting others. I think that the offline mode is the answer. That's why I'm searching for a way to turn on the offline mode editing when a user opens it.
Maybe offline mode is not the most efficient way, I'm open to all suggestions.
What you can do instead is copy the sheet and let them work on the duplicated sheet. Use the code below.
Code:
function openDuplicatedSheet() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var spreadsheetName = spreadsheet.getName();
// Duplicated file id
var fileId = SpreadsheetApp.create("Copy of " + spreadsheetName).getId();
var destination = SpreadsheetApp.openById(fileId);
// Rename sheet so it won't be duplicated
destination.renameActiveSheet("temp-sheet-to-be-removed-later)");
var sheets = spreadsheet.getSheets();
// Copy the sheets excluding the script so it won't duplicate infinitely
sheets.forEach(function (sheet, index) {
sheet.copyTo(destination);
// Use sheet name from the original sheet
var sheetName = sheet.getSheetName();
destination.getSheets()[index + 1].activate();
destination.renameActiveSheet(sheetName);
});
// Remove default Sheet1 which was renamed earlier to avoid duplication of sheet name
destination.deleteSheet(destination.getSheets()[0]);
var htmlOutput = HtmlService
.createHtmlOutput('' + spreadsheetName + '')
.setWidth(350)
.setHeight(50);
SpreadsheetApp.getUi().showModalDialog(htmlOutput, 'Click to open duplicated sheet');
}
Trigger:
Prompt upon opening:
Output:
This will create a duplicate/copy of the content of the file (excluding the script) and should be accessible to their own drives.
Note:
There is a little delay with the pop window. Just wait for it to show up.
Use the duplicated file to avoid multiple duplicates of the original file.
The duplicated file won't further duplicate as its script was not included in the copy.
Reference:
duplicate spreadsheet
How to divide a google spreadsheet (with about 100 sheets) in two (or more) spreadsheets (of about 50 sheets each) in google-apps-script ?
Alas, due to a google bug (see https://productforums.google.com/d/topic/docs/H2ZakBguOgk/discussion), I can't copy the entire spreadsheet file and delete some sheets in each spreadsheets.
I can only copy sheets one by one on another spreadsheet, then delete the original sheet(s) if copy is a success.
Thanks in advance ;)
Here is a code snippet that should do what you want, I didn't test it so maybe you'll have to tweak some details but the general idea is there...
EDIT : I tested and made the corrections to make it work... sorry for the typos in first version
function splitSS() {
var oldFileID = 'original ss Id'
var newFile = DocsList.getFileById(oldFileID).makeCopy()
var newFileID = newFile.getId()
var ss = SpreadsheetApp.openById(newFileID);
Logger.log(ss.getNumSheets())
var todel = parseInt((ss.getNumSheets())/2);
Logger.log(todel)
var tokeep = ss.getNumSheets()-todel
Logger.log(tokeep)
for (pa=ss.getNumSheets()-1;pa>tokeep;--pa){
ss.setActiveSheet(ss.getSheets()[pa]);
var delsheet = ss.deleteActiveSheet(); // delete sheets begining with the last one
Utilities.sleep(400);
}
var ssold = SpreadsheetApp.openById(oldFileID);
for (pa=todel;pa>1;--pa){
ssold.setActiveSheet(ssold.getSheets()[pa]);
var delsheet = ssold.deleteActiveSheet(); // delete sheets begining with the last one
Utilities.sleep(400);
}
}