In Google sheets, I have a sheet in which there is a group of lines that duplicate a template line. Within the template line I have protected cells or ranges of cells that only I can modify.
I want the other users to be able to add copies of the template line to the group using a button that triggers a script. At the moment the script, does the copy of the template line correctly but the ranges that were protected in the template or no longer protected in the copy.
Here is the script:
function AddParticipant(){
var spreadsheet= SpreadsheetApp.getActive();
var thisSheet=spreadsheet.getActiveSheet()
var sourceRange=thisSheet.getRange(7,1,1,thisSheet.getMaxColumns()).activate()
//the ◇ char is the place before which the copy must be inserted
var testCol= thisSheet.getRange(1,2,thisSheet.getMaxRows()).getValues()
var pos=0
for (var i=0;i<testCol.length;i++){
if (testCol[i] == "◇"){
break
}
pos=i+2
}
var destRange=thisSheet.getRange(pos,1).activate()
thisSheet.insertRowsBefore(thisSheet.getActiveRange().getRow(),1)
sourceRange.copyTo(destRange,SpreadsheetApp.CopyPasteType.PASTE_NORMAL,false)
}
Is it possible to keep the protected ranges with the same protection in the copy?
From your showing script and your question, I understood your situation as follows.
AddParticipant
, you want to copy row 7 to the destination row of the same sheet.In this case, how about the following modification?
In order to edit the protected range with the script by users who are not the owner of the Spreadsheet, I think that when the script is run as the owner of the Spreadsheet, no error occurs.
In order to achieve this, I would like to propose the following 2 patterns.
Unfortunately, in this case, the button on the Spreadsheet cannot be used. Because, when the script is run by clicking a button on Spreadsheet, the script is run by each user. So, in order to use this pattern, please replace the button with a checkbox. In this pattern, the checkbox is used as the button for executing the script.
For example, please insert a checkbox to "A1". By this, when the checkbox is checked, the script is run. The modified script is as follows.
And, please install the OnEdit trigger to installedOnEdit
. Ref By this, when the checkbox is checked, the script is run.
function installedOnEdit(e) {
const { range } = e;
if (range.getA1Notation() != "A1" || !range.isChecked()) return;
AddParticipant();
range.uncheck()
}
function AddParticipant() {
var spreadsheet = SpreadsheetApp.getActive();
var thisSheet = spreadsheet.getActiveSheet();
var sourceRange = thisSheet.getRange(7, 1, 1, thisSheet.getMaxColumns()).activate();
//the ◇ char is the place before wich the copy must be inserted
var testCol = thisSheet.getRange(1, 2, thisSheet.getMaxRows()).getValues();
var pos = 0;
for (var i = 0; i < testCol.length; i++) {
if (testCol[i] == "◇") {
break;
}
pos = i + 2;
}
var destRange = thisSheet.getRange(pos, 1).activate();
thisSheet.insertRowsBefore(thisSheet.getActiveRange().getRow(), 1);
sourceRange.copyTo(destRange, SpreadsheetApp.CopyPasteType.PASTE_NORMAL, false);
}
AddParticipant()
is run.In this pattern, your button on the Spreadsheet can be used. The script is run through the Web Apps. In order to use this, please do the following flow.
The detailed information can be seen in the official document.
Please set this using the new IDE of the script editor.
https://script.google.com/macros/s/###/exec
. This URL is used with Python script.Please copy and paste the following script to the script editor. And, please set your Web Apps URL to const webAppsUrl = "https://script.google.com/macros/s/###/dev";
.
const doGet = _ => AddParticipant(true);
function AddParticipant(e) {
if (!e) {
const webAppsUrl = "https://script.google.com/macros/s/###/dev"; // Please set your Web Apps URL.
UrlFetchApp.fetch(webAppsUrl, { headers: { authorization: "Bearer " + ScriptApp.getOAuthToken() } });
return;
}
var spreadsheet = SpreadsheetApp.getActive();
var thisSheet = spreadsheet.getActiveSheet();
var sourceRange = thisSheet.getRange(7, 1, 1, thisSheet.getMaxColumns()).activate();
//the ◇ char is the place before wich the copy must be inserted
var testCol = thisSheet.getRange(1, 2, thisSheet.getMaxRows()).getValues();
var pos = 0;
for (var i = 0; i < testCol.length; i++) {
if (testCol[i] == "◇") {
break;
}
pos = i + 2;
}
var destRange = thisSheet.getRange(pos, 1).activate();
thisSheet.insertRowsBefore(thisSheet.getActiveRange().getRow(), 1);
sourceRange.copyTo(destRange, SpreadsheetApp.CopyPasteType.PASTE_NORMAL, false);
}
// ### Please don't remove the following comment line.
// DriveApp.getFiles(); // This comment line is used for automatically detecting a scope of "https://www.googleapis.com/auth/drive.readonly". This scope is used for requesting Web Apps.
// ###
When you click the button assigned with AddParticipant
, the script is run. And, the script is run by Web Apps. By this, when the users who are not the owner of Spreadsheet are running the script, the script is run.