I have been using the following code (after some edits and help from the community here) to create a duplicate sheet from a template sheet. However, the number of sheets have increased now. Is there a way to make some edits in this code such that the newly created sheet shows up directly so I can right away edit without horizontally scrolling through to find the new sheet that was created from the script? .
Edited question for giving better clarity on the issue.
function duplicateSheetWithProtections() {
var ui = SpreadsheetApp.getUi();
var oldSheetName = ui.prompt('Sheet to Copy?');
var newSheetName = ui.prompt('New Sheet Name?');
var ss = SpreadsheetApp.getActiveSpreadsheet();
sheet = ss.getSheetByName(oldSheetName.getResponseText());
sheet2 = sheet.copyTo(ss).setName(newSheetName.getResponseText());
var protections = sheet.getProtections(SpreadsheetApp.ProtectionType.RANGE);
for (var i = 0; i < protections.length; i++) {
var p = protections[i];
var rangeNotation = p.getRange().getA1Notation();
var p2 = sheet2.getRange(rangeNotation).protect();
p2.setDescription(p.getDescription());
p2.setWarningOnly(p.isWarningOnly());
if (!p.isWarningOnly()) {
p2.removeEditors(p2.getEditors());
p2.addEditors(p.getEditors());
// p2.setDomainEdit(p.canDomainEdit()); // only if using an Apps domain
/* Make the new sheet active */
ss.setActiveSheet(sheet);
}
}
}
Try
sheet2.moveActiveSheet(0)
this will be the simplest and most effective solution
Related
i've a function called when opening my spreadsheet that aim to loop trought all sheets, activate them and set cursor to the last modified cell (saved by another function) and, a the last re-select the last used sheet (saved as before by another function).
It worked fine for years, but suddenly stopped working.
Here is my code:
function onOpen()
{
var timer = 2000;
var proprieta = PropertiesService.getScriptProperties();
var lastSheet = proprieta.getProperty("ultimo");
var lastModifiedCell = proprieta.getProperty(lastSheet);
var applicazione = SpreadsheetApp.getActive();
var fogli = applicazione.getSheets();
var ui = SpreadsheetApp.getUi();
for (var i=0; i < fogli.length; i++)
{
var attuale = fogli[i].getName();
var ultimorange = proprieta.getProperty(attuale);
applicazione.getSheetByName(attuale).getRange(ultimorange).activate();
//ui.alert(attuale);
//ui.alert(ultimorange);
Utilities.sleep(timer);
}
applicazione.getSheetByName(lastSheet).getRange(lastModifiedCell).activate();
}
Doesn't return any error but the for loop is not selecting anymore sheet and range given.
If i enable the ui.alert the sheet name and range are displayed correctly.
The last selection ath the end, works correctly...i have no idea why it happens...
Is there anyone who can help me figure out what's wrong?
Thanks to anyone who will answer!!!
I was able to replicate the issue. To prevent this from happening, you can use SpreadsheetApp.flush()
Your code:
function onOpen()
{
var timer = 2000;
var proprieta = PropertiesService.getScriptProperties();
var lastSheet = proprieta.getProperty("ultimo");
var lastModifiedCell = proprieta.getProperty(lastSheet);
var applicazione = SpreadsheetApp.getActive();
var fogli = applicazione.getSheets();
var ui = SpreadsheetApp.getUi();
for (var i=0; i < fogli.length; i++)
{
var attuale = fogli[i].getName();
var ultimorange = proprieta.getProperty(attuale);
var range = applicazione.getSheetByName(attuale).getRange(ultimorange).activate();
SpreadsheetApp.flush();
Utilities.sleep(timer);
}
applicazione.getSheetByName(lastSheet).getRange(lastModifiedCell).activate();
ui.alert("Activation Done");
}
I'm new but i found something recently (i come from excel scripts) :
getting a "range" and getting it's a1Notation are totally different.
Maybe your "ultimorange" (from "attuale") is a range and NOT the notation of the range. It would make getRange(ultimorange) not working.
I have a google sheet that has many protected ranges/cells. It is currently set up so that myself and two others have full edit access to the workbook/protected ranges/cells. All others accessing the sheet can then only edit certain cells. It works exactly how I expect.
However, when I use a script to copy that sheet and insert data, the protections for the other two full editors goes away. I do not remove protections in my code at all just add data to the sheet.
Any thoughts on why this would happen or how to fix it? Again, these two other users can access the sheet they just can no longer edit any cell/range.
Try this (sheetname should be the name of your sheet to copy):
function duplicateSheetWithProtections() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
sheet = ss.getSheetByName('sheetname');
sheet2 = sheet.copyTo(ss).setName('My Copy');
var protections = sheet.getProtections(SpreadsheetApp.ProtectionType.RANGE);
for (var i = 0; i < protections.length; i++) {
var p = protections[i];
var rangeNotation = p.getRange().getA1Notation();
var p2 = sheet2.getRange(rangeNotation).protect();
p2.setDescription(p.getDescription());
p2.setWarningOnly(p.isWarningOnly());
if (!p.isWarningOnly()) {
p2.removeEditors(p2.getEditors());
p2.addEditors(p.getEditors());
// p2.setDomainEdit(p.canDomainEdit()); // only if using an Apps domain
}
}
}
Hi I've been trying to experiment with google's script editor and i think that I've gotten the code right but it wont seem to work. I used the code they made in google's tutorial video with edits but it cant seem to create an event. On the executions page it says completed but no new event is showing up.
Anyway i've attached screen shots of the sheet as well as the code. Hope y'all can help thanks!
function scheduleMeetings() {
var spreadsheet = SpreadsheetApp.getActiveSheet();
var calendarId = spreadsheet.getRange('H6').getValue();
var eventCal = CalendarApp.getCalendarById(calendarId);
var tasks = spreadsheet.getRange("G10:H100").getValue();
for (x=0; x<tasks.length; x++) {
var schedules = tasks[x];
var date = schedules[0];
var task = schedules[1];
eventCal.createAllDayEvent(task, date);
}
}
Try this:
function scheduleMeetings() {
var spreadsheet = SpreadsheetApp.getActiveSheet();
var calendarId = spreadsheet.getRange('H6').getValue();
var eventCal = CalendarApp.getCalendarById(calendarId);
var tasks = spreadsheet.getRange("G10:H100").getValues();//you had getValue()
for (var x=0;x<tasks.length;x++) {
var schedules = tasks[x];//Select a row
var date = schedules[0];//column G
var task = schedules[1];//column H
//you may need to add var date=new Date(schedules[0]);
eventCal.createAllDayEvent(task, date);
}
}
I am creating workbooks for teachers to monitor students progress on a specific skill. We have a workbook with various templates they may need to copy the sheets/graphs they need for each child. These sheets are protected without the exception of the cells the teachers need to access in order to input student data. Right now when we use the COPY TO a new spreadsheet, we lose those protections. (Most of our K-2 teachers are not tech-savvy enough to have full access to a sheet with a graph.) There has to be a way to create some type of protection that carries over to copied files that is foolproof. Thanks to anyone who knows how to do this.
I tried using this code and it does copy my sheet and keep it protected, BUT how can I get it to stay protected when the COPY TO is used to another existing workbook?
function duplicateProtectedSheet() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
sheet = ss.getSheetByName("B - General Info");
sheet2 = sheet.copyTo(ss).setName("My Copy1");
var p = sheet.getProtections(SpreadsheetApp.ProtectionType.SHEET)[0];
var p2 = sheet2.protect();
p2.setDescription(p.getDescription());
p2.setWarningOnly(p.isWarningOnly());
if (!p.isWarningOnly()) {
p2.removeEditors(p2.getEditors());
p2.addEditors(p.getEditors());
// p2.setDomainEdit(p.canDomainEdit()); // only if using an Apps domain
}
var ranges = p.getUnprotectedRanges();
var newRanges = [];
for (var i = 0; i < ranges.length; i++) {
newRanges.push(sheet2.getRange(ranges[i].getA1Notation()));
}
p2.setUnprotectedRanges(newRanges);
}
Here is an example of my current workbook with the templates teachers will be copied to their own workbooks.
https://docs.google.com/spreadsheets/d/1JB95bdu4Qatx7uMZrQFP7GkiKBuuB47PCV8ZjyQWmHo/edit?usp=sharing
try this:
function test(){
var ss = SpreadsheetApp.getActiveSheet();
var protections = ss.getProtections(SpreadsheetApp.ProtectionType.RANGE);
var newSheet = ss.copyTo(SpreadsheetApp.getActive());
var prot;
var p;
var editors;
for (var i = 0; i < protections.length; i++){
prot = protections[i];
p = newSheet.getRange(prot.getRange().getA1Notation()).protect();
p.setDescription(prot.getDescription());
editors = prot.getEditors();
for (var j = 0; j < editors.length; j++){
p.addEditor(editors[i]);
}
}
}
This code copies the sheet and stores the original's protections, then it set the same protections in the newly-created sheet. for you it would be a matter of setting ss and newSheet to the ones you intend to use.
Soooo close on this one thanks to stackoverflow help :)
The following code duplicates a sheet based on a template, and copies over the protected range permissions from the template sheet to the new sheet.
However, the permission range is now there in the new sheet, but not with the same user.
The template sheet has only one user that can edit, but for the new sheet, while the same range is restricted, all users from the entire spreadsheet can edit the new sheet.
Anyone happen to know if I can make it be just the exact same user as the template? And not like the user that initiates the script but only the same user as the template. Here's the code:
function newSheet() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("New Sheet Template");
var protections = sheet.getProtections(SpreadsheetApp.ProtectionType.RANGE);
var dateI = Browser.inputBox('Enter Date: ','(DD/MM/YYYY)', Browser.Buttons.OK_CANCEL);
var nameSheet= "Sheet - "+dateI
if (dateI == "cancel" ) {
}
else {
ss.insertSheet(nameSheet, {template: sheet});
ss.getRange('B4').setValue(dateI);
for (var i = 0; i < protections.length; i++) {
var sheet2 = ss.getSheetByName("Sheet - "+dateI);
var p = protections[i];
var rangeNotation = p.getRange().getA1Notation();
var p2 = sheet2.getRange(rangeNotation).protect();
p2.setDescription(p.getDescription());
p2.setWarningOnly(p.isWarningOnly());
}
}
}
Thanks in advance! :)