Как копировать формат и значения, а не формулы, при создании резервной копии электронной таблицы в скрипте Google Apps? - PullRequest
2 голосов
/ 07 октября 2019

Цель состоит в создании замороженных резервных копий электронной таблицы с несколькими листами. Резервная электронная таблица должна копировать значения и формат, но не формулы.

На некоторых листах есть =IMPORTRANGE, что становится проблемой, если электронная таблица сначала копируется, а затем значения копируются в том же диапазоне. опять же, чтобы избавиться от формул, потому что новая электронная таблица требует доступа к импортированному диапазону в середине функции (что приводит к #REF в A1).

Этот вопрос явно задавался много раз, нокажется, ни один из ответов не решил эту проблему. Я посмотрел на эти вопросы (и даже больше): Ссылка 1 , Ссылка 2 , Ссылка 3 , Ссылка 4 , Ссылка 5 и Ссылка 6 . Я пытался реализовать фрагменты из ответов на эти вопросы или их комбинации, но безрезультатно. Было трудно отследить каждый бит фрагмента, который я тестировал.

Я пытался использовать copyTo() либо для копирования целых листов в функции forEach, копирование с опциями {contentsOnly:true} и {formatOnly:true}, нобыли неудачными. Либо copyTo() хочет, чтобы диапазоны находились в одной и той же электронной таблице / листе, либо getDataRange() не соответствует диапазону резервного копирования ...

Вот сценарий, который я сейчас использую, который успешно создает копиювсей таблицы с ценностями только. Я не могу вспомнить, от какого вопроса я получил его.

function copyEntireSpreadsheet(){
  var ss,ssName,sheet,sheetName,data,destination
  ss = SpreadsheetApp.openById("id").getSheets();
  ssName = SpreadsheetApp.openById("id").getName();
  destination = SpreadsheetApp.create(ssName + " - " + new Date().toLocaleString());

  for (var i = 0; i < ss.length; i++){
    sheet = ss[i];
    sheetName = sheet.getSheetName();
    data = sheet.getSheetValues(1, 1, sheet.getLastRow(), sheet.getLastColumn());
    destination.insertSheet(sheetName);
    destination.getSheets()[i+1].getRange(1, 1, sheet.getLastRow(), sheet.getLastColumn()).setValues(data);
  }

 destination.deleteSheet(destination.getSheetByName('Sheet1'));
}

Исходная электронная таблица имеет много форматирования с объединенными ячейками, условное форматирование и т. Д., Которые идеально подходят для копирования. Я также могу жестко запрограммировать определенные листы в сценарий, если это будет иметь какое-то значение с помощью альтернативного метода.

Короче говоря: я ищу замороженную резервную копию электронной таблицы с несколькими листами. Нужно копировать значения и форматирование, а не формулы.

Я мог бы что-то упустить в одном из ответов на все эти вопросы, поэтому я буду продолжать пытаться. В то же время, любая помощь / направление будет оценено. Заранее спасибо!

РЕШЕНО: @ Второй пример сценария Tanaike, приведенный ниже, является отличным обходным путем для копирования листов, которые имеют ссылки на другие электронные таблицы и, следовательно, требуют доступа к ним до перезаписывается только значениями. Большое спасибо @Tanaike за обширную помощь в этом - очень признателен.

1 Ответ

2 голосов
/ 07 октября 2019
  • Вы хотите скопировать значения и формат всех листов электронной таблицы в новую электронную таблицу.
    • В этом случае требуется копировать только значения без формул.
    • The source spreadsheet has a lot of formatting with merged cells, conditional formatting, etc.
    • Исходная электронная таблица включает значения, введенные с IMPORTRANGE.
  • Вы хотите добиться этого с помощью Google Apps Script.

Ниже приведен пример сценария для вышеуказанной цели.

Поток:

  1. Скопируйте все листы в исходной электронной таблице как временные листы.
  2. На скопированных листах ячейки перезаписываются только значениями. Таким образом, формулы могут быть удалены.
    • Если исходная электронная таблица копируется, значения, полученные с помощью IMPORTRANGE, становятся #REF. Потому что требуется авторизация на новой скопированной электронной таблице. Чтобы избежать этого, временные листы копируются в исходной электронной таблице.
  3. Копирование исходной электронной таблицы.
  4. Удаление временных листов в исходной электронной таблице.
  5. Удалите исходные листы в электронной таблице назначения.

С помощью вышеуказанного потока можно копировать только значения без авторизации IMPORTRANGE.

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

function copyEntireSpreadsheet() {
  var id = "###"; // Please set the source Spreadsheet ID.

  var ss = SpreadsheetApp.openById(id);
  var srcSheets = ss.getSheets();
  var tempSheets = srcSheets.map(function(sheet, i) {
    var sheetName = sheet.getSheetName();
    var dstSheet = sheet.copyTo(ss).setName(sheetName + "_temp");
    var src = dstSheet.getDataRange();
    src.copyTo(src, {contentsOnly: true});
    return dstSheet;
  });
  var destination = ss.copy(ss.getName() + " - " + new Date().toLocaleString());
  tempSheets.forEach(function(sheet) {ss.deleteSheet(sheet)});
  var dstSheets = destination.getSheets();
  dstSheets.forEach(function(sheet) {
    var sheetName = sheet.getSheetName();
    if (sheetName.indexOf("_temp") == -1) {
      destination.deleteSheet(sheet);
    } else {
      sheet.setName(sheetName.slice(0, -5));
    }
  });
}

Ссылки:

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