Javascript 如何确保脚本块在下一个块之前先运行?
抱歉,如果这是一个基本的问题,但我只是不能让这个工作的方式,我需要 我的脚本基本上由3部分组成: 1) 。删除图纸中的所有保护 2) 。执行一些复制功能(由于范围受到保护,我需要先删除保护#1) 3) 。在#2完成后设置保护 这是我的密码: 首先清除保护Javascript 如何确保脚本块在下一个块之前先运行?,javascript,google-apps-script,google-sheets,Javascript,Google Apps Script,Google Sheets,抱歉,如果这是一个基本的问题,但我只是不能让这个工作的方式,我需要 我的脚本基本上由3部分组成: 1) 。删除图纸中的所有保护 2) 。执行一些复制功能(由于范围受到保护,我需要先删除保护#1) 3) 。在#2完成后设置保护 这是我的密码: 首先清除保护 var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('COST REPORT'); var protections = ss.getProtections(Spreadsh
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();
}
}
为了便于调试,我减少了一些脚本,但基本上我需要按照这个顺序逐个执行和完成脚本。如果您只是尝试按原样运行脚本,保护不会被删除,我会收到错误“尝试编辑保护范围…”
如果我自己运行每个块,那么它工作得很完美,但这包括用户必须运行的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);
}
};
功能移除保护(){
var ss=SpreadsheetApp.getActiveSpreadsheet().getSheetByName(“成本报告”);
var保护=ss.getProtections(电子表格应用程序保护类型范围);
对于(变量i=0;i<0.length;i++){
无功保护=保护[i];
if(protection.canEdit()){
保护。移除();
}
}
};
函数clearRangeData(){
var costReport=SpreadsheetApp.getActiveSpreadsheet().getSheetByName(
‘成本报告’;
costReport.getRange('F12:F16').clearContent();//理论
costReport.getRange('D20:D20').clearContent();//周结束日期
};
函数weeklyFileRangeProtection(){
//成本报告
var ss=SpreadsheetApp.getActive().getSheetByName(“成本报告”);
var costReportCOGS=ss.getRange('G11:G16');
var protection=costReportCOGS.protect().setDescription('costReportCOGS');
var me=Session.getEffectiveUser();
保护。加法器(me);
protection.removeditors(protection.getEditors());
if(protection.canDomainEdit()){
protection.setDomainEdit(false);
}
};
我相信您对这个问题有点误诊。代码已经按照正确的顺序运行,但由于谷歌底层架构的性质,在执行写调用之前,保护不会被删除
在这种情况下,将您引导到异步行为的注释是没有帮助的,它们从Javascript的角度来看是有意义的,但不是这里的问题,这是一个应用程序脚本/谷歌表单问题,您调用的所有函数都不是异步的
我有两个建议,一个是在移除保护后尝试调用SpreadsheetApp.flush()
。另一种方法是使用Utilities.sleep()
在执行remove()调用后,人工暂停脚本一段时间
我相信你对这个问题有点误诊。代码已经按照正确的顺序运行,但由于谷歌底层架构的性质,在执行写调用之前,保护不会被删除 在这种情况下,将您引导到异步行为的注释是没有帮助的,它们从Javascript的角度来看是有意义的,但不是这里的问题,这是一个应用程序脚本/谷歌表单问题,您调用的所有函数都不是异步的 我有两个建议,一个是在移除保护后尝试调用
SpreadsheetApp.flush()
。另一种方法是使用Utilities.sleep()
在执行remove()调用后,人工暂停脚本一段时间
您遇到了问题,因为对于您调用的每个函数
SpreadsheetApp.getActiveSpreadsheet
。每次你打这个电话时,你都会创建一个虚拟的spreadhseet“副本”,你对这个副本所做的更改只会在整个脚本完成后传递到Google服务器上的版本。因此,如果手动运行工作流所需的3个功能中的每一个:
运行函数1->脚本完成->更新服务器中的电子表格->运行函数2(现在获取更新的电子表格)->脚本完成->更新服务器中的电子表格->运行函数3(现在获取重新更新的电子表格)->脚本完成->更新服务器中的电子表格
现在,如果您运行这三个函数,脚本的方式如下所示:
var ss=SpreadsheetApp.getActiveSpreadsheet().getSheetByName('COST REPORT')代码>这将创建电子表格的虚拟副本->您的代码将从此副本中删除保护,并且服务器电子表格不会被修改->再次调用var costReport=SpreadsheetApp.getActiveSpreadsheet().getSheetByName('COST REPORT')代码>创建服务器电子表格的新副本,但尚未删除其保护->您的代码尝试清除此副本上的数据,这会触发错误
正如@Cameron Roberts在他的回答中所建议的那样,调用之间的Spreadsheet.flush()
将解决问题,因为if强制将更改同步到服务器中的电子表格。但是您将遇到另一个“问题”,即调用的副本数量,.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);
};
var ss=SpreadsheetApp.getActiveSpreadsheet();
var costReport=ss.getSheetByName(“成本报告”);
//第一个明确的保护
var protections=costReport.getProtections(SpreadsheetApp.ProtectionType.RANGE);
对于(变量i=0;i<0.length;i++){
无功保护=保护[i];
if(protection.canEdit()){
保护。移除();
};
};
//第二步清除单元格中的数据
costReport.getRange('F12:F16')。
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);
};