The code below is used to perform some simple functions in a Google Sheet.
It creates two new sheets (makes them (0) and (1), names them, and adds color) and hides another sheet.
The code has been extremely unreliable. If I create a blank google sheet and test it works fine but when I add it to the live version of the sheet it times out and fails to run all the code.
I also tested copying the live version (in case there was some corruption in the file) and initially it seemed to work but then the same problem occurred. I am brand new to app script so perhaps I am missing something obvious. I would appreciate any suggestions.
function New_Tabs() {
var spreadsheet = SpreadsheetApp.getActive();
var curDate = Utilities.formatDate(new Date(), "GMT+1", "M/d") //sets format for current
date as month/day
//Selects and activates the Day_date sheet / Gets calculated date info
var sheet = SpreadsheetApp.getActive().getSheetByName('Day_Date');
sheet.activate();
var val = SpreadsheetApp.getActiveSheet().getRange(2,6).getValue();
//Logger.log(val) Used this to check the value was pulled correctly
//Insert the sheet for today's date - Data from portal/Excel macro will be pasted here
spreadsheet.insertSheet(0); //Makes it the first sheet
spreadsheet.getActiveSheet().setName(val); //pulls calculated date from Day_Date sheet
spreadsheet.getActiveSheet().setTabColor('#00ff00'); //Colors the sheet tab green
//Insert the sheet for Logistics
spreadsheet.insertSheet(1); //Makes it the second sheet
spreadsheet.getActiveSheet().setName("Logistics " + curDate ); //names the sheet with text
and current date
spreadsheet.getActiveSheet().setTabColor('#00ff00'); //Colors the sheet tab green
//trying to slow down to make hiding the tab more reliable
Utilities.sleep(2000);// pause for 2 seconds
//selects the sheet for today's date - Data from portal/Excel macro will be pasted here
spreadsheet.setActiveSheet(spreadsheet.getSheetByName(val), true);
//trying to slow down to make hiding the tab more reliable
Utilities.sleep(2000);// pause for 200 milliseconds
//selects the Day_date sheet and hides it
spreadsheet.setActiveSheet(spreadsheet.getSheetByName('Day_Date'), true);
spreadsheet.getActiveSheet().hideSheet();
SpreadsheetApp.getUi().alert("Completed");
};
Try it this way:
function New_Tabs() {
const ss = SpreadsheetApp.getActive();
const curDate = Utilities.formatDate(new Date(), "GMT+1", "M/d");
const sh = SpreadsheetApp.getActive().getSheetByName('Day_Date');
const val = sh.getRange(2,6).getValue();
let ns = ss.insertSheet(0);
ns.setName(val);
ns.setTabColor('#00ff00');
let ns1 = ss.insertSheet(1);
ns1.setName("Logistics " + curDate );
ns1.setTabColor('#00ff00');
ns.hideSheet();
ss.toast("Completed")
}
Related
I have a Google sheet that I need to copy each day into a new tab. I need the new tab to be named with the new date and I need all of the formatting duplicated. I've been able to get it to make a new tab and rename it correctly but I cannot get it to transfer the formatting over. The cell range I need is A1:G34. Can anyone help?
I've tried doing a macro recording and it still didn't work
I believe this will do the trick. You just need to change sheets name from 'Main' to which you want to copy data from and click on ⏩️ > Duplicate at top of page next to Help.
/** #OnlyCurrentDoc */
function onOpen() {
const ui = SpreadsheetApp.getUi();
ui.createMenu('⏩️')
.addItem('Duplicate', 'duplicateSheet')
.addToUi();
}
function duplicateSheet(){
var ss = SpreadsheetApp.getActive();
var ssh = ss.getRange("Main!A1:G34"); //Selects sheet and range you wish to copy to new sheet
var date = Utilities.formatDate(new Date(), "GMT+1", "dd/MM/yyyy"); // Todays date
ss.insertSheet(date); //Creates new sheet with todays date as name
var dsh = ss.getSheetByName(date);
var drg = dsh.getRange(dsh.getLastRow() + 1, 1);
ssh.copyTo(drg); //Cpoies A1:G34 data from Main sheet to new sheet
}
I'm trying to create a button that makes a copy of the master sheet into an archive folder. I've got that working, but it requires me to 'Allow Access' to several external sheets, which ruins all the formulas in the archived version (as it's trying to pull from backend sheets that are waiting for the importrange to be allowed).
Now, I'm looking to hard copy the values only from the master sheet into the archived version, so they are static values as they were at the time of creation. However, I'm getting 'Exception: Range not found' error when I try to archive, and the importrange formula remains in the archived sheet version.
Here's my code:
function archiveSheet () {
var confirm = Browser.msgBox('Have you fully completed the RTU?', Browser.Buttons.YES_NO);
if(confirm=='no'){Logger.log('The user clicked "NO."')};
if(confirm=='yes'){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var RTUDate = ss.getRange('Backend!O9').getValue();
Logger.log(RTUDate)
var RTUTime = ss.getRange('Backend!O12').getValue();
Logger.log(RTUTime)
// generates the timestamp and stores in variable formattedDate as Month Date, Year
//GMT+10 selected as server is in USA
//E.g. February 17, 2021 10:00:00 -0800
//https://developers.google.com/google-ads/scripts/docs/features/dates
var formattedDate = Utilities.formatDate(RTUDate,"GMT+20", "MMMM dd, yyyy");
//formats time
var formattedTime = Utilities.formatDate(RTUTime,"GMT+20","HH:mm");
// gets the name of the original file and appends a space " " followed by the timestamp stored in formattedDate
var name = SpreadsheetApp.getActiveSpreadsheet().getName() + " " + formattedDate + " " + formattedTime;
// gets the destination folder by their ID
var destination = DriveApp.getFolderById("MyDriveIDHere");
// gets the current Google Sheet file
var file = DriveApp.getFileById(SpreadsheetApp.getActiveSpreadsheet().getId());
// makes copy of "file" with "name" at the "destination"
var newFile=file.makeCopy(name, destination);
// here is where the error occurs (I think):
var source_sheet = SpreadsheetApp.getActive().getSheetByName('Codex');
var target_sheet_ID = SpreadsheetApp.OpenByID(newFile.getID());
var target_sheet = target_sheet_ID.getSheetByName('Codex');
source_sheet.getRange('Codex!A2:O').copyTo(target_sheet_ID.getRange('Codex!A2:O'), SpreadsheetApp.CopyPasteType.PASTE_VALUES,false);
}
Any help would be greatly appreciated!
Since you've already selected the sheet Codex you should only put the A1 notation of the ranges. Delete 'Codex!' and see if it works. Copying and pasting has its limitations between different spreadsheets. You may try replacing that last line with:
var values = source_sheet.getRange('A2:O').getValues()
target_sheet_ID.getRange('A2:O').setValues(values)
I have a spreadsheet to track monthly memberships and payments. I duplicate the sheet at the end of the month rename it to the date and lock it to archive it. I have a marco recorded and setup to do this and have a button on the sheet to click to do this. It works great.
However, I'd like to make this script triggered via time which I have setup in the Tigger area of google scripts. But when it runs, it fails and I get the following error:
Exception: Please select an active sheet first.
at ArchiveSheet(macros:5:15)
Here is my code:
function ArchiveSheet() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet()
spreadsheet.duplicateActiveSheet();
var sheetname = Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "MMM/yyyy");
spreadsheet.getActiveSheet().setName("Archive "+ sheetname);
spreadsheet.setActiveSheet(spreadsheet.getSheetByName('Current Month'), true);
spreadsheet.getRange('J3:J263').activate();
};
Any help would be appreciated.
getActiveSpreasheet() can only be used on bounded scripts or on change, on edit and on open installable triggers created programmatically, on a time-driven trigger you have to use one of the following
open(file) (this should be used together with DriveApp / Advanced Drive Service
openById(id)
openByUrl(url)
Related
Time-Driven triggers not working properly
Sheet Duplication with a trigger
function myfunk101() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName('Sheet0');
sh.activate();
const nsh = ss.duplicateActiveSheet();
const n = Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "HH:mm:ss");
nsh.setName("Archive " + n);
};
The active sheet is always ss.getSheets()[0] so it's better to pick on by name. And it won't activate a sheet on a current session because the instance its running on is only opened on the server.
function createTriggerFormyfunk101() {
if (ScriptApp.getProjectTriggers().filter(t => t.getHandlerFunction() == 'myfunk101').length == 0) {
ScriptApp.newTrigger('myfunk101').timeBased().everyMinutes(5).create();//I used every five minutes because I didn't want to wait for the end of the month
}
}
I think this is a better way to go:
function myfunk101() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("Sheet0");//Pick your sheet
ss.insertSheet(Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "HH:mm:ss"), {template: sh});//change you time format for your name. Since I was running 5 minute triggers I wanted more precision.
};
insertSheet(sheetName, options)
I am building a daily checklist that uses a trigger to make a new tab every night at 12pm. The code is below - but I need the code to clear the content of those cells, not the underlying formulas. I assume instead of "var rangetoclear" it must be something else, but I could not find on help page.
Can anybody help?
Here is the code:
/* DASHBOARD---------------------------------------------------------------------------------------------------
Edit this section to change the dates tabs are created for and the range of data that will be cleared each time! */
var numberOfDaysForwardForNextTab = 0
var rangeToClear = 'F8:I1003'
// -------------------------------------------------------------------------------------------------------------
var ss = SpreadsheetApp.getActiveSpreadsheet(); // get the spreadsheet object
SpreadsheetApp.setActiveSheet(ss.getSheets()[0]); // set the first sheet as active
// Sets date for add tab & date for delete tab
var MILLIS_PER_DAY = 1000 * 60 * 60 * 24;
var today = new Date();
var addWeek = Utilities.formatDate(new Date(today.getTime() + (numberOfDaysForwardForNextTab * MILLIS_PER_DAY)), "GMT+1", "MM-dd-yy");
// Adds tab
ss.duplicateActiveSheet(); //Copies current sheet
ss.renameActiveSheet(addWeek); //Renames sheet to date from above
ss.moveActiveSheet(1); //Moves sheet to the first position
// Prepares tab (clears old content)
var sheet = ss.getSheetByName(addWeek);
sheet.getRange(rangeToClear).clearContent()
}
One solution is to get the formulas of the source sheet and for the range you want to clear rangeToClear and then copy the formulas to the duplicate sheet you just created after clearing its contents:
const rangeToClear = 'F8:I1003';
const source_sheet = ss.getSheets()[0];
const formulas = source_sheet.getRange(rangeToClear).getFormulas();
const sheet = ss.getSheetByName(addWeek);
sheet.getRange(rangeToClear).clearContent()
sheet.getRange(rangeToClear).setFormulas(formulas)
References:
getFormulas()
setFormulas()
I am currently using a google sheet to manage my portfolio. I want to save the value of my portfolio every day and save those numbers to create a growth graph. I want to take the value from one cell, paste it to another and the next day grab the value again from the same cell and paste on the cell under the one of the previous day without loosing my previous value. I am trying to create an AppScript script but I cant figure out how to go to the next cell once the day changes.
function Paste() {
var date = Utilities.formatDate(new Date(), "GMT+1", "dd/MM/yyyy")
var cellNumber = 3;
var cell = "C" + cellNumber;
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange(cell).activate();
spreadsheet.getRange('J11').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
};
I want to increase cellNumber once a day!
function Paste() {
var ts=Utilities.formatDate(new Date(), "GMT+1", "dd/MM/yyyy")
var srcss=SpreadsheetApp.openById('sssid');//source of information spreadsheet
var desss=SpreadsheetApp.openById('dssid');//storage destination spreadsheet
var srcsh=srcss.getSheetByName('source sheet name');
var dessh=desss.getSheetByName('destination sheet name');
var value=srcsh.getRange('C3').getValue();
dessh.appendRow([ts,value]);
};