Trong Google Sheets, làm cách nào để sao chép một trang tính cùng với sự cho phép của nó


10

Trong Bảng tính Google có tên là Tham dự, có một bảng gọi là Mẫu . Người dùng sao chép trang tính này, đổi tên trang tính với ngày hiện tại và sử dụng trang tính này để đánh dấu điểm danh cho sinh viên. Bảng mẫu chứa các ô được bảo vệ và điểm danh được đánh dấu bằng cách nhập số ID của Sinh viên vào khoảng trống đã cho (các ô không được bảo vệ). Tôi sử dụng tập lệnh sau để sao chép nhiều trang tính và đổi tên chúng hàng ngày:

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

Tập lệnh này giúp tôi tạo nhiều bản sao của trang tính từ Bản mẫu nhưng các bản sao trùng lặp không giữ quyền của Ô / Phạm vi. Có cách nào để thêm chức năng lặp để trích xuất quyền từ Mẫu và áp dụng nó mỗi khi vòng lặp template.copyTotạo một trang tính không?


Vui lòng xem bài đăng liên quan của tôi ở đây ... stackoverflow.com/questions/40512801/ từ
phinland

Câu trả lời:


9

Kịch bản 1: mẫu là một trang được bảo vệ với phạm vi không được bảo vệ

Trong kịch bản dưới đây, tôi nhân đôi trang tính, bảo vệ loại Trang tính, sau đó bảo vệ trang tính mới theo cùng một cách: cùng mô tả, cùng loại. Nếu bảo vệ không chỉ là một cảnh báo, thì hãy xóa tất cả các trình soạn thảo và thêm những người được phép cho trang tính gốc. Cuối cùng, lặp qua các phạm vi không được bảo vệ, ánh xạ lại từng phạm vi trong số chúng (thông qua getA1Notation) sang trang tính mới và không bảo vệ chúng.

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

Kịch bản 2: mẫu là một trang tính với phạm vi được bảo vệ

Sử dụng sheet.getProtectionsphương pháp, bạn có thể nhận được các mảng bảo vệ trên một trang tính nhất định và lặp lại chúng, tạo ra các chất tương tự của chúng trên trang đích. Điều này hơi khó chịu vì dường như không có phương pháp nào để đơn giản nhân bản bảo vệ sang phạm vi khác. (Người ta có thể thay đổi phạm vi bảo vệ, nhưng điều đó sẽ chuyển nó sang phạm vi mới, thay vì sao chép.)

Vì vậy, trong chức năng dưới đây tôi làm như sau:

  1. Nhận ký hiệu A1 của từng phạm vi được bảo vệ với p.getRange().getA1Notation();
  2. Bảo vệ phạm vi tương ứng của bảng mục tiêu với p2 = sheet2.getRange(rangeNotation).protect();
  3. Đặt thuộc tính của bảo vệ mới p2theo các thuộc tính của bảo vệ ban đầu 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 
   }
  }
} 

Cũng có thể có các phạm vi được bảo vệ trong một trang được bảo vệ, trong trường hợp đó bạn sẽ cần kết hợp hai chức năng (làm mọi việc mà mỗi chức năng đó thực hiện, ngoại trừ tất nhiên bạn sẽ chỉ sao chép trang tính một lần.)


Tôi đã chèn đề xuất của bạn vào vòng lặp của mình và thử nghiệm trong Kịch bản 1, tôi nhận được thông báo lỗi TypeError: Cannot call method "protect" of null. Tôi nhận được lỗi này vì từ dòng này var p2 = sheet.protect();.
Arvind

1
Vì vậy, đó là dòng sheet2.protect();? Sau đó, nó có nghĩa là sheet2 là null, vì vậy bạn nên nhìn vào dòng được định nghĩa.

Trong mã của tôi sheet2 được gọi là sheet . Nó được định nghĩa làvar sheet = ss.getSheetByName(AttendanceObjects[i]);
Arvind

Dù sao. Gỡ lỗi mã của bạn là công việc của bạn, không phải của tôi.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.