使用Google Apps Script复制Google Sheet时如何保留保护范围权限
解决方案
问题原因
调用makeCopy()复制Google Sheet时,系统默认仅保留受保护范围的规则,不会同步这些范围配置的非所有者编辑权限,因此你需要手动在复制完成后增加权限同步逻辑。
修改后完整脚本
function copyfilefromsource() { var ui = SpreadsheetApp.getUi(); var sheet_merge = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("List"); var last_row = sheet_merge.getLastRow(); var newsheet_email = null; var file_owner = null; var dest_folder = null; var new_file = null; var source_file = null; var student_id = null; var google_domain = null; var range = sheet_merge.getRange(1, 1, last_row, 4); source_file = DriveApp.getFileById(range.getCell(1, 2).getValue()); // 读取源文件 // ========== 新增:读取源表格的受保护范围权限配置 ========== var sourceSs = SpreadsheetApp.openById(source_file.getId()); var sourceProtections = []; // 遍历所有工作表的范围级保护规则 sourceSs.getSheets().forEach(function(sheet) { var protections = sheet.getProtections(SpreadsheetApp.ProtectionType.RANGE); protections.forEach(function(prot) { // 提取该保护范围允许的编辑者邮箱 var allowedEditors = prot.getEditors().map(function(editor) { return editor.getEmail(); }); sourceProtections.push({ sheetName: sheet.getName(), rangeA1: prot.getRange().getA1Notation(), editors: allowedEditors }); }); }); // ========== 新增结束 ========== dest_folder = DriveApp.getFolderById(range.getCell(2, 2).getValue()); // 读取目标文件夹ID file_owner = range.getCell(3, 2).getValue(); // 读取文件所有者账号 google_domain = range.getCell(4, 2).getValue(); // 读取邮箱域名后缀 for (var i = 7; i <= last_row; i++) { if (range.getCell(i, 4).getValue() == '') { student_id = range.getCell(i, 1).getValue(); newsheet_email = student_id + google_domain; newsheet_firstname = range.getCell(i, 2).getValue(); newsheet_surname = range.getCell(i, 3).getValue(); new_file = source_file.makeCopy(student_id, dest_folder) new_file.setOwner(file_owner); new_file.addViewer(newsheet_email); new_file.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.EDIT); var id_ss = new_file.getId(); var newSs = SpreadsheetApp.openById(id_ss); newSs.getSheets()[0].getRange(2, 2).setValue(student_id); // ========== 新增:同步保护范围权限到新表格 ========== sourceProtections.forEach(function(protConfig) { var targetSheet = newSs.getSheetByName(protConfig.sheetName); if (!targetSheet) return; // 查找新表格中对应位置的保护规则 var targetProtections = targetSheet.getProtections(SpreadsheetApp.ProtectionType.RANGE); var targetProt = targetProtections.find(function(p) { return p.getRange().getA1Notation() === protConfig.rangeA1; }); if (targetProt) { // 批量添加允许的编辑者 protConfig.editors.forEach(function(email) { // 过滤掉脚本执行账户,避免重复添加 if (email !== Session.getActiveUser().getEmail()) { targetProt.addEditor(email); } }); } }); // ========== 新增结束 ========== SpreadsheetApp.getActiveSheet().getRange(i,1).setFormula('=HYPERLINK("' + new_file.getUrl() +'/","'+student_id+'")'); SpreadsheetApp.getActiveSheet().getRange(i,4).setValue(new_file.getId()); } } }
注意事项
- 请使用源表格的所有者账户执行脚本,确保有权限读取保护范围的编辑者列表
- 如果你同时设置了整表级别的保护规则,需要额外补充
SpreadsheetApp.ProtectionType.SHEET类型的规则同步逻辑,当前脚本仅适配范围级别的保护配置 - 若学生邮箱属于企业/教育域账号,请确认域权限没有限制跨文件添加编辑者
内容的提问来源于stack exchange,提问作者weizer
相关产品推荐
相关产品推荐

