簡體   English   中英

鎖定/保護包含特定文本值的整個 Google 電子表格中的單元格

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

我有以下腳本(來自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();
    }
  }
}

我希望這些包含特定文本值的單元格被鎖定/防止被除我(我是文件的所有者)之外的任何其他用戶編輯/刪除。 如果刪除第二列 (B) 中的日期,則上述腳本會清除文本值,並且單元格應可供所有用戶編輯。

我嘗試了許多代碼片段來做到這一點,但沒有運氣,我發現最接近的方法是下面的腳本,但它只鎖定一列和該列中的所有單元格。 不僅是那些具有特定價值的人...

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!");
  }
}

知道如何僅鎖定包含該特定文本值(“ENDED”)的單元格並在該值被清除時解鎖/取消保護它們嗎?

工作流程如下:

  • 合並一個 function 運行時,使用內容“ENDED”保護您范圍內的所有單元格
  • 修改現有的 onEdit() function 通過添加額外的代碼來檢查 B 列中單元格的內容是否已被刪除

下面是一個示例:

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();
      }
    }
  }
}

更新

要在每次編輯時實施保護更改,您可以修改代碼如下:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM