简体   繁体   中英

Prevent google script from duplicating protected ranges

I have this script that I am using to copy over (convert formulas to values) and then protect the range when a user enters a value "Burned" in to a certain cell (A2, A6, etc) at the end of each month (can't make it triggered by date as users may be completing data entry on slightly different dates). The spreadsheet needs users to lock the data every month, so the script is set up for converting and protecting data each month as the user enters "Burned" into each month. The script is working well to convert formulas to values and it is also working to protect the range. However, every time I edit the sheet, it creates duplicate protected ranges so I end up with multiple protected ranges called January Burned, February Burned, etc. Is there any way to prevent the script from duplicating the protected ranges? Any help is greatly appreciated.

function onEdit(e)
//January
{
var ss = SpreadsheetApp.getActive();
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Caseload");
var valueToCheckA = sheet.getRange("A2").getValue();
var rangeA = sheet.getRange("A2:AZ5");  
{
if(valueToCheckA == "Burned")
{
rangeA.copyTo(rangeA, {contentsOnly:true});
var protection = rangeA.protect().setWarningOnly(true).setDescription('January Burned');
}
}
} 

//February
{
var ss = SpreadsheetApp.getActive();
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Caseload");
var valueToCheckB = sheet.getRange("A6").getValue();
var rangeB = sheet.getRange("A6:AZ9");  
{
if(valueToCheckB == "Burned")
{
rangeB.copyTo(rangeB, {contentsOnly:true});
var protection = rangeB.protect().setWarningOnly(true).setDescription('February Burned');
}
}
} 

//March
{
var ss = SpreadsheetApp.getActive();
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Caseload");
var valueToCheckC = sheet.getRange("A10").getValue();
var rangeC = sheet.getRange("A10:AZ13");  
{
if(valueToCheckC == "Burned")
{
rangeC.copyTo(rangeC, {contentsOnly:true});
var protection = rangeC.protect().setWarningOnly(true).setDescription('March Burned');
}
}
} 

You had some weird things going on in your code. So I'd reformat it like this:

//January
function onEdit(e)
{
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Caseload");
  var valueToCheckA = sheet.getRange("A2").getValue();
  var rangeA = sheet.getRange("A2:AZ5");  
  if(valueToCheckA == "Burned")
  {
    rangeA.copyTo(rangeA, {contentsOnly:true});
    var protection = rangeA.protect().setWarningOnly(true).setDescription('January Burned');
  }
} 

Try it again and let me know if anything has changed.

After looking over you code again. I grabbed entire code and took a close look at it and I made an interesting discovery. Several of your sections of code are not within the function onEdit so they run every time you access your scripts even when onEdit is not called. In fact, when I think about it, I believe you just run this once a month so why not just put it in a separate function and call once a month and forget the onEdit trigger.

function onEdit(e)
{
  var ss = SpreadsheetApp.getActive();//January
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Caseload");
  var valueToCheckA = sheet.getRange("A2").getValue();
  var rangeA = sheet.getRange("A2:AZ5");  
  if(valueToCheckA == "Burned")
  {
    rangeA.copyTo(rangeA, {contentsOnly:true});
    var protection = rangeA.protect().setWarningOnly(true).setDescription('January Burned');
  }
} 
// This section is not in the onEdit function so it's run every time you come to this page
var ss = SpreadsheetApp.getActive();//February
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Caseload");
var valueToCheckB = sheet.getRange("A6").getValue();
var rangeB = sheet.getRange("A6:AZ9");  
if(valueToCheckB == "Burned")
{
    rangeB.copyTo(rangeB, {contentsOnly:true});
    var protection = rangeB.protect().setWarningOnly(true).setDescription('February Burned');
}

// This section is not in the onEdit function so it's run every time you come to this page 
var ss = SpreadsheetApp.getActive();//March
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Caseload");
var valueToCheckC = sheet.getRange("A10").getValue();
var rangeC = sheet.getRange("A10:AZ13");  
if(valueToCheckC == "Burned")
{
  rangeC.copyTo(rangeC, {contentsOnly:true});
  var protection = rangeC.protect().setWarningOnly(true).setDescription('March Burned');
}

So here's a rough start of a function that could do the job for you and you can just run it once a month. I haven't tested it and it most likely has some mistakes in it so check it out.

function monthlyBurn()
{
  var ui = SpreadsheetApp.getUi();
  var response = ui.prompt('Enter checkCell,protectRange,description all separate by commas', ui.ButtonSet.OK);
  var t = response.getResponseText().split(',');
  if(t.length !== 3)
  {
   ui.alert('Invalid input. Your missing a parameter')
   return;
  }
  var ss = SpreadsheetApp.getActive();
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Caseload");
  var valueToCheckC = sheet.getRange(t[0]).getValue();
  var rangeC = sheet.getRange(t[1]);  
  if(valueToCheckC == "Burned")
  {
    rangeC.copyTo(rangeC, {contentsOnly:true});
    var protection = rangeC.protect().setWarningOnly(true).setDescription(t[2]);
  }
}

Thanks for all the input and assistance, I have spoken with a colleague who was able to write this script which is working great.

    function onEdit(e)
{
  var sheet = e.range.getSheet();
  if (sheet.getName() != "Caseload" || e.value != "Burned") return;

  var moment = Moment.load();
  var date = moment.utc(e.range.offset(0, 1).getValue());
  if (!date.isValid()) return;

  var month = date.format('MMMM');
  var range = sheet.getRange(e.range.getRow(), e.range.getColumn(), 4, 26*2); // 4 rows and 26*2 columns (AZ)
  range.copyTo(range, {contentsOnly: true});
  range.protect().setWarningOnly(true).setDescription(month + ' Burned');

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