Range#sort无法根据新公式的值进行排序

时间:2019-03-19 17:05:39

标签: google-apps-script google-sheets

我正在使用Google Apps脚本将多个Google表格中的数据提取到一个主表格中。要将日期转换成星期数,我在第1列中使用了工作表函数ISOWEEKNUM()。 我想按周数排序,由于标题,我使用Range#sort

我遇到的问题是,当我测试运行 getData() 时不执行排序,Range#sort调用无效。如果我先运行 getData() 然后手动运行 sortRange() 函数,它将起作用。

是否有关于编写其中包含ISOWEEKNUM()的单元格,然后尝试直接在同一脚本执行中进行排序的内容?无需用户手动排序或启动更多脚本就可以解决该问题?

function getData()
{
  var thisSpreadSheet = SpreadsheetApp.getActiveSpreadsheet();
  var dataSheet = thisSpreadSheet.getSheetByName('Data');
  var deliverySheets = listDeliverySheets();

  var outputWeekAndTotal = [];
  var outputCratesPerStore = [];
  var i;
  for(i = 0; i < deliverySheets.length; i++)
  {
    outputWeekAndTotal.push(["=ISOWEEKNUM(\""+deliverySheets[i].getRange("A2").getDisplayValue()+"\")", deliverySheets[i].getRange("L12").getValue()]);
    outputCratesPerStore.push(deliverySheets[i].getRange("L5:L9").getValues());    
  }

  dataSheet.getRange(2, 1, outputWeekAndTotal.length, outputWeekAndTotal[0].length)
    .setValues(outputWeekAndTotal);
  dataSheet.getRange(2, 3, outputCratesPerStore.length, outputCratesPerStore[0].length)
    .setValues(outputCratesPerStore);
  sortRange();
}

function sortRange()
{
  var thisSpreadSheet = SpreadsheetApp.getActiveSpreadsheet();
  var rangeToSort = thisSpreadSheet.getSheetByName('Data').getRange(2, 1, 7, 7); /*Constants used temporarily*/
  rangeToSort.sort({column: 1, ascending: true});
}

1 个答案:

答案 0 :(得分:1)

基本问题是Google is free to (and does) optimize their interpretation of your code避免滥用其服务器。当您调用对不同对象进行操作的函数时,Google并不总是确定顺序很重要,因此可能会以(您想要的)顺序调用某些API操作。您可以通过在完全相同的对象上链接方法来帮助Google,但这并不总是足够的。导致副作用/异步更改的操作(例如编写公式)或对不同的API进行操作(例如在使用Form,Docs或Sheets Service方法后调用Drive API /服务),即使“已链接”也可能无法按顺序执行。”

要解决此问题,必须强行刷新写缓存缓冲区。对于电子表格服务,这是通过调用SpreadsheetApp#flush完成的。

  ...
  dataSheet.getRange(...).setValues(...);
  SpreadsheetApp.flush();
  sortRange();
}

刷新写缓存将强制在执行下一个脚本行之前计算写公式,从而使它们的值可用于排序方法。