在单元格中输入值时如何延迟单元格保护?
How to delay cell protection when value is entered in a cell?
我在第一次输入数据后使用了以下 OnEdit() 触发代码来锁定单元格:
function LockCells(event){
var range = event.range;
var description = 'Protected'; // + stringDate;
var protection = range.protect().setDescription(description);
var me = Session.getEffectiveUser();
protection.addEditor(me);
protection.removeEditors(protection.getEditors());
if (protection.canDomainEdit()) {
protection.setDomainEdit(false);
}
}
当我以用户身份(不是 sheet 管理员)在单元格中输入值时,它会立即阻止单元格重新输入值。我们可以延迟这个过程吗?我的意思是,如果我们现在输入值,但在 10 分钟或 1 小时后而不是立即应用该单元的保护?
我相信你的目标如下。
- 您的
LockCells
功能由 OnEdit 可安装触发器执行。
- 您想运行 函数
LockCells
中的脚本在OnEdit 触发器之后是运行。
在这种情况下,下面的修改脚本怎么样?
修改后的脚本 1:
比如当OnEdit触发器为运行时,当你想运行函数中的脚本LockCells
后大概6分钟,修改后的脚本可以有点简单如下
function LockCells(event) {
Utilities.sleep(5 * 60 * 1000); // For example, after 5 minutes, the script is run.
var range = event.range;
var description = 'Protected'; // + stringDate;
var protection = range.protect().setDescription(description);
var me = Session.getEffectiveUser();
protection.addEditor(me);
protection.removeEditors(protection.getEditors());
if (protection.canDomainEdit()) {
protection.setDomainEdit(false);
}
}
修改后的脚本 2:
当你想运行函数中的脚本LockCells
超过6分钟后,修改后的脚本如下。请将以下脚本复制并粘贴到电子表格的脚本编辑器中。并且,请将 OnEdit 可安装触发器重新安装到函数 LockCells
。这样,当您编辑单元格时,在这个示例脚本中,编辑的单元格会在 10 分钟后受到保护。
var time = 10 * 60 * 1000; // 10 minutes
function LockCells(event) {
var date = new Date().getTime();
var range = event.range;
var a1Notation = `'${range.getSheet().getSheetName()}'!${range.getA1Notation()}`;
var p = PropertiesService.getScriptProperties();
var ranges = p.getProperty("ranges");
ranges = ranges ? JSON.parse(ranges).concat({ date, a1Notation }) : [{ date, a1Notation }];
p.setProperty("ranges", JSON.stringify(ranges));
ScriptApp.newTrigger("lockCellsByTrigger").timeBased().after(time).create();
}
function lockCellsByTrigger(e) {
ScriptApp.getScriptTriggers().forEach(t => {
if (t.getUniqueId() == e.triggerUid) ScriptApp.deleteTrigger(t);
});
var limit = time;
var now = new Date().getTime();
var p = PropertiesService.getScriptProperties();
var ranges = p.getProperty("ranges");
if (!ranges) return;
ranges = JSON.parse(ranges);
var {rranges, r} = ranges.reduce((o, e) => {
o[e.date + limit < now ? "rranges" : "r"].push(e);
return o;
}, {rranges: [], r: []});
if (rranges.length == 0) return;
p.setProperty("ranges", JSON.stringify(r));
var description = 'Protected';
var me = Session.getEffectiveUser();
rranges.forEach(({a1Notation}) => {
var protection = SpreadsheetApp.getActiveSpreadsheet().getRange(a1Notation).protect().setDescription(description);
protection.addEditor(me);
protection.removeEditors(protection.getEditors());
if (protection.canDomainEdit()) {
protection.setDomainEdit(false);
}
});
}
- 如果要更改时间,请修改
time
。当前阶段,10分钟后,编辑的单元格被保护。
- 这个脚本的流程如下。
- 编辑单元格时,
LockCells
由可安装的 OnEdit 触发器 运行。
- 将编辑单元格的a1Notation和日期放入Properties Service,10分钟后安装时间驱动触发器。
- 当时间驱动触发器 运行 函数
lockCellsByTrigger
时,10 分钟后编辑的单元格受到保护。
参考文献:
我在第一次输入数据后使用了以下 OnEdit() 触发代码来锁定单元格:
function LockCells(event){
var range = event.range;
var description = 'Protected'; // + stringDate;
var protection = range.protect().setDescription(description);
var me = Session.getEffectiveUser();
protection.addEditor(me);
protection.removeEditors(protection.getEditors());
if (protection.canDomainEdit()) {
protection.setDomainEdit(false);
}
}
当我以用户身份(不是 sheet 管理员)在单元格中输入值时,它会立即阻止单元格重新输入值。我们可以延迟这个过程吗?我的意思是,如果我们现在输入值,但在 10 分钟或 1 小时后而不是立即应用该单元的保护?
我相信你的目标如下。
- 您的
LockCells
功能由 OnEdit 可安装触发器执行。 - 您想运行 函数
LockCells
中的脚本在OnEdit 触发器之后是运行。
在这种情况下,下面的修改脚本怎么样?
修改后的脚本 1:
比如当OnEdit触发器为运行时,当你想运行函数中的脚本LockCells
后大概6分钟,修改后的脚本可以有点简单如下
function LockCells(event) {
Utilities.sleep(5 * 60 * 1000); // For example, after 5 minutes, the script is run.
var range = event.range;
var description = 'Protected'; // + stringDate;
var protection = range.protect().setDescription(description);
var me = Session.getEffectiveUser();
protection.addEditor(me);
protection.removeEditors(protection.getEditors());
if (protection.canDomainEdit()) {
protection.setDomainEdit(false);
}
}
修改后的脚本 2:
当你想运行函数中的脚本LockCells
超过6分钟后,修改后的脚本如下。请将以下脚本复制并粘贴到电子表格的脚本编辑器中。并且,请将 OnEdit 可安装触发器重新安装到函数 LockCells
。这样,当您编辑单元格时,在这个示例脚本中,编辑的单元格会在 10 分钟后受到保护。
var time = 10 * 60 * 1000; // 10 minutes
function LockCells(event) {
var date = new Date().getTime();
var range = event.range;
var a1Notation = `'${range.getSheet().getSheetName()}'!${range.getA1Notation()}`;
var p = PropertiesService.getScriptProperties();
var ranges = p.getProperty("ranges");
ranges = ranges ? JSON.parse(ranges).concat({ date, a1Notation }) : [{ date, a1Notation }];
p.setProperty("ranges", JSON.stringify(ranges));
ScriptApp.newTrigger("lockCellsByTrigger").timeBased().after(time).create();
}
function lockCellsByTrigger(e) {
ScriptApp.getScriptTriggers().forEach(t => {
if (t.getUniqueId() == e.triggerUid) ScriptApp.deleteTrigger(t);
});
var limit = time;
var now = new Date().getTime();
var p = PropertiesService.getScriptProperties();
var ranges = p.getProperty("ranges");
if (!ranges) return;
ranges = JSON.parse(ranges);
var {rranges, r} = ranges.reduce((o, e) => {
o[e.date + limit < now ? "rranges" : "r"].push(e);
return o;
}, {rranges: [], r: []});
if (rranges.length == 0) return;
p.setProperty("ranges", JSON.stringify(r));
var description = 'Protected';
var me = Session.getEffectiveUser();
rranges.forEach(({a1Notation}) => {
var protection = SpreadsheetApp.getActiveSpreadsheet().getRange(a1Notation).protect().setDescription(description);
protection.addEditor(me);
protection.removeEditors(protection.getEditors());
if (protection.canDomainEdit()) {
protection.setDomainEdit(false);
}
});
}
- 如果要更改时间,请修改
time
。当前阶段,10分钟后,编辑的单元格被保护。 - 这个脚本的流程如下。
- 编辑单元格时,
LockCells
由可安装的 OnEdit 触发器 运行。 - 将编辑单元格的a1Notation和日期放入Properties Service,10分钟后安装时间驱动触发器。
- 当时间驱动触发器 运行 函数
lockCellsByTrigger
时,10 分钟后编辑的单元格受到保护。
- 编辑单元格时,