google-apps-script - 如何使用谷歌脚本锁定单元格?
问题描述
我有一个 Google 电子表格,可以与我的员工共享以记录每个订单的详细信息。这只是示例:
https://docs.google.com/spreadsheets/d/1r8_6S_jI-ZzL1GgZEur4ZVM51xqu3fWfnbFOHw3ZTZw/edit?usp=sharing
每次订单关闭时,我希望保护整个订单行以避免错误编辑。在示例文件中,我有一个从其他帖子中复制的脚本代码(我再也找不到了),但我和原始海报之间的需求有点不同,所以我编辑了范围,但我仍然无法做到完美的。
这是我需要的:
如果 G2 = 1,A2:F2 保护到只有所有者可以编辑。当 G2 为其他时,清除保护范围 A2:F2。我需要它在每一行做同样的事情,直到 2000 年。(G3 = 1 然后保护 A3:F3)(G4 = 1 然后保护 A4:F4)这样的事情直到 2000 行。
我希望将相同的代码应用于所有 4 个选项卡(Sheet1 到 Sheet4)
我发现在我当前的脚本中,如果 G2 = 1,每次我编辑某些内容时,它都会在同一范围 (A2:F2) 中添加一个新范围。我记得原来的帖子是 onOpen 但我必须让它 onEdit 以确保一切都得到很好的保护。
解决方案
也许这可以帮助你。首先考虑几点:
首先,创建 Range 不是一个快速的过程,它需要 0.5 到 1 秒,因此在 4 张纸上执行 2000 行(即 8000 行)需要 1 或 2 个小时,这远远超出了即使您是 Enterprise G Suite 用户,也有执行时间限制。
范围的主要问题是它们存储在 中SpreadsheetApp.ProtectionType.RANGE
,这会创建一个范围数组,因此为了在 G 不为 1 时删除特定范围,您必须将您编辑的行与范围数组的所有值进行比较。
每次编辑行时都会执行此脚本,如果它受到保护(G = 1)它什么也不做,如果它不是并且您更改 G = 1,那么它会保护该行的范围 A:F。如果更改 G 中的 1,则会删除保护。因此,这不会保护或取消保护 4 张工作表中的每一行,它只会保护或取消保护您在任何工作表中编辑的行。
function onEdit() {
var sprsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = sprsheet.getActiveSheet();
var protections = sheet.getProtections(SpreadsheetApp.ProtectionType.RANGE);
var col_G = sheet.getRange("G2:G2000").getValues();
var edited_row = sheet.getActiveRange().getRow();
var protected = false;
var range_pos;
modifyProtection(edited_row, protections, col_G, sheet, protected);
}
function modifyProtection(edited_row, protections, col_G, sheet, protected, range_pos){
if (protections.length == 0 && col_G[edited_row - 2] == 1){ //In case there aren't ranges yet
createRange(edited_row, sheet);
} else {
for (var i = 0; i < protections.length; i++){
if (edited_row == protections[i].getRange().getRow()){
range_pos = i;
protected = true;
}
}
if (protected && col_G[edited_row - 2] != 1){
protected = false;
deleteRange(range_pos, protections);
} else {
if (!protected && col_G[edited_row - 2] == 1){
protected = true;
createRange(edited_row, sheet);
}
}
}
}
function createRange(edited_row, sheet, protected){
var range = sheet.getRange('A'+(edited_row)+':F'+(edited_row));
var protection = range.protect().setDescription('Sample protected range');
var me = 'your_email';//This will be the only editor of the protected ranges
protection.addEditor(me);
protection.removeEditors(protection.getEditors());
if (protection.canDomainEdit()) {
protection.setDomainEdit(false);
}
}
function deleteRange(i, protections){
protections[i].remove();
}
推荐阅读
- javascript - 使用 PerformanceObserver API 获取和保存数据以供进一步使用类 - JS
- database - 获取具有至少两个值的文档,用于数组中的特定条件,在 MongoDB 中查询
- jekyll - Jekyll 重定向到 404 并且不渲染 post.md
- c - 如何在C中一次清除多个位?
- qt - Qml 使用 mouseAera 获取 listElement 的文本
- mysql - 在 mysql DB 中创建视图时如何将行号作为列?
- snowflake-cloud-data-platform - 我们如何使用 Azure AD 使用 DB Visualizer 连接到雪花
- neo4j - 在 Cypher 中透视数据
- python - 在多个环境中使用一个 IPython
- python - 从数据框python散点图多列