Search code examples
google-apps-scriptgoogle-sheetsnamed-rangesspreadsheet-protection

How to protect ranges per specific users in google sheet?


I am trying to apply protection on all sheets and certain ranges using a google script, for every sheet in its workbook (and can be applied on new added sheets via a trigger later)

the problem is, I want to assign different ranges to different users after protecting the whole sheet from anyone, but the people allowed to edit on their ranges!

I can't seem to know why it doesn't work.. It works oppositely, allowing all users to edit all ranges but the protected ones.

I want the first editor to be able to edit his QC_Range, and the second editor to be able to edit his PLN_Range and restrict access from editing (making it view only) for all other cells and whole the sheet.

function Sheet_Ranges_Protection(){

  var Veranda_Test = SpreadsheetApp.openById("Sheet ID");
  //var workbookB = SpreadsheetApp.getActiveSpreadsheet();

  var Veranda_Sheets = Veranda_Test.getSheets();
 for(var SheetNumb = 0; SheetNumb < Veranda_Sheets.length; SheetNumb++) 
  {          
    var Shprotection = Veranda_Sheets[SheetNumb].getProtections(SpreadsheetApp.ProtectionType.SHEET);

    var QC_Range         = Veranda_Sheets[SheetNumb].getRange("E1:G5");
    var PLN_Range        = Veranda_Sheets[SheetNumb].getRange("A1:C5");

    if (Shprotection == true)
      SheetNumb++;

    else if (Shprotection == false)
    {
      var Shprotection = Veranda_Sheets[SheetNumb].protect().setDescription('Sheet Protection');    

      var Rangesprotection = Veranda_Sheets[SheetNumb].getProtections(SpreadsheetApp.ProtectionType.RANGE);

      if (Rangesprotection == false)
      { 
        var QCprotection = QC_Range.protect().setDescription('QC Protection');  
        var me = Session.getEffectiveUser(); 
        QCprotection.addEditor(me); 
        QCprotection.removeEditors(QCprotection.getEditors()); 

        if (QCprotection.canDomainEdit())
        { 
          QCprotection.setDomainEdit(false); 
          QCprotection.addEditors(['[email protected]']); 
        }

        var PLNprotection = PLN_Range.protect().setDescription('PLN Protection');
        var me = Session.getEffectiveUser();  
        PLNprotection.addEditor(me); 
        PLNprotection.removeEditors(PLNprotection.getEditors()); 

        if (PLNprotection.canDomainEdit()) 
        { 
          PLNprotection.setDomainEdit(false);
          PLNprotection.addEditors(['[email protected]']);
        }

      }
      else
        SheetNumb++;

    //  Shprotection = true;
    //  Rangesprotection = true;

      // Ensure the current user is an editor before removing others. Otherwise, if the user's edit
      // permission comes from a group, the script will throw an exception upon removing the group.

    }
  }
}

Solution

  • I've reworked your code and I think it does what you pretend now. In this case, I don't make a sheet protection but protect all the ranges separately:

    function Sheet_Ranges_Protection() {
      var Veranda_Test = SpreadsheetApp.openById("Sheet ID");
      var Veranda_Sheets = Veranda_Test.getSheets();
    
      for(var SheetNumb = 0; SheetNumb < Veranda_Sheets.length; SheetNumb++) {
    
        var me = Session.getEffectiveUser();
    
        // Define ranges that will be protected for everyone
        var range1 = Veranda_Sheets[SheetNumb].getRange(6, 1, Veranda_Sheets[SheetNumb].getMaxRows(), Veranda_Sheets[SheetNumb].getMaxColumns());
        var range2 = Veranda_Sheets[SheetNumb].getRange(1, 8, 5, Veranda_Sheets[SheetNumb].getMaxColumns());
        var range3 = Veranda_Sheets[SheetNumb].getRange(1, 4, 5);
        var ranges = [range1, range2, range3];
    
        // Set protection for all the sheet minus QC/PLN ranges
        for(var i = 0; i < ranges.length; i++) {
          var rangeProtection = ranges[i].protect().setDescription('Range protection');
          rangeProtection.addEditor(me);
          rangeProtection.removeEditors(rangeProtection.getEditors());
          if (rangeProtection.canDomainEdit()) {
            rangeProtection.setDomainEdit(false);
          }
        }
    
        var QC_Range         = Veranda_Sheets[SheetNumb].getRange("E1:G5");
        var PLN_Range        = Veranda_Sheets[SheetNumb].getRange("A1:C5");
    
        // Set protection for QC range
        var QC_protection = QC_Range.protect().setDescription('QC protection');
        QC_protection.removeEditors(QC_protection.getEditors());
        QC_protection.addEditor('[email protected]');
        if (QC_protection.canDomainEdit()) {
          QC_protection.setDomainEdit(false);
        }
    
        // Set protection for PLN range
        var PLN_protection = PLN_Range.protect().setDescription('PLN protection');
        PLN_protection.removeEditors(PLN_protection.getEditors());
        PLN_protection.addEditor('[email protected]');
        if (PLN_protection.canDomainEdit()) {
          PLN_protection.setDomainEdit(false);
        }    
      }
    }
    

    I hope this works for you!