Переименование листов с помощью al oop, но избегание повторяющихся имен - PullRequest
1 голос
/ 17 июня 2020

У меня есть таблица со списком мотоциклетных туров.

Мне нужно назвать листы в соответствии с этим списком и переименовать листы, если список изменится. Имя листа будет объединением названия тура и индекса отправления.

Код ниже работает хорошо, за исключением случаев, когда есть 2 отправления идентичных туров, возникает следующее исключение:

' Лист с именем «XXX» уже существует. »

Если я переверну l oop (i-- вместо i++), он будет работать.

I хотите изменить код на l oop в одном направлении, а затем, если возникнет исключение, l oop в другом направлении.

Изменить:

Итак, если у меня есть список туров:

Tour A 1, Tour B 1, Tour C 1, Tour A 2, Tour D 1, Tour E 1,

и я хочу изменить 'Tour B 1 'в другой экземпляр' Tour A '. Тогда «Тур В 1» изменится на «Тур А 2», а существующий «Тур А 2» изменится на «Тур А 3».

Зацикливание сверху, ошибка возникает, потому что «Тур В 1 'пытается перейти на' Tour A 2 ', в то время как исходный' Tour A 2 'все еще существует.

Однако, зацикливание снизу, это работает, потому что существующий' Tour A 2 'меняется на' Tour A 3 ', и к тому времени, когда l oop достигнет' Tour B 1 ', он может измениться на' Tour A 2 ', поскольку лист с таким именем больше не существует!

Надеюсь, это Чисто? Обратное верно, если имя листа изменяется в нижней части списка. A ++ l oop будет работать, но a - l oop не будет.

Поэтому я хотел бы попробовать ++ l oop, за которым следует - l oop if возникает ошибка ...

// Triggered by onEdit

function renameSheets() {

// Sets the sheet names to match season schedule

  var tourNames = seasonScheduleTab.getRange('D5:D34').getValues();
  var departures = seasonScheduleTab.getRange('C5:C34').getValues();

  var sheets = ss.getSheets();


// I think I need an if statement above my for loop to change the loop to (var i = 30; i > 0; i --) if an exception occurs?

  for (var i = 1; i < 31; i ++){

    if (tourNames[i-1] !='') {

    sheets[i].setName(tourNames[i-1] + ' ' + departures[i-1]);
      }

    }

  }

1 Ответ

2 голосов
/ 18 июня 2020

Я считаю, что ваша цель заключается в следующем.

  • Вы хотите изменить имена листов в таблице Google, используя tourNames[i-1] + ' ' + departures[i-1], извлеченные var tourNames = seasonScheduleTab.getRange('D5:D34').getValues(); и var departures = seasonScheduleTab.getRange('C5:C34').getValues();
  • имена для обновления имен листов являются уникальными значениями для всех имен.
  • Когда l oop выполняется в прямом направлении, при возникновении ошибки вы хотите изменить l oop на обратное направление.

Для этого, как насчет этого ответа?

Шаблон 1:

В этом шаблоне ваша цель, когда l oop запускается с прямое направление, когда возникает ошибка, вы хотите изменить l oop на обратное направление достигается. Для этого используется «попробуй ... поймай». Но в этом случае, когда ошибка возникает в обоих направлениях l oop, возникает ошибка. Будьте осторожны.

Измененный скрипт:

При изменении вашего скрипта, пожалуйста, измените следующее.

От:
for (var i = 1; i < 31; i ++){

  if (tourNames[i-1] !='') {

  sheets[i].setName(tourNames[i-1] + ' ' + departures[i-1]);
    }

  }

}
Кому:
try {
  for (var i = 1; i < 31; i ++) {
    if (tourNames[i-1] !='') {
      sheets[i].setName(tourNames[i-1] + ' ' + departures[i-1]);
    }
  }
} catch(e) {
  for (var i = 30; i > 0; i --) {
    if (tourNames[i-1] !='') {
      sheets[i].setName(tourNames[i-1] + ' ' + departures[i-1]);
    }
  }
}

Шаблон 2:

В этом шаблоне используется следующий поток:

  1. Проверить повторяющиеся имена. Когда существуют повторяющиеся имена, сценарий останавливается.
  2. Измените все имена листов на временные имена без включения имен для изменения имен листов.
  3. Замените все имена листов на имена для изменение имен листов.

По этому потоку я думаю, что не требуется изменять направление l oop. В данном случае, чтобы снизить стоимость процесса, используется Sheets API расширенных сервисов Google.

Измененный скрипт:

Пример скрипта выглядит следующим образом. Перед использованием включите API Таблиц в расширенных сервисах Google .

function myFunction() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const seasonScheduleTab = ss.getSheetByName("###");  // Please set the sheet name.

  const spreadsheetId = ss.getId();
  const sheetNames = seasonScheduleTab.getRange('C5:D34').getValues().map(([c, d]) => `${c} ${d}`);

  // 1. Check the duplicate names. When the duplicate names are existing, the script is stopped.
  if (sheetNames.length > [...new Set(sheetNames)].length) {
    throw new Error("Duplicated names are existing.");
  }

  const sheets = ss.getSheets();
  let sheetIds = [];
  for (let i = 1; i < 31; i++) {
    sheetIds.push(sheets[i].getSheetId());
  }
  const tempName = "tempSheetName_";  // This is used for changing the sheet name to the temporal names.

  // 2. Change all sheet names with the temporal names without including the names for changing the sheet names.
  let reqs = sheetIds.map((id, i) => ({updateSheetProperties: {properties: {sheetId: id, title: `${tempName}${i + 1}`}, fields: "title"}}));

  // 3. Change all sheet names with the names for changing the sheet names.
  reqs = reqs.concat(sheetIds.map((id, i) => ({updateSheetProperties: {properties: {sheetId: id, title: `${sheetNames[i]}`}, fields: "title"}})));

  // Request to Sheets API with the created request body.
  Sheets.Spreadsheets.batchUpdate({requests: reqs}, spreadsheetId);
  SpreadsheetApp.flush(); // I'm not sure whether this is required to be used.
}

Примечание:

  • По крайней мере, в этом случае это необходимо включить 31 лист в электронную таблицу Google. Пожалуйста, будьте осторожны.
  • Используйте этот скрипт с V8.

Ссылки:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...