I'm using a spreadsheet to track my routine in the gym. I have it set up to duplicate the active sheet and name the duplicate with today's date. It's set up to trigger the below code on edit:
function myProgress() {
var fullDate = Utilities.formatDate(new Date(), "GMT-5", "dd/MM/yyyy");
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var name = fullDate;
var currentName = ss.getSheetByName(name);
if (!currentName) {
ss.insertSheet(name, {template: sheet});
ss.moveActiveSheet(1);
ss.setActiveSheet(ss.getSheets()[0]);
}
}
Which works great on desktop.
If today (28/02/2020) I edit my workout routine done on 25/02/2020, Sheet 25/02/2020 is duplicated and named "28/02/2020". Then Sheet 28/02/2020 is the active sheet.
But because of the way the mobile app works (maybe to do with the confirmation of entered text?) it will duplicate and rename the the sheet but it won't set the new one as the active sheet.
Yes, it's only a minor inconvenience to have to remember to go to today's sheet before continuing to edit, but I'd really love to work out a way around this.
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 have a data sheet that will update weekly. I would like a script to copy the sheet and rename it with the current date. The goal is to preserve the data in the sheet weekly before it updates so that I have a record of the data.
This is the script that I have so far:
/** #OnlyCurrentDoc */function myFunction() {
let sh, temp_one_values;
sh = SpreadsheetApp.getActive();
temp_one_values = transpose_(sh.getSheetByName('Complete Tutoring Roster').getRange('A1:Z1000').getValues());
{temp_one.copyTo(sh).setName(szToday);
}
}
function transpose_(array) {
return Object.keys(array[0]).map(function (col) {
return array.map(function (row) {
return row[col];
});
});
}
function CopyDataSheet() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange('A1').activate();
spreadsheet.duplicateActiveSheet();
spreadsheet.getActiveSheet().setName('11/19/2020');
};
I used record a macro to get the script.
I know that I need to edit the setName code. But I am not sure how to code it to pull the current date.
Explanation:
You just need to get the date of today in the desired format: MM/dd/yyyy:
const today = Utilities.formatDate(new Date(), spreadsheet.getSpreadsheetTimeZone(), "MM/dd/yyyy");
And then use the copyTo(spreadsheet) method to duplicate the sheet into the existing spreadsheet and then name it with the date of today:
sheet.copyTo(spreadsheet).setName(today);
You don't need to activate ranges or sheet. That is a logic generated by macros but it makes your code confusing and inefficient. Instead of getting the active sheet, use getSheetByName to get the desired sheet based on its name.
Solution:
In this solution, change Sheet1 to the name of the sheet you want to duplicate.
function CopyDataSheet() {
const spreadsheet = SpreadsheetApp.getActive();
const sheet = spreadsheet.getSheetByName('Sheet1');
const today = Utilities.formatDate(new Date(), spreadsheet.getSpreadsheetTimeZone(), "MM/dd/yyyy");
sheet.copyTo(spreadsheet).setName(today);
};
I'm quite new to google sheet script and looking for some assistance. I am trying to make a google script that will erase cells in a response sheet after a user has submitted it. As this could be a form edit url, it may not necessarily be the last row.
So everytime a form is submitted / edited, columns AN:AQ are cleared.
Any help greatly appreciated
I'm adding the working script to OP's question for anyone who comes across this.
function onFormSubmit11(e) {
var range = e.range;
var ss = range.getSheet();
var row = range.getRowIndex();
ss.getRange("AN"+row).clear();
ss.getRange("AO"+row).clear();
ss.getRange("AP"+row).clear()
ss.getRange("AQ"+row).clear()
}
The Spreadsheet trigger invoked by the Google Form contains the Range object. You can retrieve the sheet linked to the range as well the index of the row linked to the current form submission.
function formTrigger(e) {
var range = e.range;
var sheet = range.getSheet();
var rowIndex = row.getRowIndex();
sheet.getRange(rowIndex + 1, 1).setValue("Hello");
}
You could try something as simple as an onFormSubmit running the script through your linked spreadsheet. The script below will clear AN:AQ every time a form is submitted which is 'alf of what I think you're asking for.
As for on edit, that's something I'm trying to figure out myself in my own question!
function onFormSubmit() {
var ss = SpreadsheetApp.getActiveSpreadsheet()
var sh = ss.getActiveSheet()
sh.getRange('AN1:AQ').clear();
}
Hi Again,
Try this below. As before, make sure your trigger is set on OnFormSubmit and it should work flawlessly. I've tested it myself, it only cleared the range between AN:AQ on row (wherever the form edits). If you want to delete different sections just replace the AN:AQ for whatever column(s) you wish to clear.
function onFormSubmit(e) {
var range = e.range;
var ss = range.getSheet();
var row = range.getRowIndex();
ss.getRange("AN:AQ"+row).clear();
}
I am trying to write a script that will delete all responses, start a new sheet and then style the new sheet by making the first row red color. Here is what I have so far:
function Initialize2() {
var form = FormApp.getActiveForm();
var ss = SpreadsheetApp.openById(form.getDestinationId());
form.deleteAllResponses();
form.removeDestination();
form.setDestination(FormApp.DestinationType.SPREADSHEET, ss.getId());
form = FormApp.getActiveForm();
ss = SpreadsheetApp.openById(form.getDestinationId());
var sheet = ss.getSheets()[0];
var range = sheet.getRange("A1:Z1");
range.setBackground("red");
sheet.setFrozenColumns(1);
}
The problem that I am facing is that it will create a new sheet, but the color update happens on the previously active sheet. How do I make it so that it updates the new active sheet?
By the time you select a sheet for color changes, the new sheet with form responses may not exist yet, because Sheets may postpone operations to improve performance. To ensure the creation has happened, call
SpreadsheetApp.flush();
before
var sheet = ss.getSheets()[0];
As a caveat, I am very new to Google Apps scripting. I appreciate any assistance that can be provided.
I am trying to copy the contents of a sheet into a new document. This code works without any problem:
// Create a new Spreadsheet and copy the current sheet into it.
var newSpreadsheet = SpreadsheetApp.create("Spreadsheet to export");
var projectname = SpreadsheetApp.getActiveSpreadsheet();
sheet = originalSpreadsheet.getActiveSheet();
sheet.copyTo(newSpreadsheet);
However, this copies over the formulas from the current sheet - I am trying to copy the values only, as the formulas reference data on other sheets in the original document.
My attempt to do this is as follows:
// Create a new Spreadsheet and copy the current sheet into it.
var newSpreadsheet = SpreadsheetApp.create("Spreadsheet to export");
var projectname = SpreadsheetApp.getActiveSpreadsheet();
sheet = originalSpreadsheet.getActiveSheet();
sheet.copyTo(newSpreadsheet, {contentsOnly:true})
However, this generates the following error: Cannot find method (class)copyTo($Proxy914,object).
I am unsure what I am doing wrong. Any assistance would be appreciated. Thanks in advance!
There are actually 2 copyTo, one applies to sheet and the other applies to Range
According to the documentation (see links above), the second one has optional argument to copy values only while the first has not.
What I guess you could do is use the Range.copyTo() to copy the whole sheet range to a temporary sheet (in the same spreadsheet) and then copy that temporary sheet to the other spreadsheet and finally delete the temporary sheet from the source spreadsheet.
Hoping it is clear enough ;-)
In the script gallery there is a script called spreadsheetFrozenBackup, through which a copy of a spreadsheet can be made.
The range.copyTo that Serge alludes to is used.
It is not a long script, so I reproduce it here for information:
// Make copy of current spreadsheet with backup name.
function spreadsheetFrozenBackup() {
// Get current spreadsheet.
var ss = SpreadsheetApp.getActiveSpreadsheet();
// Name the backup spreadsheet with date.
var bssName = ss.getName() + " frozen at " + Utilities.formatDate(new Date(), "GMT", "yyyyMMdd HHmmss");
var bs = SpreadsheetApp.openById((DocsList.copy(DocsList.getFileById(ss.getId()), bssName)).getId());
// Make sure all the formulae have been evaluated...
SpreadsheetApp.flush();
// Get all the sheets in the spreadsheet
var bsl = bs.getSheets();
var pl = "";
for (var i = 0; i < bsl.length; i++) {
bsl[i].getDataRange().copyTo(bsl[i].getDataRange(), {contentsOnly:true});
pl = pl + " " + bsl[i].getName();
SpreadsheetApp.getActiveSpreadsheet().toast(pl, "Processed Sheets");
}
SpreadsheetApp.getActiveSpreadsheet().toast(bssName, "Frozen Backup");
}