如果,如您在 cmets 中所述,您使用 可在编辑触发器上安装,您描述的问题应该不会发生,因为 “当脚本运行时触发器,脚本使用安装触发器的人的身份运行,而不是其操作触发事件的用户的身份。这是出于安全原因。例如,如果您在脚本中安装触发器,但您的同事执行触发事件的操作时,脚本会以您的身份运行,而不是您同事的身份。有关这方面的完整信息,请参阅了解权限和脚本执行。"
见文档here
编辑:抱歉,我没有看到关于这种特殊情况的问题:issue 1562 posted on july 2012, status "triaged"
编辑 2:我尝试了 @tracon6 建议暂时删除保护,但它也不起作用......脚本在尝试应用保护时生成错误。
但是
作为 EDIT 3
我找到了一个可行的解决方法!我们可以在写入 targetSheet 时添加一个编辑器,然后在之后立即删除它......在它之间使用 flush 可以工作。
这是我用来测试的代码:
function onEditInstallable(event) {
var sheet = event.source.getActiveSheet();
if(sheet.getName()=='Sheet1'){return};
var r = event.source.getActiveRange();
var column = r.getColumn();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var targetSheet = ss.getSheetByName("TFA");
var targetSheet = ss.getSheetByName("Sheet1");
var user = SpreadsheetApp.getActive().getEditors()[1];
var permission = targetSheet.getSheetProtection();
permission.addUser(user);
targetSheet.setSheetProtection(permission);
SpreadsheetApp.flush();
targetSheet.getRange(1,column).setValue('value change on sheet 2, column : '+column);
SpreadsheetApp.flush();
permission.removeUser(user)
targetSheet.setSheetProtection(permission)
}
编辑 4:
由于似乎许多编辑者都可以访问这些工作表(请参阅最后的 cmets),因此必须有一种方法可以知道谁在电子表格上处于活动状态。在非域环境中,使用触发函数是不可能的,因此我建议使用带有列表的小型 uiApp,用户必须从中选择,使用可安装的 onOpen 触发它,并将值存储在主函数中使用它。
这是处理该方面的一段代码。
function SpecialonOpen(){
var s = SpreadsheetApp.getActive();
var app = UiApp.createApplication().setTitle('Please select your email in this list').setWidth(300).setHeight(300);
var list = app.createListBox().setName('list')
var editors = s.getEditors();
for(var n in editors){
list.addItem(editors[n].getEmail());
}
var handler = app.createServerHandler('getMail').addCallbackElement(list);
var btn = app.createButton('select',handler);
s.show(app.add(list).add(btn))
}
function getMail(e){
var email = e.parameter.list;
var editors = ScriptProperties.getProperty('currentEditors')||' ';
if(editors.indexOf(email)==-1){
editors+=(','+email);
ScriptProperties.setProperty('currentEditors',editors);
}
var app = UiApp.getActiveApplication().close();
var editors = ScriptProperties.getProperty('currentEditors').split(',');
if(editors[0].length<2){editors.splice(0,1)};
Logger.log(editors)
return app
}
您还应该添加一个功能来在某个时刻重置此列表...不知道什么是最好的?也许每天都有?我会把这个交给你;-)