Как дублировать таблицу Google Spreadsheet, переименовать ее и вставить содержимое в абсолютные значения с помощью скриптов Google App - PullRequest
0 голосов
/ 26 февраля 2020

Hello Stackoverflowers,

Я хочу дублировать лист с именем «Панель инструментов» 1-го числа каждого месяца с именем листа предыдущего месяца и года (ММММ ГГГГ) и содержимым как stati c values.

Чтобы сделать это, я попытался адаптировать два следующих сценария, но он не выполняет то, что я хочу.

проблемы:

  1. Значения не вставляются как абсолютные значения.

  2. Имя листа - это имя текущий месяц, а не предыдущий месяц.

Я считаю, что для проблемы Num. 1, следующее утверждение содержит ошибку в синтаксисе, но я не могу ее найти:

asn.copyTo(getRange("MMMMM yyyy"),{contentsOnly: true});

Для проблемы num. 2 Я действительно не знаю, как начать.

=> Есть идеи? Любая помощь будет высоко ценится

function duplicatesheet() {
  var as = SpreadsheetApp.getActiveSpreadsheet(); // active spreadsheet

    var s = as.getSheetByName('Dashboard'); // first sheet object

 // var s = as.getActiveSheet(); // first sheet object
  var dateCell = "H5"; // cell containing first date
  var N = 1; // number of copies to make

  var startDate = new Date(s.getRange(dateCell).getValue()); // get the date stored in dateCell
  var day = startDate.getDate(); // extract the day
  var month = startDate.getMonth(); // extract the month
  var year = startDate.getFullYear(); // extract the year

  // loop over N times
  for (var i = 0; i < N; i++) {

   var asn = s.copyTo(as); // make a duplicate of the first sheet



    var thisSheetDate = new Date(year, month, day+(i+1)); // store the new date as a variable temporarily

    asn.getRange(dateCell).setValue(thisSheetDate); // writes the date in cell "B3"
    asn.setName(Utilities.formatDate(thisSheetDate, undefined, "MMMMM yyyy")); // sets the name of the new sheet
    asn.copyTo(getRange("MMMMM yyyy"),{contentsOnly: true});
  }
}
function moveValuesDown() {
  var ss = SpreadsheetApp.getActiveSpreadsheet ();
  var source = ss.getRange ("Dashboard!A4:I");

  source.copyTo (ss.getRange ("MySheet1!A5"), {contentsOnly: true});
}

Ответы [ 3 ]

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

Ваши цели:

  1. Сохранение значений за последний месяц на листе с названием прошлого месяца.
  2. Сделайте это 1-го числа месяца
  3. Продолжайте использовать существующая панель мониторинга на текущий месяц
  4. Повторите в следующем месяце

Пример их достижения:

function onMonthStart() {
  const monthNames = ['Jan','Feb','Mar','Apr','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];

  // Whats last month's name?
  var thisMonth = Utilities.formatDate(new Date(),"GMT","MMM");
  var pastMonth = monthNames[monthNames.indexOf(thisMonth) - 1];
  if (monthNames.indexOf(thisMonth) == 0){
    pastMonth = 'Dec';
  }

  // Create new destination sheet for past month values
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var pastMonthSheet = ss.insertSheet(pastMonth);

  // Copy data from dashboard
  var pastMonthDataRange = ss.getSheetByName('Dashboard').getDataRange();

  // Paste in past month's sheet
  pastMonthSheet.activate().getRange(pastMonthDataRange.getA1Notation()).setValues(pastMonthDataRange.getValues())
}

Как вызвать onMonthStart каждый 1-й месяц?:

Установить управляемый временем триггер в первый день месяца. time driven triggers splash screen


Примечания:

  1. Использование метода Sheet.copyTo занимает Spreadsheet объект как param. Вы передаете диапазон с опциями. Не то же самое!
  2. Старайтесь быть последовательными в вашем стиле именования переменных и используйте имена со значением для удобства чтения.
1 голос
/ 26 февраля 2020

Создание копии Dashboard каждый месяц первого числа месяца

function createNewSheetFromTemplate(templatename="Dashboard") {
  const dt=new Date();
  //This runs the insert only on the first day of the month
  if(dt.getDate()==1) {
    const ss=SpreadsheetApp.getActive();
    const template=ss.getSheetByName(templatename);//default parameter
    const name=Utilities.formatDate(new Date(dt.getFullYear(),dt.getMonth(),0), Session.getScriptTimeZone(), "MMMM/yyyy");
    ss.insertSheet(name, {template:template});
  }
}

function createTimeBasedTrigger() {
  if(!isATrigger('createNewSheetFromTemplate')) {
    ScriptApp.newTrigger('createNewSheetFromTemplate').timeBased().everyDays(n).atHour(6).create();//The trigger happens daily at 6 am
  }
}

//You just need to run this once.   It's setup to  only allow one trigger to be created even if you run it again.
function isATrigger(funcName){
  var r=false;
  if(funcName){
    var allTriggers=ScriptApp.getProjectTriggers();
    for(let i=0;i<allTriggers.length;i++){
      if(funcName==allTriggers[i].getHandlerFunction()){
        r=true;
        break;
      }
    }
  }
  return r;
}

Примечание. Для этого сценария требуется V8.

0 голосов
/ 28 февраля 2020

@ Купер и @Aerials Большое спасибо за ваш вклад! Оба очень элегантные решения.

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

Вот как это выглядит:

/// Duplicate Dashboard values in previous month tab

function createNewSheetFromTemplate(templatename="Dashboard") {
  const dt=new Date();
  //This runs the insert only on the first day of the month
  if(dt.getDate()==1) {
    const ss=SpreadsheetApp.getActive();
    const template=ss.getSheetByName(templatename);//default parameter
    const name="Pacing " + Utilities.formatDate(new Date(dt.getFullYear(),dt.getMonth(),0), Session.getScriptTimeZone(), "MMMM");
    ss.insertSheet(name, {template:template});

 // Select the new created sheet already renamed    
     var pastMonthSheet = ss.getSheetByName(name);
 // Copy values from dashboard
  var pastMonthDataRange = ss.getSheetByName(name).getDataRange();

  // Paste in the values form the dashboard as absolute values in the past month sheet
  pastMonthSheet.activate().getRange(pastMonthDataRange.getA1Notation()).setValues(pastMonthDataRange.getValues())

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