Reputation: 1137
I hope this won't make me lose points but I have been looking everywhere and I can't find an answer:
Is there a way of keeping the protected ranges in the new copy ?
If it is not possible, maybe use
var protection = spreadsheet.getRange('D1:G9').protect();
on the new copy?
But then I have no idea how to assign it to the new copy, as the script would be in the original spreadsheet and the copy of the spreadsheet has no Id before being created ...
Upvotes: -1
Views: 3279
Reputation: 201643
a spreadsheet
of Make a copy of a spreadsheet while keeping protected ranges
means a sheet in a Spreadsheet.When Spreadsheet is copied, the protected ranges are also copied. So I understood like above. If my understanding is correct, how about this answer? Please think of this as just one of several answers.
Unfortunately, in the current stage, when a sheet is copied to Spreadsheet using copyTo()
of Class Sheet and the method of copyTo of Sheets API, the protected ranges are not copied. This situation is the same with the manual copy.
In order to copy the protected ranges, the protected ranges are required to be copied to the copied sheet. But when Spreadsheet Service is used for this situation, the script becomes a bit complicate. So in this answer, as a workaround, I used Sheets API. In this case, the object retrieved by the get method is almost the same with the request body of the method of batchRequest. So I used this.
Before you use this script, please enable Sheets API at Advanced Google Services. And also, please set the variables of srcId
, srcSheetName
and dstId
.
var srcId = "###"; // Please set source Spreadsheet ID.
var srcSheetName = "###"; // Please set source sheet name you want to copy.
var dstId = "###"; // Please set destination Spreadsheet ID.
var src = SpreadsheetApp.openById(srcId);
var dst = SpreadsheetApp.openById(dstId);
var sheetId = src.getSheetByName(srcSheetName).copyTo(dst).getSheetId();
var protectedRanges = Sheets.Spreadsheets.get(srcId, {ranges: [srcSheetName], fields: "sheets/protectedRanges"});
var requests = protectedRanges.sheets[0].protectedRanges.map(function(e) {
e.range.sheetId = sheetId;
return {addProtectedRange: {protectedRange: e}};
});
Sheets.Spreadsheets.batchUpdate({requests: requests}, dstId);
About the following question,
how can we adapt if the sheet itself is protected except some ranges?
In this case, the property of unprotectedRanges
is required to be included as follows.
var srcId = "###"; // Please set source Spreadsheet ID.
var srcSheetName = "###"; // Please set source sheet name you want to copy.
var dstId = "###"; // Please set destination Spreadsheet ID.
var [src, dst] = [srcId, dstId].map(s => SpreadsheetApp.openById(s));
var sheetId = src.getSheetByName(srcSheetName).copyTo(dst).getSheetId();
var protectedRanges = Sheets.Spreadsheets.get(srcId, { ranges: [srcSheetName], fields: "sheets/protectedRanges" });
var requests = protectedRanges.sheets[0].protectedRanges.map(e => {
e.range.sheetId = sheetId;
if (e.unprotectedRanges) {
e.unprotectedRanges.forEach(f => f.sheetId = sheetId);
}
return { addProtectedRange: { protectedRange: e } };
});
Sheets.Spreadsheets.batchUpdate({ requests }, dstId);
Upvotes: 8