在Google表格中,如何复制表格及其权限


10

在一个名为Attendance的Google Spreadsheet中,有一个名为Template的工作表。用户复制此工作表,用当前日期重命名工作表,并使用此工作表标记学生的出勤率。模板表包含受保护的单元格,并通过在给定的空间(未受保护的单元格)中输入学生的ID号来标记出勤。我使用以下脚本来复制多个工作表并每天对其进行重命名:

function createDailyAttendance() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var refss = ss.getSheetByName("DataPointers");

    // Get the range Row and Column information.
  var dataRangeRow = refss.getRange("K2").getValue();
  //var dataRangeCol = ss.getRangeByName(ColName).getValue();


   // Get the range of cells that store Duplicate sheet name.
  var AttendanceDataRange = refss.getRange(dataRangeRow);

  var AttendanceObjects = AttendanceDataRange.getValues();

  var template = ss.getSheetByName('Template');

  for (var i=0; i < AttendanceObjects.length; i++) {

     // Put the sheet you want to create in a variable
     var sheet = ss.getSheetByName(AttendanceObjects[i]);

      // Check if the sheet you want to create already exists. If so,
      // log this and loop back. If not, create the new sheet.
        if (sheet) {
           Logger.log("Sheet " + AttendanceObjects[i] + "already exists");
        } else {
           template.copyTo(ss).setName(AttendanceObjects[i]);
           }
        }
  return;
}

该脚本帮助我从模板创建工作表的多个副本,但是重复的副本不保留单元格/范围权限。有没有一种添加循环功能的方法,该功能可以从Template中提取权限并在每次循环template.copyTo创建工作表时应用该功能?


请在这里查看我的相关文章... stackoverflow.com/questions/40512801/…–
phinland

Answers:


9

方案1:模板是具有不受保护范围的受保护工作表

在下面的脚本中,我复制工作表,获取其对工作表类型的保护,然后以相同的方式保护新工作表:相同的描述,相同的类型。如果保护不仅是警告,请删除所有编辑器,然后添加原始表允许的编辑器。最后,遍历不受保护的范围,将每个范围(通过getA1Notation)重新映射到新的工作表,然后取消保护范围。

function duplicateProtectedSheet() {
  var ss = SpreadsheetApp.getActiveSpreadsheet(); 
  sheet = ss.getSheetByName("Sheet1");
  sheet2 = sheet.copyTo(ss).setName("My Copy"); 
  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);
}  

方案2:模板是具有受保护范围的工作表

使用sheet.getProtections方法,您可以在给定的工作表上获得一系列保护,并对其进行循环,在目标工作表上创建其类似物。这有点令人讨厌,因为似乎没有方法可以简单地将保护克隆到另一个范围。(可以更改保护范围,但是可以将其移动到新范围,而不是复制。)

因此,在下面的函数中,我执行以下操作:

  1. 使用以下命令获取每个受保护范围的A1表示法 p.getRange().getA1Notation();
  2. 用以下方法保护目标表的相应范围 p2 = sheet2.getRange(rangeNotation).protect();
  3. 设置性能新的保护p2按原保护性能p
function duplicateSheetWithProtections() {
  var ss = SpreadsheetApp.getActiveSpreadsheet(); 
  sheet = ss.getSheetByName('Template');
  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 
   }
  }
} 

在受保护的工作表中也可能有受保护的范围,在这种情况下,您需要将两个功能结合起来(执行它们各自所做的所有事情,当然您只需要复制工作表一次)。


我在循环中插入了您的建议,并在方案1中进行了测试,但收到一条错误消息TypeError: Cannot call method "protect" of null。我收到此错误,因为从此行开始var p2 = sheet.protect();
2015年

1
那就是那条线sheet2.protect();?这意味着sheet2为空,因此您应该查看定义它的那一行。

在我的代码中sheet2称为sheet。它的定义为var sheet = ss.getSheetByName(AttendanceObjects[i]);
Arvind

无论如何。调试代码是您的工作,而不是我的工作。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.