Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/389.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何确保脚本块在下一个块之前先运行?_Javascript_Google Apps Script_Google Sheets - Fatal编程技术网

Javascript 如何确保脚本块在下一个块之前先运行?

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

抱歉,如果这是一个基本的问题,但我只是不能让这个工作的方式,我需要

我的脚本基本上由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();
    }
}
为了便于调试,我减少了一些脚本,但基本上我需要按照这个顺序逐个执行和完成脚本。如果您只是尝试按原样运行脚本,保护不会被删除,我会收到错误“尝试编辑保护范围…”

如果我自己运行每个块,那么它工作得很完美,但这包括用户必须运行的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);
 };