简体   繁体   English

锁定/保护包含特定文本值的整个 Google 电子表格中的单元格

[英]Lock/Protect cells in a whole Google spreadsheet containing a specific text value

I have the following script ( from this answer ) which inserts a specific text value to a range of cells based on the date on the second column (B) in the same row.....我有以下脚本(来自this answer ),它根据同一行中第二列(B)上的日期将特定文本值插入到一系列单元格中.....

function onEdit(e) {
  if (e.range.getColumn() == 2) {
    //User edited the date column
    if (typeof e.range.getValue() === typeof new Date()) {
      //Value of edit was a date
      endColumns(e.range.getRow(), e.range.getValue());
    } else if (e.range.getValue() === ""  || e.range.getValue() === null) {
      var sheets = SpreadsheetApp.getActiveSheet();
      // Delete all "ENDED" values:
      var resetRange = sheets.getRange(e.range.getRow(), e.range.getColumn() + 1, 1, sheets.getMaxColumns() - e.range.getColumn());
      var resetValues = resetRange.getValues()[0];
      for(var i = 0; i < resetValues.length; i++) {
        if(resetValues[i] == "ENDED") {
          var resetCell = sheets.getRange(e.range.getRow(), e.range.getColumn() + 1 + i);
          resetCell.clearContent();
        }
      }      
    }
  }
}

function endColumns(rowNum, limitDate) {
  var sheets = SpreadsheetApp.getActiveSheet();

  var colOffset = 3; //Offset to account for your row Headers
  var dateHeader = sheets.getRange(1, colOffset, 1, sheets.getMaxColumns() - colOffset);

  var availableDates = dateHeader.getValues()[0];

  var foundCol = 0;
  for (var i = 0; i < availableDates.length; i++) {
    if (availableDates[i] >= limitDate) {
      break;
    }
    foundCol++;
  }

  var rewriteCells = sheets.getRange(rowNum, foundCol + colOffset, 1, sheets.getMaxColumns() - (foundCol + colOffset - 1));

  //Add your formatting and text below:
  rewriteCells.setValue("ENDED");

  // Clear past dates if new date is later:
  var beforeDate = sheets.getRange(rowNum, colOffset, 1, foundCol);
  var beforeValues = beforeDate.getValues()[0];
  for(var i = 0; i < beforeValues.length; i++) {
    if(beforeValues[i] == "ENDED") {
      sheets.getRange(rowNum, colOffset + i).clearContent();
    }  
  }


  // Clear all cells that are "white" (no header)
  for (var i = 0; i < availableDates.length; i++) {
    if (availableDates[i] === "" || availableDates[i] === null) {
      sheets.getRange(rowNum, colOffset+i).clear();
    }
  }
}

I want these cells, containing that specific text value, to be lock/protect from edit/delete by any other user except me (which i am the owner of the file).我希望这些包含特定文本值的单元格被锁定/防止被除我(我是文件的所有者)之外的任何其他用户编辑/删除。 If the date in second column (B) is deleted then the above script clears the text values and the cells should be available for editing from all users.如果删除第二列 (B) 中的日期,则上述脚本会清除文本值,并且单元格应可供所有用户编辑。

I've try many codes snippets to do this with no luck and the closest approach that i found is the bellow script, but it locks only one column and all the cells in that column.我尝试了许多代码片段来做到这一点,但没有运气,我发现最接近的方法是下面的脚本,但它只锁定一列和该列中的所有单元格。 Not only those with a specific value...不仅是那些具有特定价值的人...

function onEdit(event)
{
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = SpreadsheetApp.getActiveSheet();
  var CellRow = SpreadsheetApp.getActiveRange().getRow();
  var CellColumn = SpreadsheetApp.getActiveRange().getColumn();

  if (CellColumn == 7){
    sheet.getRange(CellRow, CellColumn).setValue("ENDED");
    Browser.msgBox("YOU CANNOT ADD DATA HERE!");
  }
}

Any idea how can i lock only the cells containing that specific text value ("ENDED") and unlock/un-protect them when that value it's cleared?.知道如何仅锁定包含该特定文本值(“ENDED”)的单元格并在该值被清除时解锁/取消保护它们吗?

The workflow would be as following:工作流程如下:

  • Incorporate a function that when run, protects all cells of your range with the content "ENDED"合并一个 function 运行时,使用内容“ENDED”保护您范围内的所有单元格
  • Modify your existing onEdit() function by adding additional code that will check if the content of a cell in column B has been deleted修改现有的 onEdit() function 通过添加额外的代码来检查 B 列中单元格的内容是否已被删除

Below is a sample:下面是一个示例:

function myStartFunction(){
  var sheets = SpreadsheetApp.getActive().getActiveSheet();
  //adapt according to your datarange
  var myRange=sheets.getRange(1,3,sheets.getLastRow(),sheets.getLastColumn());
  var values=myRange.getValues();
  for(var i=0;i<values.length;i++){
    for(var j=0;j<values[0].length;j++){
      if(values[i][j]=="ENDED"){
        var cell=myRange.getCell(i+1,j+1);
        var protection = cell.protect();
        protection.removeEditors(protection.getEditors());
      }
    }
  }       
}
function onEdit(e){
  //YOUR EXISTING CODE
  if (e.range.getColumn() == 2) {
    //User edited the date column
    if (typeof e.range.getValue() === typeof new Date()) {
      //Value of edit was a date
      endColumns(e.range.getRow(), e.range.getValue());
    } else if (e.range.getValue() === ""  || e.range.getValue() === null) {
      var sheets = SpreadsheetApp.getActiveSheet();
      // Delete all "ENDED" values:
      var resetRange = sheets.getRange(e.range.getRow(), e.range.getColumn() + 1, 1, sheets.getMaxColumns() - e.range.getColumn());
      var resetValues = resetRange.getValues()[0];
      for(var i = 0; i < resetValues.length; i++) {
        if(resetValues[i] == "ENDED") {
          var resetCell = sheets.getRange(e.range.getRow(), e.range.getColumn() + 1 + i);
          resetCell.clearContent();
        }
      }      
    }  
  }

  //HERE COMES THE ADDITIONAL PART
  if(e.range.getColumn() == 2 &&  e.oldValue != "" && e.range.getValue() == "") {
    var row=e.range.getRow();
    var sheets = SpreadsheetApp.getActiveSheet();
    var protections=sheets.getProtections(SpreadsheetApp.ProtectionType.RANGE);
    for (var i = 0; i < protections.length; i++) {
     var protection = protections[i];
     if (protection.getRange().getRow()==row) {
       protection.remove();
      }
    }
  }
}

UPDATE更新

To implement protection changes on each edit, you can modify the code as following:要在每次编辑时实施保护更改,您可以修改代码如下:

var sheets = SpreadsheetApp.getActiveSheet();

function Open(){
  var sheets = SpreadsheetApp.getActive().getActiveSheet();
  //adapt according to your datarange
  var myRange=sheets.getRange(3,3,sheets.getLastRow(),sheets.getLastColumn());
  var values=myRange.getValues();
  for(var i=0;i<values.length;i++){
    for(var j=0;j<values[0].length;j++){
      if(values[i][j]=="ENDED"){
        var cell=myRange.getCell(i+1,j+1);
        var protection = cell.protect();
        protection.removeEditors(protection.getEditors());
      }
    }
  }
}



function onEdit(e) {  
  if (e.range.getColumn() == 2) {
    //User edited the date column
    if (typeof e.range.getValue() === typeof new Date()) {
      //Value of edit was a date
      endColumns(e.range.getRow(), e.range.getValue());
      // wait until the function endColumns() finished
      SpreadsheetApp.flush();
      var myRange=sheets.getRange(e.range.getRow(),3,1,sheets.getLastColumn());
      var values=myRange.getValues();
      for(var j=0;j<values[0].length;j++){
        if(values[0][j]=="ENDED"){
          var cell=myRange.getCell(1,j+1);
          var protection = cell.protect();
          protection.removeEditors(protection.getEditors());
        }
      }      
    } else if (e.range.getValue() === ""  || e.range.getValue() === null) {
        // Delete all "ENDED" values:
        var resetRange = sheets.getRange(e.range.getRow(), e.range.getColumn() + 1, 1, sheets.getMaxColumns() - e.range.getColumn());
        var resetValues = resetRange.getValues()[0];
        for(var i = 0; i < resetValues.length; i++) {
          if(resetValues[i] == "ENDED") {
            var resetCell = sheets.getRange(e.range.getRow(), e.range.getColumn() + 1 + i);
            resetCell.clearContent();                                
          }
        }
      Logger.log('date removed');
      var row=e.range.getRow();
      var protections=sheets.getProtections(SpreadsheetApp.ProtectionType.RANGE);
      for (var i = 0; i < protections.length; i++) {
        var protection = protections[i];
        if (protection.getRange().getRow()==row) {
          protection.remove();
         }
       }      
     }  
  }
}
function endColumns(rowNum, limitDate) {
...
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 保护电子表格,然后使用脚本取消保护特定单元格和范围 - Protect spreadsheet then unprotect specific cells and ranges with script Google Spreadsheet Script有选择地保护某些单元格吗? - Google Spreadsheet Script to selectively protect certain cells? 在特定时间在其他单元格中自动锁定/保护Google表格中的行/单元格 - Automatic Lock/Protect Rows/cells in Google Sheets at a specific time in other Cells 保护电子表格中除单元格或单元格区域以外的所有内容 - Protect everything but the value of a cell or range of cells in a spreadsheet 根据同一行的另一个单元格中的日期,自动在 Google 电子表格的单元格中插入特定文本的脚本 - Script to automatically insert a specific text in cells of a Google spreadsheet, based on a date in another cell, on the same row 当电子表格未打开时,包含自定义函数的单元格将返回“ NaN”。 (访问Google电子表格的App Script Webapp) - Cells containing custom functions return “NaN'” when spreadsheet is not open. (Apps Script webapp accessing google spreadsheet) 在 Google 电子表格脚本中获取特定单元格值 - Get a specific cell value in a Google Spreadsheet Script Google电子表格脚本 - 将值移至特定单元格 - Google spreadsheet script - move value to specific cell Google 脚本锁定单元格 - Google Script Lock Cells 如何在Google Spreadsheet中获取包含特定值的最后一个条目 - How to get the last entry containing a certain value in Google Spreadsheet
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM