【问题标题】:How to copy unprotected cells and then protect them如何复制未受保护的单元格然后保护它们
【发布时间】:2019-08-28 13:07:58
【问题描述】:

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

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

附:对不起我的英语

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

}

【问题讨论】:

  • 我想你可能对如何使用getUnprotectedRanges()有误解。所以我无法理解你的目标。关于ss.getRange(2,1).setValues(unprotected),在这种情况下,你想要unprotected的值是多少?
  • 你是对的。我不明白如何使用“getUnprotectedRanges()”。我需要新添加的和未受保护的行的日常副本(到 Table2),然后保护它们。

标签: google-apps-script google-sheets


【解决方案1】:

你的脚本有几个问题

  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的保护应该设置在代码末尾

这里的代码 sn-p 从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

【讨论】:

  • 我不知道“PropertiesService()”类。一切都很好!感谢您的时间! Огромное человеческое спасибо!
猜你喜欢
  • 1970-01-01
  • 2023-01-10
  • 1970-01-01
  • 1970-01-01
  • 2015-09-05
  • 2015-10-07
  • 1970-01-01
  • 1970-01-01
  • 2019-03-23
相关资源
最近更新 更多