Range#sort fails to sort based on new formula's values

孤人 提交于 2021-01-29 08:04:24

问题


I am extracting data from several Google Sheets into one main sheet using Google Apps Script. To convert dates to week-numbers I use the sheet function ISOWEEKNUM() for column 1. I want to sort by week-numbers and because of headers I use Range#sort.

The problem I am having is that no sorting is performed when I test run getData(), the Range#sort call has no effect. If I first run getData() and then manually run my sortRange() function it works.

Is there something about writing cells with ISOWEEKNUM() in them and then try to sort directly in the same script execution? What can be done solve this without the user having to sort or start more scripts manually?

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:


The fundamental issue is that Google is free to (and does) optimize their interpretation of your code to avoid abuse of their servers. When you call functions that operate on different objects, Google doesn't always determine that the order is important, and thus may invoke certain API operations out of (your desired) order. You can help Google by chaining methods on the exact same object, but this is not always sufficient. Operations that cause side effects / asynchronous changes, such as writing a formula, or operate over different APIs - such as calling the Drive API/Service after using Form, Docs, or Sheets Service methods - may not be performed in order even if "chained."

To fix this, you must forcibly flush the write cache buffer. For the Spreadsheet Service, this is done via a call to SpreadsheetApp#flush.

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

Flushing the write cache will force the written formulas to be calculated prior to executing the next script lines, making their values available to the sorting method.



来源:https://stackoverflow.com/questions/55246464/rangesort-fails-to-sort-based-on-new-formulas-values

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!