Google Sheets 脚本:从脚本函数获取值到侧边栏

Google Sheets Script: Get Value From Script Function Into Sidebar

对于分析电子表格,一个函数会对大约 240 行数据中的每一行进行大量计算。这个函数很慢,所以我添加了代码来检查它在循环时 运行ning 了多长时间。

在 360 秒结束之前我退出 - 首先保存在项目属性中处理的最后一行,并提供警报。然后我可以重新 运行 函数,它检查函数是否未完成,并询问我是否要从处理的最后一行继续。一切顺利。

但是,这可能需要长达半小时才能最终完成,因此我一直在网上寻找同时 运行 该函数的多个实例的方法。我找到了一个使用边栏的

补充工具栏按预期打开,但尽管有一些帮助,我在 HTML 中的脚本并未将 table 单元格设置为初始“大小”。服务器端函数 c_Optimise_Stabilator_Allocation() 正确返回类似 [87.0, 74.0, 62.0, 25.0] 的数组,但客户端函数 setSize(arrSize) 不工作。

GS 代码是:

// display sidebar in gs
function c_Optimise_Stabilator_Sidebar(){
  var html = HtmlService.createHtmlOutputFromFile('StabSidebar').setTitle('Optimise Stabilator').setWidth(250);
  SpreadsheetApp.getUi().showSidebar(html);
}

function c_Optimise_Stabilator_Allocation(tranche, operation){
  var debug = true;
  const ui = SpreadsheetApp.getUi();

  // Get numRows
  const sAngle = "Optimise_Stab_Angle";
  const range = c_GetRangeObjByName(sAngle);
  const numRows = range.getLastRow(); // s/b ~248 rows
  
  // set different num rows per tranche, using percentage
  const pct1 = 0.35, pct2 = 0.30, pct3 = 0.25;
  
  const size1 = Math.round(numRows*pct1),   startRow1 = 0;
  const size2 = Math.round(numRows*pct2),   startRow2 = size1;
  const size3 = Math.round(numRows*pct3),   startRow3 = size1+size2;
  const size4 = numRows-size1-size2-size3,  startRow4 = size1+size2+size3;
            if (debug) { Logger.log ('T1: '+size1+'; T2: '+size2+'; T3: '+size3+'; T4: '+size4); }
  
  if (operation=='size') {
    var arrSize = [size1, size2, size3, size4];
    if (debug) { Logger.log(arrSize); }
    return arrSize;
    
  } else if (operation=='run') {
    switch(tranche) { 
      case 'tranche1' :
          //        c_Optimise_Stabilator(startRow1, size1); 
        break;
      case 'tranche2' :
          //        c_Optimise_Stabilator(startRow2, size2); 
        break;
      case 'tranche3' :
          //        c_Optimise_Stabilator(startRow3, size3); 
        break;
      case 'tranche4' :
          //        c_Optimise_Stabilator(startRow4, size4); 
        break;
      default :
        break;
    }
  }
return;
}

HTML代码:

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>

  <button onclick='run()'>Run Stabilator Optimisation</button><br>
  
  <table>
    <tr> <th>Tr</th> <th>Status</th>                  <th>Optimised</th>   <th>Tot.Rows</th>     <th>Time</th> </tr>
    <tr> <td>1</td>  <td id='status1'>Waiting...</td> <td id='opt1'>0</td> <td id='size1'>0</td> <td id='time1'>xxx</td> </tr>
    <tr> <td>2</td>  <td id='status2'>Waiting...</td> <td id='opt2'>0</td> <td id='size2'>0</td> <td id='time2'>xxx</td> </tr>
    <tr> <td>3</td>  <td id='status3'>Waiting...</td> <td id='opt3'>0</td> <td id='size3'>0</td> <td id='time3'>xxx</td> </tr>
    <tr> <td>4</td>  <td id='status4'>Waiting...</td> <td id='opt4'>0</td> <td id='size4'>0</td> <td id='time4'>xxx</td> </tr>
  </table>

<script>

window.onload=function(){
  console.log('onload');
  google.script.run
    .withSuccessHandler( function(arrSize) {
      setSize(arrSize);
      }
    )
    .c_Optimise_Stabilator_Allocation('all', 'size');
}
function setSize(arrSize){
  console.log('setSize');
  for(var i=0;i<vA.length;i++) {
    document.getElementById('size' + (i+1)).innerHTML=arrSize[i];
  }
}
function run() {
  google.script.run.c_Optimise_Foil('tranche1', 'run'); document.getElementById('status1').innerHTML='Running...';
  google.script.run.c_Optimise_Foil('tranche2', 'run'); document.getElementById('status2').innerHTML='Running...';
  google.script.run.c_Optimise_Foil('tranche3', 'run'); document.getElementById('status3').innerHTML='Running...';
  google.script.run.c_Optimise_Foil('tranche4', 'run'); document.getElementById('status4').innerHTML='Running...';
}


console.log("My Code");
</script>

</body>
</html>

我已尽我所能从各种来源拼凑了 HTML 的代码,但无法找到 setSize 函数不起作用的原因。欢迎大家提出意见。 MTIA

我真的不想为你调试你的代码,但我确实想知道它是否能处理多个回调,所以这里有一个简单的例子:

HTML:

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  
  <script>
    window.onload=function(){
    google.script.run
  .withSuccessHandler(function(vA) {
    updateSelect(vA);
  })
  .getSelectOptions();
}
function updateSelect(vA,id){//the id allows me to use it for other elements
  var id=id || 'sel1';
  var select = document.getElementById(id);
  select.options.length = 0; 
  for(var i=0;i<vA.length;i++) {
    select.options[i] = new Option(vA[i],vA[i]);
  }
}

function sendRequest() {
  const n=document.getElementById('sel1').value;
  document.getElementById('div' + n).innerHTML='Initiating Request' + n;
  google.script.run
  .withSuccessHandler(function(v){
    document.getElementById('div' + v).innerHTML='Received Request' + v;
  })
  .initRequest(n);
}

function sendAll() {
  for(let i=1;i<5;i++) {
    document.getElementById('div' + i).innerHTML="Iniating Request" + i;
    google.script.run
    .withSuccessHandler(function(v){
      document.getElementById('div' + v).innerHTML='Received Request' + v;
    })
    .initRequest(i);
  }
}

console.log("My Code");
  </script>
  </head>
  <body>
     <select id='sel1'></select>
     <input type="button" value="Initiate" onClick="sendRequest();" />
     <input type="button" value="All" onclick="sendAll();" />
     <div id="div1"></div>
     <div id="div2"></div>
     <div id="div3"></div>
     <div id="div4"></div>
  </body>
</html>

代码:

function getSelectOptions() {
  const ss=SpreadsheetApp.getActive();
  const sh=ss.getSheetByName('Sheet1');
  const rg=sh.getRange(1,1,sh.getLastRow());
  const vs=rg.getValues();
  return vs;
}
function launchDialog() {
  SpreadsheetApp.getUi().showModelessDialog(HtmlService.createHtmlOutputFromFile("ah3"),"Testing");
}

function initRequest(n) {
  return n;
}

我不希望它得到任何分数。我只是认为知道它可以工作可能会有所帮助。很可能有人会否决它,然后我将其删除。