简体   繁体   中英

Lock Google Sheets cells/range after condition is met

We're using Google Sheets for financial reconciliation internally and facing some mistakes in it. There is a spreadsheet with all the data to which almost everyone in company has access for editing. What I want to do is to lock certain cells for all users except few people when simple condition (for example, cell fill color is changed to red) is met. So the function description looks like:

  1. everyone has access to spreadsheet
  2. cells in range (which one should be locked) are not locked
  3. cells are not locked until condition is met
  4. user enters value to cell/range
  5. user applies condition (fill color, for example)
  6. cell locks. access from all users except few ones is removed
  7. users with access could edit/unlock

It would be much appreciated if someone could help with the exact function to apply. Many thanks in advance!

The only thing I did found is the documentation which is close to my problem: https://developers.google.com/apps-script/reference/spreadsheet/range https://developers.google.com/apps-script/reference/spreadsheet/protection But I'm zero in Apps Script which is used by Google Sheets(

This gets you close but unfortunately I ran into the problem of onEdit events do not consider background color changes apparently... So ultimately this will only fire after a cell value changes.

If the cell is Red and the range is not yet protected, it will be protected as you being the only editor. If the background is not red it will either strip away the protection or not change.

/**
* Protects and unprotects ranges;
* @param {Object} e event object;
*/
function onEdit(e) {
  //access cell formats;
  var bgColor = e.range.getBackground();
  var bold = e.range.getFontWeight();

  //access edited range, value and sheet;
  var rng = e.range;
  var val = e.value;
  var sh  = rng.getSheet();

  //access edited range row and column;
  var row = rng.getRow();
  var col = rng.getColumn();

  //access protections;
  var ps = sh.getProtections(SpreadsheetApp.ProtectionType.RANGE);

  //filter out other cells protections;
  ps = ps.filter(function(p){
   var ptd = p.getRange();
   if(row===ptd.getRow()&&col===ptd.getColumn()) {
     return p;
   }
  })[0];

  //SpreadsheetApp.getActive().toast(bgColor); //Uncomment to get a toast displaying background color of edited cell.

  //if protection not set -> protect;
  if(!ps) {
    if (bgColor === '#ff0000' && bold === 'bold') {
      SpreadsheetApp.getActive().toast("Cell Locked");
      var protection = rng.protect(); //protect Range;
      var users = protection.getEditors(); //get current editors;
      var emails = [Session.getEffectiveUser(),'email1@email.com','email2@email.com']; //declare list of users (emails)
      
      protection.addEditor(Session.getEffectiveUser());
      protection.addEditors(emails);
      protection.removeEditors(users); //remove other editors' access;
    }}else {
      if(!val || bgColor != '#ff0000' || bold != 'bold') { ps.remove(); } //if cell is empty -> remove protection;
    }
}

Perhaps someone can improve on this and adjust for background events only. Also if working fast this doesn't keep up well.

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