No Planilhas Google, como duplico uma planilha junto com sua permissão

10

Em uma planilha do Google chamada Atendimento, há uma planilha chamada Modelo . O usuário duplica esta planilha, renomeia a planilha com a data atual e usa esta planilha para marcar a presença dos alunos. A folha Modelo contém células protegidas e o atendimento é marcado digitando o número de identificação do aluno no espaço fornecido (células não protegidas). Eu uso o seguinte script para duplicar várias planilhas e renomeá-las todos os dias:

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;
}

Esse script me ajuda a criar várias cópias de planilhas do modelo, mas as cópias duplicadas não mantêm as permissões de célula / intervalo. Existe uma maneira de adicionar uma função de loop que extrai a permissão do Template e a aplica sempre que o loop template.copyTocria uma planilha?

Arvind
fonte
Por favor, veja o meu post relacionado aqui ... stackoverflow.com/questions/40512801/…
phinland

Respostas:

9

Cenário 1: o modelo é uma planilha protegida com intervalos desprotegidos

No script abaixo, duplico a planilha, obtenho a proteção do tipo Planilha e protejo a nova planilha da mesma maneira: mesma descrição, mesmo tipo. Se a proteção não for apenas um aviso, remova todos os editores e adicione os permitidos para a folha original. Por fim, faça um loop sobre intervalos desprotegidos, remapeando cada um deles (via getA1Notation) para a nova planilha e desproteja-os.

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);
}  

Cenário 2: o modelo é uma planilha com intervalos protegidos

Usando o sheet.getProtectionsmétodo, você pode obter a matriz de proteções em uma determinada planilha e fazer um loop sobre elas, criando seus análogos na planilha de destino. Isso é um pouco chato, porque parece não haver método para simplesmente clonar uma proteção para outro intervalo. (Pode-se alterar o intervalo de proteção, mas que iria mover -lo para a nova gama, em vez de copiar.)

Portanto, na função abaixo, faço o seguinte:

  1. Obtenha a notação A1 de cada intervalo protegido com p.getRange().getA1Notation();
  2. Proteja o intervalo correspondente da folha de destino com p2 = sheet2.getRange(rangeNotation).protect();
  3. Defina as propriedades da nova proteção de p2acordo com as propriedades da proteção original 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 
   }
  }
} 

Também é possível ter intervalos protegidos dentro de uma planilha protegida; nesse caso, você precisaria combinar as duas funções (faça tudo o que cada uma delas faz, exceto é claro que você duplicará a planilha apenas uma vez).


fonte
Inseri sua sugestão no meu loop e testei no cenário 1, recebi uma mensagem de erro TypeError: Cannot call method "protect" of null. Estou recebendo esse erro porque a partir desta linha var p2 = sheet.protect();.
precisa
11
Então essa era a linha sheet2.protect();? Então isso significa que a planilha2 é nula; portanto, você deve observar a linha em que está definida.
Na minha folha de código2 é referida como folha . É definido comovar sheet = ss.getSheetByName(AttendanceObjects[i]);
Arvind
De qualquer forma. Depurar seu código é seu trabalho, não meu.