【问题标题】:How to create trigger to run multiple function in parallel (passing parameter)如何创建触发器以并行运行多个函数(传递参数)
【发布时间】:2019-07-16 09:03:38
【问题描述】:

我有一个函数要运行多次,以减少函数的大修处理:

function ModifyVAxisChartThreading(){
  var nbChart=39;
   i++;
   for(var j=i;j<nbChart;j+=4)
  {
    Vmax=rangeMax[j*6];
    Vmin=rangeMinId[j*6];
    id=rangeMinId[(j*6)+1];
    var delta=(Vmax-Vmin)*0.1;
    Logger.log("Vmax="+Vmax+"Vmin="+Vmin+"id="+id+"i="+j);
    var currChart = chart[id];
    if(currChart.getType()!="COLUMN")
    {
      Vmin-=delta
      Vmax=Number(Vmax)+(delta*1.5)//Number() function to avoid Vmax becoming a string for no reason
    }
    Logger.log("Vmax="+Vmax+"Vmin="+Vmin+"id="+id+"j="+j);
     currChart = currChart.modify()
      .setOption('vAxes', {0: {textStyle: {fontSize: 10}, titleTextStyle: {fontSize : 8}, viewWindow: {min: Vmin, max:Vmax}}})//adpative vaxis for AREA and COMBO
      .build();
    sheet.updateChart(currChart);
  }

}

我已经创建了一个函数test(),它创建了两个触发器,但触发器只运行函数 ModifyVAxisChartThreading() 具有相同的基值 i (0)。

function test(){
  //delete all previous trigger
  var allTriggers = ScriptApp.getProjectTriggers();
  for (var i = 0; i < allTriggers.length; i++) {
      ScriptApp.deleteTrigger(allTriggers[i]);

  }
 i=-1;
  var ss=SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Dashboard Data");
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Dashboard");
 rangeMax =ss.getRange("O3:O231").getValues();//Range to modify if you add charts
 rangeMinId=ss.getRange("P3:P232").getValues();//Range to modify if you add charts
 chart = sheet.getCharts();
 var nbChart=19;
  Logger.log("range Max ="+rangeMax + "autre="+rangeMinId);
 //create the trigger to run the function ModifyVAxisChartThreading in parallel
 for(var j=0;j<4;j++)
  {
  Utilities.sleep(1000);
  var testTrigger =ScriptApp.newTrigger("ModifyVAxisChartThreading")
  .timeBased()
  .after((1) * 60 * 1000)
  .create();
  Logger.log(testTrigger.getUniqueId());
  }
}

这是我的全局变量:

var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Dashboard");
var ss=SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Dashboard Data");
var rangeMax =ss.getRange("O3:O231").getValues();//Range to modify if you add charts
var rangeMinId=ss.getRange("P3:P232").getValues();//Range to modify if you add charts
var i=-1;
var  chart = sheet.getCharts();

【问题讨论】:

  • 您是否尝试过复制+粘贴函数并更改条件以使奇数和偶数有一个(例如ModifyVAxisChartThreadingOdd()ModifyVAxisChartThreadingEven()),然后添加两个Edit -&gt; Current project's triggers 页面上的可安装触发器让它们在同一个触发器上运行?不过,我不知道 Installable 触发器事件类型是否对您有用,您希望什么时候能够运行它?
  • 我不想这样做但是,我终于想出了如何实现我想要的,我应该在这个帖子上发布我的解决方案
  • 请发布您的解决方案作为答案,这对文档和整个社区都有好处。

标签: multithreading google-apps-script google-sheets triggers


【解决方案1】:

好的,所以我找到了为我的函数运行多线程的解决方案。这里是:

var RECURRING_KEY = "recurring";//variable for 
var ARGUMENTS_KEY = "arguments";//passing argument to trigger
var nbThread =2;//nb of trigger for the function for one sheet

function ModifyVAxisChartThreading(e){
  var scriptProperties = PropertiesService.getScriptProperties();
  var triggerId = e.triggerUid;
  var triggerData = JSON.parse(scriptProperties.getProperty(e.triggerUid));
  var sheetName=triggerData[ARGUMENTS_KEY];//get the string argument of the trigger
  var ss=SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName+"Dashboard Data");
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName+"Dashboard");
  var nbChart=39;
  var rangeMax =ss.getRange("O3:O231").getValues();//Range to modify if you add charts
  var rangeMinId=ss.getRange("P3:P232").getValues();//Range to modify if you add charts
  var chart = sheet.getCharts();
  var Vmax=0; var Vmin=0;var id=-1;var delta=0;
  for(var j=triggerData[RECURRING_KEY]/*get the int argument*/;j<nbChart;j+=nbThread)
  {
    Vmax=rangeMax[j*6];
    Vmin=rangeMinId[j*6];
    id=rangeMinId[(j*6)+1];
    delta=(Vmax-Vmin)*0.1;
    Logger.log("Vmax="+Vmax+"Vmin="+Vmin+"id="+id+"i="+j);
    var currChart = chart[id];
    if(currChart.getType()!="COLUMN")
    {
      Vmin-=delta
      Vmax=Number(Vmax)+(delta*1.5)//Number() function to avoid Vmax becoming a string for no reason
    }
    Logger.log("Vmax="+Vmax+"Vmin="+Vmin+"id="+id+"j="+j);
     currChart = currChart.modify()
      .setOption('vAxes', {0: {textStyle: {fontSize: 10}, titleTextStyle: {fontSize : 8}, viewWindow: {min: Vmin, max:Vmax}}})//adpative vaxis for AREA and COMBO
      .build();
    sheet.updateChart(currChart);
  }
}

//This is the function that create all the triggers to parallelize the function MofifyVAxisChartThreading() 
function test(){
  //delete all previous trigger
  var allTriggers = ScriptApp.getProjectTriggers();
  for (var i = 0; i < allTriggers.length; i++) {
      ScriptApp.deleteTrigger(allTriggers[i]);

  }
  var sheetNames=["sheet0 ","sheet1 ","sheet2 ","sheet3 ","sheet4 ","sheet5 ","sheet6 ","sheet7 ","sheet8 "];
 //create the trigger to run the function ModifyVAxisChartThreading in parallel
 for(var z=0;z<sheetNames.length;z++)//create nbThread triggers for every sheets
 {
   for(var j=0;j<nbThread;j++)
   {
     Utilities.sleep(1000);
     var testTrigger =ScriptApp.newTrigger("ModifyVAxisChartThreading")
     .timeBased()
     .after((0.15) * 60 * 1000)
     .create();
     Logger.log(testTrigger.getUniqueId());
     var triggerData = {};
     triggerData["i"] = j ;
     setupTriggerArguments(testTrigger, sheetNames[z], j);//pass the parameters to the trigger
   }
 }
}
//this function pass the parameters in the properties of the trigger
function setupTriggerArguments(trigger, functionArguments, recurring) {
  var triggerUid = trigger.getUniqueId();
  var triggerData = {};
  triggerData[RECURRING_KEY] = recurring;
  triggerData[ARGUMENTS_KEY] = functionArguments;
  PropertiesService.getScriptProperties().setProperty(triggerUid, JSON.stringify(triggerData));
}

传递参数的代码受到此链接代码的极大启发:How can I pass a parameter to a time-based Google App Script trigger?

【讨论】:

    猜你喜欢
    • 2011-09-05
    • 1970-01-01
    • 2013-12-20
    • 1970-01-01
    • 1970-01-01
    • 2016-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多