简体   繁体   中英

Is there a way to add/delete editors' access to protected cells dynamically by checkbox values on a Google sheet?

I am new to Google Apps Scripts and am puzzled with the problem of manipulating access of different editors. I have over 10 sheets and 20 editors, and I need to allocate their access rights according to their roles. I am thinking of using checkboxes for adding and deleting their access rights. So far these two are the codes I have picked up from the others. One for showing and hiding the timestamps by checking/unchecking the boxes, whilst another for adding and deleting the editors.

For Timestamps

function runEmailAccess(){

var ss = SpreadsheetApp.getActiveSpreadsheet();
var sEditors = ss.getSheetByName('Sheet Name');
var sheet = SpreadsheetApp.openById("Sheet ID");

var nAddEditor = sEditors.getRange('A2').getValue();
if (nAddEditor != 0){
var vAddEditor = sEditors.getRange('A3:A'+nAddEditor).getValues();
sheet.addEditors(vAddEditor);
 }

var nRemoveEditor = sEditors.getRange('B2').getValue();
if (nRemoveEditor != 0){
var vRemoveEditor = sEditors.getRange('B3:B'+nRemoveEditor).getValues();

for (j=0;j<vRemoveEditor.length;j++) {
  sheet.removeEditor(vRemoveEditor[j][0])
}
}

} 

For checkboxes

function onEdit(e){
  if (e.range.columnStart == 6 && e.range.columnEnd == 6 && e.range.rowStart <= 20) {
    var ckeckboxRange = "F1:F20";
    var date = new Date();
    var range = e.source.getRange(ckeckboxRange);
    var values = range.getValues().map(function(e) {return e[0] === true ? [date] : [""]});
    range.offset(0, 1).setValues(values);
  }
}

var SpreadSheet = SpreadsheetApp.getActiveSpreadsheet();
var editors = SpreadSheet.getEditors();
for (var i = 0; i < editors.length; i++) {
     SpreadSheet.removeEditor(editors[i]);
    };

And finally we have the expected outcome as it would be a clearer picture of what I have described. It is like a command portal to control different access rights on a holistic level.

Expected outcome

Many thanks to all useful comments.

You need the the following components:

  • onEdit trigger
  • Checking which checkbox has been edited and making the connection to the respective sheet
  • Retrieve the editor from the line wiht the checkbox
  • Verify either the box has been checked or unechecked

Below is a sample providing this funcitonality:

function onEdit(e){
  var ss = SpreadsheetApp.getActive();
  //change name of the sheet if necessary!
  var sheetWithCheckBoxes = ss.getSheetByName("Sheet1");
  var column =  e.range.getColumn();
  if (e.range.getSheet().getName() == sheetWithCheckBoxes.getName() && (column == 3 || column == 4 || column == 5)) {
    Logger.log("if");
    var spreadsheet2 = SpreadsheetApp.openById("XXX");
    var sheet;
    switch (column){
      case 3:
        sheet = ss.getSheetByName("name");
        break;
      case 4:
        sheet = ss.getSheetByName("name2");
        break;
      case 5:
        sheet = spreadsheet2.getSheetByName("name3");
        break;
    }       
   
    var protection = sheet.protect();
    if (protection.canDomainEdit()) {
      protection.setDomainEdit(false);
    }
    var editor = sheetWithCheckBoxes.getRange(e.range.getRow(), 2).getValue();
     Logger.log(e.value);
    if(e.value == "TRUE"){
       Logger.log("true");
      protection.addEditor(editor);
    }
    if(e.value == "FALSE"){
            Logger.log("false");
      protection.removeEditor(editor);
    }
  }
}

Note:
In this sample the first two sheets are in the same spreadsheet like the sheet with the checkboxes and the wthird dsheet is in a different spreadsheet.

Please adapt the sheets and spreadsheets accoring to you needs.

UPDATE

For setting not only the sheet protection, but also share the spreadsheet with new users, you need to use the method DriveApp.getFileById(id).addEditor(editor) .

However, DriveApp.getFileById(id) is a call that cannot be triggered with a simple onEdit trigger due to restrictions .

Solution:

Bind an installable onEdit trigger to your function instead of the simple one. Make sure to rename the function beforehand to avoid conflicts because of the simple and installable trigger being fired simultaneously.

Sample setting up both the spreadsheet and sheet permissions:

function Edit(e){
  var ss = SpreadsheetApp.getActive();
  //change name of the sheet if necessary!
  var sheetWithCheckBoxes = ss.getSheetByName("Sheet1");
  var column =  e.range.getColumn();
  if (e.range.getSheet().getName() == sheetWithCheckBoxes.getName() && (column == 3 || column == 4 || column == 5)) {
    var spreadsheet2 = SpreadsheetApp.openById("XXX");
    var sheet;
    var id;
    switch (column){
      case 3:
        sheet = ss.getSheetByName("name");
        id = ss.getId();
        break;
      case 4:
        sheet = ss.getSheetByName("name2");
        id = ss.getId();
        break;
      case 5:
        id = spreadsheet2.getId();
        sheet = spreadsheet2.getSheetByName("name3");
        break;
    }       
    var protection = sheet.protect();
    if (protection.canDomainEdit()) {
      protection.setDomainEdit(false);
    }
    var editor = sheetWithCheckBoxes.getRange(e.range.getRow(), 2).getValue();
    Logger.log(e.value);
    if(e.value == "TRUE"){
      DriveApp.getFileById(id).addEditor(editor);
      protection.addEditor(editor);
    }
    if(e.value == "FALSE"){
      protection.removeEditor(editor);
    }
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM