Ежемесячное копирование значений электронной таблицы на новый лист

#google-apps-script #google-sheets #backup

#google-приложения-скрипт #google-таблицы #резервное копирование

Вопрос:

Я пытаюсь создать функцию резервного копирования для своей электронной таблицы с помощью редактора сценариев Google, используя следующий код, который я нашел в Github:

 function makeCopy(){

 var formattedDate= Utilities.formatDate(new Date(),"GMT","yy:mm:dd''HH:mm:ss");

 var saveAs =  "Copy "   formattedDate;

 var destinationFolder = DriveApp.getFolderById("ID");

 DriveApp.getFileById(SpreadsheetApp.getActiveSpreadsheet().getId())
 .makeCopy(saveAs,destinationFolder);

 }
 

но у меня есть две проблемы:

  • Я не могу использовать его с листом, который использует IMPORT-AGE.
  • Я не хочу получать активную электронную таблицу, вместо этого я хочу использовать идентификатор листа и не уверен, как это сделать.

Комментарии:

1. Я решил вторую проблему. все еще пытаюсь разгадать первый вариант.

2. Создайте новый файл электронной таблицы и скопируйте значения из исходной.

3. @Mario Я хочу сделать это с помощью скрипта, чтобы я мог добавить триггер времени.

4. Я имел в виду сценарий, а не ручной подход. Проверьте мой ответ 🙂

5. Я думаю, я просто воспользуюсь оригинальным листом

Ответ №1:

Объяснение:

К сожалению:

  • importranges невозможно разрешить программно. Итак, вам нужно установить get значения из исходной электронной таблицы и вставить их во вновь созданную (целевую) электронную таблицу.
  • copyTo невозможно использовать между двумя разными электронными таблицами, поэтому вместо этого вы можете использовать getValues и setValues .
  • Логика заключается в том, чтобы перебирать исходные листы и для каждого листа получать значения и копировать их на соответствующие целевые листы.

Дополнительные точки изменения:

  • В объекте date, который вы указали "yy:mm:dd''HH:mm:ss" , mm указаны минуты. Я думаю, что в первом наборе строк вы хотите получить месяц, поэтому используйте MM вместо этого. Проверьте также официальную документацию относительно дат.
  • Вместо передачи значения в печатном GMT виде получите часовой пояс вашего файла электронной таблицы, используя вместо этого getSpreadsheetTimeZone() .

С вышеуказанными изменениями у вас есть:

 const formattedDate = Utilities.formatDate(new Date(),source_ss.getSpreadsheetTimeZone(),"yy:MM:dd''HH:mm:ss");
 

Решение:

 function makeCopy() {
  const source_id = "SpreadsheetID"; // add the id of the spreadsheet to copy
  const source_ss = SpreadsheetApp.openById(source_id);
  const formattedDate = Utilities.formatDate(new Date(),source_ss.getSpreadsheetTimeZone(),"yy:MM:dd''HH:mm:ss");
  const saveAs =  "Copy "   formattedDate;
  const destFolder = DriveApp.getFolderById("FolderID"); // add the destination folder ID
  const file = DriveApp.getFileById(source_id).makeCopy(saveAs, destFolder);
  const target_ss = SpreadsheetApp.openById(file.getId());
  const source_sheets = source_ss.getSheets();
  const target_sheets = target_ss.getSheets();
  source_sheets.forEach((sh,i)=>{
     let values = sh.getDataRange().getValues();
     target_sheets[i].getRange(1,1,values.length,values[0].length).setValues(values);
     SpreadsheetApp.flush();
  })
}
 

Ответ №2:

Я считаю, что ответ Сомарио правильный, но я не думаю, что вам нужно делать все это копирование в конце…

 function makeCopy(source_ID) {

  // const source_id = "SpreadsheetID"; (pass the ID via a function?)

  const source_ss = SpreadsheetApp.openById(source_ID);
  const formattedDate = Utilities.formatDate(new Date(),source_ss.getSpreadsheetTimeZone(),"yy:MM:dd''HH:mm:ss");
  const saveAs =  "Copy "   formattedDate;
  const destFolder = DriveApp.getFolderById("FolderID"); // add the destination folder ID
  const file = DriveApp.getFileById(source_id).makeCopy(saveAs, destFolder);
  
  // You may want to do something with the new file's ID (like save the ID somewhere on the sheet you called this from
  // Logger.Log(file.id);
}
 

Я уверен, что это не делает ничего продуктивного:

   const target_ss = SpreadsheetApp.openById(file.getId());
  const source_sheets = source_ss.getSheets();
  const target_sheets = target_ss.getSheets();
  source_sheets.forEach((sh,i)=>{
     let values = sh.getDataRange().getValues();
     target_sheets[i].getRange(1,1,values.length,values[0].length).setValues(values);
     SpreadsheetApp.flush();
  })
 

Комментарии:

1. Я не думаю, что вы внимательно прочитали мой ответ, но вы скопировали только его часть и опубликовали ее в качестве своего решения. Хотя это нормально, ОП упомянул, что у него есть importrange в его исходном листе. Это означает, что если вы копируете только файл, данные из importranges не будут скопированы , потому что в новом файле пользователю необходимо вручную разрешить importrange . Вот почему мы копируем значения с той частью кода, в которой вы уверены, что она не нужна. Эта проблема описана как в вопросе, так и в моем ответе. Я голосую против, потому что ваш ответ никоим образом не отвечает на вопрос OPs.

2. Ах, да, я пропустил эту часть. Я предположил, что можно просто сохранить его как формулы importrange.

3. I can't use it with a sheet that uses IMPORT-AGE.