0

So based on ADAM's sheet sorting program(linked below), I have modified it slightly to take sheet names by an order type and a date. Ex: "B: 10/23/2017" for birthday orders or "Month End: 10/2017" for month end reports.

https://productforums.google.com/forum/#!topic/docs/eP7kHR6L7ZI/discussion

    //function to sort tabs by date
function sortTabs() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheets = ss.getSheets();

  var ignored = 5;      //last 5 sheets to be ignored

  var sheetDateMatrix = [];
  var sheetDateRow = [];

  var MONTH_END = 'Month End:';
  var monthArray = ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12']     //Easy conversion of 0-11 format to 1-12 format

  var tabOrder = []   //Final array of tab names in order

  //Loops through all sheets seperates order types from date. Sends to matrix.
  for (var i = 0; i < sheets.length - ignored; i++) {

    sheetDateRow = sheets[i].getName().split(" ");

    if(sheetDateRow.length <= 2) {
      sheetDateRow[1] = new Date(sheetDateRow[1])
      sheetDateMatrix.push(sheetDateRow);
    }
    else {                       
      sheetDateRow.shift();
      sheetDateRow[0] = MONTH_END;
      sheetDateRow[1] = getLastDayOfMonth(sheetDateRow[1]);

      sheetDateMatrix.push(sheetDateRow);   
    }
  }

  //sorts matrix by date
  sheetDateMatrix.sort(function(a, b) {
    return b[1] - a[1];
  });

  //Reforms dates into correct format. Rejoins order type with date. Sets spreadsheet tabs' indices following the sheetDateMatrix' order
  for(var j = 0; j < sheets.length - ignored; j++ ) {
    if(sheetDateMatrix[j][0] == MONTH_END) {
      sheetDateMatrix[j][1] = monthArray[sheetDateMatrix[j][1].getMonth()] + '/' + sheetDateMatrix[j][1].getFullYear();
    }
    else {
      sheetDateMatrix[j][1] = monthArray[sheetDateMatrix[j][1].getMonth()] + '/' + ('0' + sheetDateMatrix[j][1].getDate()).slice(-2) + '/' + sheetDateMatrix[j][1].getFullYear();
    }

    tabOrder.push(sheetDateMatrix[j].join(' '));

    ss.setActiveSheet(ss.getSheetByName(tabOrder[j]));
    ss.moveActiveSheet(j + 1);
  }
  return tabOrder;
}

The tabOrder array lists an array correctly sorted by the date.

[17-10-26 22:24:12:411 EDT] [O: 10/21/2017, B: 10/21/2017, B: 10/14/2017, B: 10/07/2017, B: 10/01/2017, Month End: 09/2017, B: 09/30/2017, B: 09/23/2017, B: 09/16/2017, B: 09/09/2017, B: 09/02/2017, B: 08/19/2017, B: 08/11/2017, B: 08/02/2017]

The problem being that the actual order of tabs in my spreadsheet does not match the array.

If I have 19 tabs currently. Last 5 tabs are ignored for templates. Sheets 09/02/2017 and 09/09/17 are swapped around.

Curious if any of you could help me solve this little headache. I intend to populate the month end reports automatically and this throws a wrench in things.

Scape
  • 3
  • 1

2 Answers2

0

Sorting Tabs

I just made a small change to the sort function and I noticed that on the Month End: sheets that the months have to be two digits. After that it seems to working find and sort the sheets with most recent date to the left and oldest dates to the right and leaves the ignore sheets to the right alone.

Here's the code:

function sortTabs() 
{
  var ss=SpreadsheetApp.getActiveSpreadsheet();
  var sheets=ss.getSheets();
  var ignored = 1;      //last 5 sheets to be ignored
  var sheetDateMatrix = [];//each row is String,Date
  var sheetDateRow = [];
  var MONTH_END = 'Month End:';
  var monthArray = ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12']     //Easy conversion of 0-11 format to 1-12 format
  var tabOrder = []   //Final array of tab names in order
  //Loops through all sheets separates order types from date. Sends to matrix.
  for (var i=0;i<sheets.length-ignored;i++) 
  {
    sheetDateRow=sheets[i].getName().split(" ");//B: 10/23/2017 or MonthEnd: 10/23/2017
    if(sheetDateRow.length <= 2) 
    {
      sheetDateRow[1] = new Date(sheetDateRow[1])
      sheetDateMatrix.push(sheetDateRow);
    }
    else 
    {                       
      sheetDateRow.shift();
      sheetDateRow[0] = MONTH_END;
      sheetDateRow[1] = getLastDayOfMonth(sheetDateRow[1]);
      sheetDateMatrix.push(sheetDateRow);   
    }
  }
  sheetDateMatrix.sort(function(a, b) 
  {
    return b[1].valueOf() - a[1].valueOf();//I changed this line to make sure were working with numbers.
  });

  //Reforms dates into correct format. Rejoins order type with date. Sets spreadsheet tabs' indices following the sheetDateMatrix' order
  for(var j = 0; j < sheets.length - ignored; j++ ) 
  {
    if(sheetDateMatrix[j][0] == MONTH_END) 
    {
      sheetDateMatrix[j][1] = monthArray[sheetDateMatrix[j][1].getMonth()] + '/' + sheetDateMatrix[j][1].getFullYear();
    }
    else 
    {
      sheetDateMatrix[j][1] = monthArray[sheetDateMatrix[j][1].getMonth()] + '/' + ('0' + sheetDateMatrix[j][1].getDate()).slice(-2) + '/' + sheetDateMatrix[j][1].getFullYear();
    }
    tabOrder.push(sheetDateMatrix[j].join(' '));
    ss.setActiveSheet(ss.getSheetByName(tabOrder[j]));
    ss.moveActiveSheet(j + 1);
  }
  return tabOrder;
}

function getLastDayOfMonth(s) 
{
  var myA=s.split('/');
  return new Date( (new Date(myA[1], myA[0],1))-1 );
}

I got the getLastDayOfMonth() function from here.

Final Tab Sort Order

enter image description here

Cooper
  • 59,616
  • 6
  • 23
  • 54
  • Thanks Cooper, I thought it was working at first. Going to keep trying to figure this one out. – Scape Oct 30 '17 at 04:20
0

The array shows the dates in order. But after running the sortTab function it mixes up some of the tabs.

Tabs after sort

Scape
  • 3
  • 1
  • I added some more sheets with similar dates to those that are out of order and I can't reproduce the problem. – Cooper Oct 30 '17 at 04:58
  • After further searching I did find this https://stackoverflow.com/questions/36667862/method-moveactivesheet-doesnt-work-as-expected-in-google-apps-script-javascr – Scape Oct 30 '17 at 05:59
  • Thanks for sharing that – Cooper Oct 30 '17 at 14:02