web-dev-qa-db-ja.com

Googleスプレッドシートで、許可とともにシートを複製するにはどうすればよいですか

AttendanceというGoogleスプレッドシートに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.copyToがシートを作成するたびに適用するループ関数を追加する方法はありますか?

9
Arvind

シナリオ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メソッドを使用すると、特定のシートの保護の配列を取得し、それらをループ処理して、ターゲットシートに類似物を作成できます。これは、保護を別の範囲に単純に複製する方法がないように思われるため、やや面倒です。 (保護範囲を変更することはできますが、それはmoveコピーの代わりに新しい範囲に移動します。)

そのため、以下の関数で次のことを行います。

  1. p.getRange().getA1Notation();で各保護範囲のA1表記を取得します
  2. ターゲットシートの対応する範囲をp2 = sheet2.getRange(rangeNotation).protect();で保護します
  3. 元の保護pのプロパティに従って、新しい保護p2の-​​ properties を設定します。
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 
   }
  }
} 

保護されたシート内に保護された範囲を持つことも可能です。その場合、2つの機能を組み合わせる必要があります(もちろん、シートを1回だけ複製することを除いて、それぞれの機能をすべて実行します)。

7
user79865