Di Google Sheets bagaimana cara menduplikasi selembar beserta izinnya

10

Di Google Spreadsheet yang disebut Kehadiran ada lembar yang disebut Template . Pengguna menduplikasi lembar ini, mengganti nama lembar dengan tanggal saat ini dan menggunakan lembar ini untuk menandai kehadiran bagi siswa. Lembar Templat berisi sel-sel yang dilindungi dan kehadiran ditandai dengan memasukkan nomor ID Siswa di ruang yang diberikan (sel yang tidak terlindungi). Saya menggunakan skrip berikut untuk menduplikasi beberapa lembar dan mengganti nama setiap hari:

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

Skrip ini membantu saya membuat beberapa lembar salinan dari Templat tetapi salinan duplikat tidak mempertahankan izin Cell / Range. Apakah ada cara untuk menambahkan fungsi loop yang mengekstraksi izin dari Template dan menerapkannya setiap kali loop template.copyTomembuat sheet?

Arvind
sumber
Silakan lihat posting terkait saya di sini ... stackoverflow.com/questions/40512801/…
phinland

Jawaban:

9

Skenario 1: templat adalah lembar yang dilindungi dengan rentang yang tidak dilindungi

Dalam skrip di bawah ini, saya menduplikasi sheet, mendapatkan perlindungannya dari tipe Sheet, kemudian melindungi sheet baru dengan cara yang sama: deskripsi yang sama, tipe yang sama. Jika perlindungan bukan hanya peringatan, maka hapus semua editor, dan tambahkan yang diizinkan untuk lembar asli. Akhirnya, lewati rentang yang tidak terlindungi, remapping masing-masing (via getA1Notation) ke sheet baru, dan buka proteksi itu.

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

Skenario 2: templat adalah lembaran dengan rentang yang dilindungi

Dengan menggunakan sheet.getProtectionsmetode, Anda bisa mendapatkan array perlindungan pada lembar yang diberikan, dan mengulanginya, membuat analognya pada lembar target. Ini agak menjengkelkan karena tampaknya tidak ada metode untuk hanya mengkloning perlindungan ke rentang lain. (Seseorang dapat mengubah rentang perlindungan, tetapi itu akan memindahkannya ke rentang baru, alih-alih menyalin.)

Jadi, dalam fungsi di bawah ini saya melakukan hal berikut:

  1. Dapatkan notasi A1 untuk setiap rentang yang dilindungi p.getRange().getA1Notation();
  2. Lindungi rentang lembar target yang sesuai dengan p2 = sheet2.getRange(rangeNotation).protect();
  3. Atur properti perlindungan baru p2sesuai dengan properti perlindungan asli 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 
   }
  }
} 

Dimungkinkan juga untuk memiliki rentang terlindungi dalam lembar terlindungi, dalam hal ini Anda perlu menggabungkan kedua fungsi (lakukan semua yang dilakukan masing-masing, kecuali tentu saja Anda akan menduplikasi lembar hanya sekali.)


sumber
Saya memasukkan saran Anda di loop saya dan diuji di Skenario 1, saya mendapat pesan kesalahan TypeError: Cannot call method "protect" of null. Saya mendapatkan kesalahan ini karena dari baris ini var p2 = sheet.protect();.
Arvind
1
Jadi, itu intinya sheet2.protect();? Maka itu berarti sheet2 adalah nol, jadi Anda harus melihat baris di mana itu didefinisikan.
Dalam kode saya sheet2 disebut sebagai sheet . Didefinisikan sebagaivar sheet = ss.getSheetByName(AttendanceObjects[i]);
Arvind
Bagaimanapun. Men-debug kode Anda adalah pekerjaan Anda, bukan milik saya.