Сортировка листов по имени, когда имена дат - PullRequest
2 голосов
/ 13 февраля 2020

У меня есть электронная таблица Google, где некоторые из названий листов являются текстовыми, а другие - датами в формате "дд / мм / гггг /". Мне нужна функция, которая может сначала поместить лист с именем «Tablero», затем отсортировать листы с именами по убыванию и оставить в конце остальные листы.

Пока это мой код:

function testOrdenar() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheetsCount = ss.getNumSheets();
  var sheets = ss.getSheets();

  // I need the sheet "Tablero" to go first
  var tablero = ss.getSheetByName("Tablero");
  ss.setActiveSheet(tablero);
  ss.moveActiveSheet(1);

  var names = []; // This is where the sheets named with dates will go
  var j = 1; // I use this as a counter, but it is not absolutly necessary

  for (var i = 0; i<sheetsCount; i++){
    var sheetName = sheets[i].getName();
    var pattern = /(\d{2})\/(\d{2})\/(\d{4})/;
    var dt = new Date(sheetName.replace(pattern,'$3-$2-$1'));
    if (dt instanceof Date && !isNaN(dt.valueOf())) {names[j] = dt; j++;} // This is to distinguish the sheets that are dates
  }

  // Here I sort the sheets descendingly
  for (var m = 1;m<j;m++) {
    for (var n = 1;n<j;n++) {
      if (names[n] < names[m]) {
        var aux = names[n];
        names[n] = names[m];
        names[m] = aux;
      }
    }
  }

  var pos = 2;
  for (var a = 0;a<j;a++) {
    var sheetName = Utilities.formatDate(new Date(names[a]), "GMT-3", "dd/MM/yyyy");
    Logger.log(sheetName);
    var sheet = ss.getSheetByName(sheetName);
    ss.setActiveSheet(sheet);
    ss.moveActiveSheet(pos);
    pos++;
  }

Сортировка верна, но я не знаю, почему каждая дата оказывается на день меньше. Я попытался добавить один к переменной de, но он выглядит как «Invalid Object». И мне также нужны эти даты в виде строк, потому что так я могу назвать листы.

Мои вопросы:

1) Как я могу получить правильные даты? (не за день до каждого). Может ли это быть как-то связано с часовым поясом? Я нахожусь в «GMT-3».

(Если ответ добавляет один, пожалуйста, скажите мне, как, потому что я попробовал это и возвращается как ошибка.)

2) Как можно Я получаю отсортированные даты в виде строк в формате «дд / мм / гггг»?

Вот скриншоты моих листов и журналы, которые я получаю:

enter image description here enter image description here

1 Ответ

1 голос
/ 13 февраля 2020

Причина:

  • Как написано в документации , Date.parse(timestring), где timestring - строка, совместимая только с iso8601, возвращает дату в UT C. При форматировании даты в GMT-3 дата смещается на 3 часа по сравнению с предыдущим днем.

Решение:

  • Использовать GMT в качестве аргумента часового пояса Utilities.formatDate

  • В качестве альтернативы, вы можете вообще избежать преобразования в дату и сортировать их как простые строки.

Пример сценария:

function testOrdenar1() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheets = ss.getSheets();
  const pattern = /(?:Tablero)|(\d{2})\/(\d{2})\/(\d{4})/;

  const map = sheets.reduce( //Create a map of sheet object : sheetName(as yyyyMMdd)
    (m, sheet) =>
      m.set(
        sheet,
        sheet
          .getName()
          .replace(pattern, (m, p1, p2, p3) =>
            m === 'Tablero' ? '99999999' : p3 + p2 + p1//make Tablero highest 8 digit number string
          )
      ),
    new Map()
  );

  sheets.sort((a, b) => map.get(b) - map.get(a));//sort sheet objects by their name
  let pos = 1;
  sheets.forEach(sh => {
    ss.setActiveSheet(sh);
    ss.moveActiveSheet(pos++);
  });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...