如何复制不受保护的单元格然后保护它们

时间:2019-08-28 13:07:58

标签: google-apps-script google-sheets

我每天需要一次(通过触发器)将数据从不受保护的单元从表1复制到表2。然后保护复制的单元格。第二天,只复制未受保护的新单元格中的数据,然后也对其进行保护。

我的问题是-我无法获得复制到Table2的正确范围。 请给一些建议

P.S。对不起,我的英语

表1-https://docs.google.com/spreadsheets/d/1fNshucMoC9wFjGKl9ZLvk2jw9yI2llKQ9dioGbO-F0s/edit?usp=sharing

表2-https://docs.google.com/spreadsheets/d/11AvUWe5vu6vHNXCPfXlK1Es3JLqQh13Fy_22l-obwP0/edit?usp=sharing

function protect_sales()
{
  // Connect to Table 1
  var sheetIncome = SpreadsheetApp.getActive().getSheetByName('Sales');
  var lastRow = sheetIncome.getLastRow(); 

  var protection = sheetIncome.protect();
  var unprotected = protection.getUnprotectedRanges();


  // Connect to Table 2
  var sss = SpreadsheetApp.openByUrl('https://docs.google.com/spreadsheets/d/11AvUWe5vu6vHNXCPfXlK1Es3JLqQh13Fy_22l-obwP0/edit');
  var ss = sss.getSheetByName('Sales');
  var lastSRow = ss.getLastRow();

  var target_range = ss.getRange(lastSRow+1,1,lastRow,5);

  ss.insertRowAfter(lastSRow);

  // Copy Data to Table 2
  ss.getRange(2,1).setValues(unprotected);

  // Protect our Range

  var dataRange = sheetIncome.getRange(1, 1, lastRow, 5)

  var protection = dataRange.protect().setDescription('protected range');

// Ensure the current user is an editor before removing others. Otherwise, if the user's edit
// permission comes from a group, the script throws an exception upon removing the group.
var me = Session.getEffectiveUser();
protection.addEditor(me);
protection.removeEditors(protection.getEditors());
if (protection.canDomainEdit()) {
  protection.setDomainEdit(false);
 }

}

1 个答案:

答案 0 :(得分:0)

您的脚本有几个问题

  1. 您将lastRow用作目标表中的行号,但是鉴于您只想复制新行,因此您的行号可能小于sheetIncome中的行总数。
      

    您需要定义一个startRow。一个优雅的解决方案是保存   前一个脚本中的lastRow作为Script property运行并使用   用于为新的复制过程定义新的StartRow

  2. 对于target_range中的set the values,您需要首先在表1中定义一个original_range,而无需指定该范围应受保护:
  var original_range=sheetIncome.getRange(startRow,1, rowNumber,5);
  var target_range = ss.getRange(targetlastRow+1,1,rowNumber,5);
  target_range.setValues(original_range.getValues());
  1. dataRange的保护应在代码末尾设置

这是一段代码,可从ScriptProperties检索每次运行的新起始行,并且如果自上次复制以来添加了新数据,它将复制新数据并更新表1的保护。最后,它将使用新的开始行更新脚本属性。还有第二个功能可以重置脚本属性并从第一行再次开始复制。请记住,如果范围受到保护,则该保护对电子表格所有者无效,仅对其他编辑者有效。

function protect_sales()
{
  // Connect to Table 1
  var sheetIncome = SpreadsheetApp.getActive().getSheetByName('Sales'); 
  var startRow = PropertiesService.getScriptProperties().getProperty('start');
  if(!startRow){
    startRow=1;
  }
  var lastRow = sheetIncome.getLastRow(); 
  var rowNumber = lastRow-startRow+1;
  //if there is new data in the sheet - copy it
  if(rowNumber>0)
  {
   // Connect to Table 2
   var sss = SpreadsheetApp.openByUrl('https://docs.google.com/spreadsheets/d/1TtpXaw4-vN8r-0i7WI7w9M005xxlFEkuThDI0tMTsVY/edit#gid=0');
   var ss = sss.getSheetByName('Sales');
   var targetlastRow = ss.getLastRow();
   var original_range=sheetIncome.getRange(startRow,1, rowNumber,5);
   var target_range = ss.getRange(targetlastRow+1,1,rowNumber,5);
   //following row not necessary
   //ss.insertRowAfter(lastSRow);

   // Copy Data to Table 2  
   target_range.setValues(original_range.getValues());                       

   // Protect our Range
   var dataRange = sheetIncome.getRange(1, 1, lastRow, 5)
   var protection = dataRange.protect().setDescription('protected range');

   // Ensure the current user is an editor before removing others. Otherwise, if the user's edit
   // permission comes from a group, the script throws an exception upon removing the group.
   var me = Session.getEffectiveUser();
   protection.addEditor(me);
   protection.removeEditors(protection.getEditors());
   if (protection.canDomainEdit()) {
    protection.setDomainEdit(false);
   }
  }
  PropertiesService.getScriptProperties().setProperty('start', lastRow+1);
}


function resetProperties(){
PropertiesService.getScriptProperties().deleteAllProperties();
}
  1. 如果您希望脚本每天自动运行,则可以设置time-driven trigger