You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 10:24:04