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
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 have one original spreadsheet. Whenever a user opens that spreadsheet it should give a separate copy of the original spreadsheet for each of them to edit so that they should not edit the original copy. if two users are using the same spreadsheet then 2 separate copies of the original spreadsheet should be generated according to the user. When they click on the original spreadsheet link it should redirect to his created copy of the spreadsheet link for them to edit. If that user already created a copy there then it should open a copy spreadsheet instead of creating a copy again. Is it possible through the app's script ? . Or any alternate solution is there for this.
and also when i am doing makecopy() in app script and running in applescript editor it will make copy and give new spreadsheet but when same thing i'm writing in onOpen() .it will give error that:
Exception: You do not have permission to call DriveApp.getFileById. Required permissions: (https://www.googleapis.com/auth/drive.readonly || https://www.googleapis.com/auth/drive)
at onOpen(Code:10:25)
mycode:
function onOpen (e) {
var Book = SpreadsheetApp.openById('1nGz4FAOYg5yRe6HTd8RZZ0dzuy1HimyyhfyquDMZMpQ');
var user = Session.getEffectiveUser().getUsername();
var name = Book.getName()+ user + " Copy ";
var newfile = DriveApp.getFileById(Book.getId()).makeCopy(name);
var newSpreadsheet = SpreadsheetApp.open(newfile);
var useremail=Session.getActiveUser().getEmail()
//newSpreadsheet.addEditors(["sanath#gmail.com"]);
console.log(newSpreadsheet.getUrl())
var href=newSpreadsheet.getUrl();
var html = "<script>window.open('" + href + "');google.script.host.close();</script>";
var userInterface = HtmlService.createHtmlOutput(html);
SpreadsheetApp.getUi().showModalDialog(userInterface, 'Open Tab');
need some help here. I have a master google sheet(Master Trix) that has several tabs.
Most of them contains private information, so i have to import a specific tab("Numbers") to another specific tab("Test")of another spreadsheet("Destination Source") that is for public view so that i can share it on google site. Edits will be made often on the master trix's tab("Numbers") and has to be reflected upon edit on tab("Test")of another spreadsheet("Destination Source")
I have tried importrange but it only copy the values to a destination tab of another spreadsheet.
Problem 1: The source tab has several links, images and formatting that i would need it on the destination. Problem 2: My management will update the master source tab and would like the destination to be updated automatically as well, with all formatting and links attached. I understand that google app script might be able to help.
I have tried the following:
function copytabtodestination() {
var source = SpreadsheetApp.getActiveSpreadsheet();
var sheet = source.getSheets()[0];
var destination = SpreadsheetApp.openById("1dKMZhXlCeoaP92kmAlFUq1NgYo38fK_HryCfJ8jBzZ8");
sheet.copyTo(destination);
}
But it creates a new tab that states "copy of Sample: Restriction Updates" . - Not the specific tab("Numbers") that is supposed to be reflected.Is there any way i can get it reflected in the "test" tab instead and changes will be updated upon edits?
Master trix: https://docs.google.com/spreadsheets/d/1Uhcq-dztXqZH9hEbF1-Ho7Wr5IQ1yTp3-VDVW5D-bpc/
Destination Source: https://docs.google.com/spreadsheets/d/1dKMZhXlCeoaP92kmAlFUq1NgYo38fK_HryCfJ8jBzZ8/
Thanks a million.
Copy Sheet Numbers to another Spreadsheet and Name it Numbers
function copyto() {
const dssid = "1dKMZhXlCeoaP92kmAlFUq1NgYo38fK_HryCfJ8jBzZ8";
const ss = SpreadsheetApp.getActive()
const sssid = ss.getId();
const sh = ss.getSheetByName('Numbers');//you can change this to another name if you wish to replace another sheet
const sshid = sh.getSheetId();
const options = {"method": "post","headers": { "Authorization": "Bearer " + ScriptApp.getOAuthToken() },"payload":{ "destinationSpreadsheetId": "" + dssid }};
const url = `https://sheets.googleapis.com/v4/spreadsheets/${sssid}/sheets/${sshid}:copyTo`;
let r = UrlFetchApp.fetch(url,options);
let title = JSON.parse(r.getContentText()).title;
const dss = SpreadsheetApp.openById(dssid);
let s = dss.getSheetByName(sh.getName());
if(s)dss.deleteSheet(s);//deletes old numbers if present
dss.getSheetByName(title).setName(sh.getName());//rename sheet to original sheet name
}
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].
I recently wrote my first Google Apps script that makes a copy of a spreadsheet (including all tabs within that spreadsheet) and places it into a specific folder in the user's Drive. The copy is renamed based on a cell value in the original spreadsheet. Here is my script, for reference:
function copyDocument() {
var ss = SpreadsheetApp.getActiveSpreadsheet(); // Get current active spreadsheet.
var id = ss.getId(); // Get current active spreadsheet ID.
var sstocopy = DriveApp.getFileById(id); // Get spreadsheet with DriveApp.
var sheet = ss.getActiveSheet(); // Get current active sheet.
var sheet_name = sheet.getRange("B1").getValue(); // Get the value of cell B1, used to name the new spreadsheet.
var folder_name = sheet.getRange("C23").getValue(); // Get the target folder ID.
var folder = DriveApp.getFolderById(folder_name); // Get the ID of the folder where you will place a copy of the spreadsheet.
sstocopy.makeCopy(sheet_name,folder); // Make a copy of the spreadsheet in the destination folder.
}
This script works, but I have been asked to modify it because the script I wrote is copying over unnecessary tabs and data that is causing confusion to users.
The new script should make a copy of a specific range in a specific sheet, create a new spreadsheet, and paste that range into it. It should also name itself after a cell value in the range.
However, the only method I have come across that specifically copies a sheet into a new spreadsheet is copyTo(spreadsheet). However, the Google Apps Script Guide specifies that "the copied sheet will be named 'Copy of [original name]'" by default.
I want to be able to rename the copied sheet after a specific cell. My question is, can I use copyTo(spreadsheet) and give the new spreadsheet a custom name, based on a cell?
Thanks!
You will need to get the data from the specific sheet to copy out to a variable of using:
var sourceSheet = ss.getSheetByName("Sheet1");
var sourceData = sourceSheet.getDataRange().getValues();
var originalRangeNotation = sourceSheet.getDataRange().getA1Notation();
Then you need to create a new, empty file and make a sheet with the same name
var ssNew = SpreadsheetApp.create("My New File Name");
ssNew.insertSheet('My New Sheet');
Then add the contents from the saved data to the new file. Since the insertSheet makes the new sheet the active one, we use:
var sheetNew = ssNew.getActiveSheet();
var rangeNew = sheet.getRange(originalRangeNotation);
range.setValues(sourceData);
Thanks. I ended up using this in place of sstocopy.makeCopy()
folder.addFile()
new_sheet.getActiveSheet().getRange("X:Y").setValues(sheet.getRange("X:Y").getValues())
DriveApp.getRootFolder().removeFile(temp)