我有一个基本上由3部分组成的脚本:
1)。删除表格中的所有保护
2)。执行一些复制功能(因为范围受到保护,我需要首先删除保护#1)
3)。在#2完成后设置保护备份。
这是我的代码:
首先清除保护
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('COST REPORT');
var protections = ss.getProtections(SpreadsheetApp.ProtectionType.RANGE);
for (var i = 0; i < protections.length; i++) {
var protection = protections[i];
if (protection.canEdit()) {
protection.remove();
}
}
第二次清除单元格中的数据
var costReport = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(
'COST REPORT');
costReport.getRange('F12:F16').clearContent(); //Theoreticals
costReport.getRange('D20:D20').clearContent(); //Week Ending Date
Third sets protection
var ss = SpreadsheetApp.getActive().getSheetByName('COST REPORT');
var costReportCOGS = ss.getRange('G11:G16');
var protection = costReportCOGS.protect().setDescription('costReportCOGS');
var me = Session.getEffectiveUser();
protection.addEditor(me);
protection.removeEditors(protection.getEditors());
if (protection.canDomainEdit()) {
protection.setDomainEdit(false);
}
var costReportPurchaseEnding = ss.getRange('D11:E16');
var protection = costReportPurchaseEnding.protect().setDescription(
'costReportPurchaseEnding');
var me = Session.getEffectiveUser();
protection.addEditor(me);
protection.removeEditors(protection.getEditors());
if (protection.canDomainEdit()) {
protection.setDomainEdit(false);
}
为了便于调试,我已经删除了一些脚本,但基本上我需要脚本来执行&amp;按顺序完成,一个接一个。如果您只是尝试按原样运行脚本,则保护不会被删除,我收到错误“尝试编辑受保护范围....”
如果我自己运行每个块然后它工作得很完美,但它包含用户必须运行的3个不同的脚本,我需要一个一个。
提前致谢!
肖恩。
这样的东西?
function removeProtection() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('COST REPORT');
var protections = ss.getProtections(SpreadsheetApp.ProtectionType.RANGE);
for (var i = 0; i < protections.length; i++) {
var protection = protections[i];
if (protection.canEdit()) {
protection.remove();
}
}
};
function clearRangeData() {
var costReport = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(
'COST REPORT');
costReport.getRange('F12:F16').clearContent(); //Theoreticals
costReport.getRange('D20:D20').clearContent(); //Week Ending Date
};
function weeklyFileRangeProtection() {
//COST REPORT
var ss = SpreadsheetApp.getActive().getSheetByName('COST REPORT');
var costReportCOGS = ss.getRange('G11:G16');
var protection = costReportCOGS.protect().setDescription('costReportCOGS');
var me = Session.getEffectiveUser();
protection.addEditor(me);
protection.removeEditors(protection.getEditors());
if (protection.canDomainEdit()) {
protection.setDomainEdit(false);
}
};
答案 0 :(得分:2)
我相信你误解了这个问题。代码已经按正确的顺序运行,但由于Google底层架构的性质,在执行写调用之前根本没有删除保护。
指向异步行为的评论在这种情况下没有帮助,从Javascript角度来看它们确实有意义,但这里不是问题,这是一个Apps脚本/ Google表格问题,你调用的函数都不是异步的。
我有两条建议,一条是在删除保护措施后尝试拨打SpreadsheetApp.flush()
。另一种是在执行remove()调用后,使用Utilities.sleep()
人为地暂停脚本一小段时间。
https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet-app#flush()
https://developers.google.com/apps-script/reference/utilities/utilities#sleep(Integer)
答案 1 :(得分:2)
您遇到问题,因为您呼叫的每个功能都SpreadsheetApp.getActiveSpreadsheet
。每次拨打此电话,您都会创建一个虚拟&#34;副本&#34;对于spreadhseet,您对此副本所做的更改只会在整个脚本完成后传递到Google服务器中的版本。因此,如果您手动运行工作流程的每个3函数:
运行功能1 - &gt;脚本完成 - &gt;更新服务器中的电子表格 - &gt;运行功能2(现在获取更新的电子表格) - &gt;脚本完成 - &gt;更新服务器中的电子表格 - &gt;运行功能3(现在获得重新更新的电子表格) - &gt;脚本完成 - &gt;更新服务器中的电子表格
现在,如果你运行这三个函数,脚本在这里的方式就是:
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('COST REPORT');
这会创建电子表格的虚拟副本 - &gt;您的代码会从此副本中删除保护,并且不会修改服务器电子表格 - &gt;您再次致电var costReport = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('COST REPORT');
,这会创建服务器电子表格的新副本,但尚未删除其保护措施 - &gt;您的代码会尝试清除此副本上的数据,从而触发错误。
正如@Cameron Roberts在他的回答Spreadsheet.flush()
中建议的那样,调用将解决问题,因为如果强制将更改同步到服务器中的电子表格中。但是你会遇到另一个&#34;问题&#34;,这是你打电话的副本量,.getActiveSpreadsheet()
非常耗时!最好只进行一次调用,存储在变量中(您已经这样做,它是变量ss
)并对其进行所有编辑。
您的代码最终会如下所示:
var ss = SpreadsheetApp.getActiveSpreadsheet();
var costReport = ss.getSheetByName('COST REPORT');
//First clear protection
var protections = costReport.getProtections(SpreadsheetApp.ProtectionType.RANGE);
for (var i = 0; i < protections.length; i++) {
var protection = protections[i];
if (protection.canEdit()) {
protection.remove();
};
};
//Second clears data in cells
costReport.getRange('F12:F16').clearContent(); //Theoreticals
costReport.getRange('D20:D20').clearContent(); //Week Ending Date
//Third sets protection
var costReportCOGS = costReport.getRange('G11:G16');
var protection = costReportCOGS.protect().setDescription('costReportCOGS');
var me = Session.getEffectiveUser();
protection.addEditor(me);
protection.removeEditors(protection.getEditors());
if (protection.canDomainEdit()) {
protection.setDomainEdit(false);
};
var costReportPurchaseEnding = costReport.getRange('D11:E16');
var protection = costReportPurchaseEnding.protect().setDescription(
'costReportPurchaseEnding');
var me = Session.getEffectiveUser();
protection.addEditor(me);
protection.removeEditors(protection.getEditors());
if (protection.canDomainEdit()) {
protection.setDomainEdit(false);
};
此方法也适用于Google Docs,它没有类似的.flush()
方法来更新服务器版本。