防止谷歌脚本重复受保护的范围

时间:2017-03-03 19:22:09

标签: javascript google-apps-script duplicates range

我有这个脚本,我用来复制(将公式转换为值),然后在用户输入值时保护范围" Burned"在每个月末的某个单元格(A2,A6等)中(由于用户可能在稍微不同的日期完成数据输入,因此无法按日期触发)。电子表格需要用户每月锁定数据,因此脚本设置为每月转换和保护数据,因为用户输入" Burned"进入每个月。该脚本可以很好地将公式转换为值,并且还可以保护范围。但是,每次我编辑工作表时,它都会创建重复的受保护范围,因此我最终得到了多个受保护的范围,名为January Burned,February Burned等。有没有办法阻止脚本复制受保护的范围?非常感谢任何帮助。

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

2 个答案:

答案 0 :(得分:0)

你的代码中发生了一些奇怪的事情。所以我会像这样重新格式化:

//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');
  }
} 

再试一次,如果有任何变化,请告诉我。

再次查看你的代码。我抓住了整个代码并仔细研究了它,我做了一个有趣的发现。您的几个代码段不在函数onEdit中,因此即使未调用onEdit,它们也会在您每次访问脚本时运行。事实上,当我考虑它时,我相信你只是每月运行一次,所以为什么不把它放在一个单独的函数中,每月调用一次并忘记onEdit触发器。

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

因此,这是一个可以为您完成工作的功能的粗略开始,您可以每月运行一次。我没有测试它,它很可能有一些错误,所以检查出来。

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

答案 1 :(得分:0)

感谢所有的投入和帮助,我和一位能够编写这个脚本的同事交谈过,这个脚本效果很好。

    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');