copy and paste with google spreadsheet script - google-apps-script

I would like to modify the script shown below, so that if re-run, it does not overwrite pre-existing data, but instead writes the rows under it.
(I use the google spreadsheet)
moveValuesOnly fonction () {
var ss = SpreadsheetApp.getActiveSpreadsheet ();
var source = ss.getRange ("Sheet1 F1: H3 ');
source.copyTo (ss.getRange ("Feuil2 A1! '), {contentsOnly: true});
source.clear ();
}

This version will find the first empty row in the destination sheet, and copy the source data so it starts there.
function moveValuesOnly () {
var ss = SpreadsheetApp.getActiveSpreadsheet ();
var source = ss.getRange ("Sheet1!F1:H3");
var destSheet = ss.getSheetByName("Feuil2");
// Déterminer l'emplacement de la première ligne vide.
var destRange = destSheet.getRange(destSheet.getLastRow()+1,1);
source.copyTo (destRange, {contentsOnly: true});
source.clear ();
}

Related

Google Sheets - App Script (copyTo - cell content & format)

I have a tracker to count daily productivity.
This is appended to a weekly tracker, in which the sum of the two serves as a running total.
The weekly tracker is appended to a separate sheet to serve as historical data.
TRACKER
DATA
As you can see in the 'DATA' screenshot, the formula is being copied from K12:O12
see function copyTT / source.copyTo
I want to retain cell formatting, and copy only the cell data, not it's formula.
Script;
function mergeTT() {
var ss = SpreadsheetApp.getActiveSpreadsheet ();
var source = ss.getRange("NEW_TTRACKER!J3:O3");
var destSheet = ss.getSheetByName("NEW_TTRACKER");
var lastRow = destSheet.getRange("J7:J11").getValues().filter(String).length;
var destRange = destSheet.getRange(lastRow+7,10,1,6);
source.copyTo(destRange, {contentsOnly: true});
var ws = ss.getSheetByName("NEW_TTRACKER")
ws.getRange('K3:O3').clearContent();
}
function copyTT() {
var ss = SpreadsheetApp.getActiveSpreadsheet ();
var source = ss.getRange("NEW_TTRACKER!J5:O12");
var destSheet = ss.getSheetByName("NEW_TDATA");
var destRange = destSheet.getRange(destSheet.getLastRow()+1,1);
source.copyTo(destRange, {contentsOnly: false});
var sheet = SpreadsheetApp.getActive().getSheetByName("NEW_TTRACKER");
sheet.getRange('J7:O11').clearContent();
}
Thanks in advance.
I've been attempting to get around it playing with different CopyPasteType properties and I'm really not getting anywhere.
About I've been attempting to get around it playing with different CopyPasteType properties, I think that your approach is correct. In your script, how about modifying your script as follows?
From:
source.copyTo(destRange, {contentsOnly: true});
To:
source.copyTo(destRange, { contentsOnly: true });
source.copyTo(destRange, SpreadsheetApp.CopyPasteType.PASTE_FORMAT, false); // Added
By this modification, the format is also copied.
Reference:
copyTo(destination, copyPasteType, transposed)

Copy Spreadsheet to a new file, specify tabs

I am copying a new instance of my spreadsheet without formulas into a folder. I found a script that works great here:
Copy an entire Spreadsheet, Just Preserve the Values.
I was trying to define a specific tab to copy but no luck.
var sheet = ss.getSheetByName('tab to dowload');
and
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.setActiveSheet(ss.getSheets()[2]);
function myFunction() {
var spreadsheetId = "###"; // Please set the source Spreadsheet ID.
var destFolderId = "###"; // Please set the destination folder ID.
// Copy each sheet in the source Spreadsheet by removing the formulas as the temporal sheets.
var ss = SpreadsheetApp.openById(spreadsheetId);
var tempSheets = ss.getSheets().map(function(sheet) {
var dstSheet = sheet.copyTo(ss).setName(sheet.getSheetName() + "_temp");
var src = dstSheet.getDataRange();
src.copyTo(src, {contentsOnly: true});
return dstSheet;
});
// Copy the source Spreadsheet.
var destination = ss.copy(ss.getName() + " - " + new Date().toLocaleString());
// Delete the temporal sheets in the source Spreadsheet.
tempSheets.forEach(function(sheet) {ss.deleteSheet(sheet)});
// Delete the original sheets from the copied Spreadsheet and rename the copied sheets.
destination.getSheets().forEach(function(sheet) {
var sheetName = sheet.getSheetName();
if (sheetName.indexOf("_temp") == -1) {
destination.deleteSheet(sheet);
} else {
sheet.setName(sheetName.slice(0, -5));
}
});
// Move file to the destination folder.
var file = DriveApp.getFileById(destination.getId());
DriveApp.getFolderById(destFolderId).addFile(file);
file.getParents().next().removeFile(file);
}
Explanation:
Your goal is to pass selected sheets, based on their name, to the newly created file.
You can do that by defining a list with the selected sheets:
var selected_sheets = ['Sheet1','Sheet5'];
and then instead of using ss.getSheets() which gets every sheet, use this to get the sheet object of the selected sheet names:
var tempSheets = selected_sheets.map(sn=>ss.getSheetByName(sn))
.map(function(sheet) {
var dstSheet = sheet.copyTo(ss).setName(sheet.getSheetName() + "_temp");
var src = dstSheet.getDataRange();
src.copyTo(src, {contentsOnly: true});
return dstSheet;
});
Solution:
Please modify this list: var selected_sheets = ['Sheet1','Sheet5']; and replace Sheet1, Sheet5 to the name of your sheets. You can also have one sheet: e.g. var selected_sheets = ['Sheet1'];.
function myFunction() {
var spreadsheetId = "###"; // Please set the source Spreadsheet ID.
var destFolderId = "###"; // Please set the destination folder ID.
// Copy each sheet in the source Spreadsheet by removing the formulas as the temporal sheets.
var ss = SpreadsheetApp.openById(spreadsheetId);
var selected_sheets = ['Sheet1','Sheet5']; // Add the sheets you want to copy here!
var tempSheets = selected_sheets.map(sn=>ss.getSheetByName(sn))
.map(function(sheet) {
var dstSheet = sheet.copyTo(ss).setName(sheet.getSheetName() + "_temp");
var src = dstSheet.getDataRange();
src.copyTo(src, {contentsOnly: true});
return dstSheet;
});
// Copy the source Spreadsheet.
var destination = ss.copy(ss.getName() + " - " + new Date().toLocaleString());
// Delete the temporal sheets in the source Spreadsheet.
tempSheets.forEach(function(sheet) {ss.deleteSheet(sheet)});
// Delete the original sheets from the copied Spreadsheet and rename the copied sheets.
destination.getSheets().forEach(function(sheet) {
var sheetName = sheet.getSheetName();
if (sheetName.indexOf("_temp") == -1) {
destination.deleteSheet(sheet);
} else {
sheet.setName(sheetName.slice(0, -5));
}
});
// Move file to the destination folder.
var file = DriveApp.getFileById(destination.getId());
DriveApp.getFolderById(destFolderId).addFile(file);
file.getParents().next().removeFile(file);
}

I need to write an onEdit function for a Google Sheets script

This is the script I want to trigger:
function moveValuesOnly () {
var ss = SpreadsheetApp.getActiveSpreadsheet ();
var source = ss.getRange ("Copy!A1:N200");
var destSheet = ss.getSheetByName("Paste");
var destRange = destSheet.getRange(destSheet.getLastRow()+1,1);
source.copyTo (destRange, {contentsOnly: true});
}
**// I want moveValuesOnly to trigger once Cell A10 in the Validation tab changes to '2'**
I would greatly appreciate any help as I am a bit green at the moment.
Kind regards,
Brendon
I would suggest to have a read at Simple Triggers and Installable Triggers.
Basically you can create any function and make it trigger using the ScriptApp class and those are called installable trigger.
But there are special functions that don't need to go through ScriptApp to get triggered, you just need to change the name of the function, and that would start enabling the trigger of those functions.
Simple trigger
Just change the name of the function so it will automatically start triggering.
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet ();
var source = ss.getRange ("Copy!A1:N200");
var destSheet = ss.getSheetByName("Paste");
var destRange = destSheet.getRange(destSheet.getLastRow()+1,1);
source.copyTo (destRange, {contentsOnly: true});
}
Installable Trigger
Create another function to execute on time to create the trigger
function moveValuesOnly(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet ();
var source = ss.getRange ("Copy!A1:N200");
var destSheet = ss.getSheetByName("Paste");
var destRange = destSheet.getRange(destSheet.getLastRow()+1,1);
source.copyTo (destRange, {contentsOnly: true});
}
function createTrigger(){
var ss = SpreadsheetApp.getActive();
ScriptApp.newTrigger('moveValuesOnly')
.forSpreadsheet(ss)
.onEdit()
.create();
}
You have specified in your code that only want to trigger when the cell is A10, but this is impossible as of right now. You need to create an if statement making sure the range being edited is the one you care about.
Look at the event objects because that would be input parameter of the trigger functions (e). That object has information about the range and spreadsheet being edited.
Basically make a condition with the e object
function onEdit(e) {
var range = e.range;
var newValue = e.value;
var oldValue = e.oldValue;
var sheet = range.getSheet();
if(sheet.getName() == "<Your sheet name>" && newValue == 2 && range.getColumn() == 1 && range.getRow() == 10){
// Browser.msgBox("Edit entered condition");
//
// Do your stuff here when the condition is satisfied
}
}

Copy an Area into the next empty Row of another spreadsheet

I am trying to copy a certain area into the next empty row of another spreadsheet.
Right now I am only able to copy it to a certain destination.
This is the code I am currently using:
function myFunction() {
var sheet=SpreadsheetApp.getActiveSheet();
var source="A3:S3";
var destination="Historie!B3";
sheet.getRange(source).copyTo(sheet.getRange(destination));
}
try something like this:
function xxx() {
var reference = 'sheet1!A2';
var rng = SpreadsheetApp.getActiveSpreadsheet().getRange(reference);
rng.setValue(rng.getValue()+1);
var ss = SpreadsheetApp.getActiveSpreadsheet ();
var ss = SpreadsheetApp.getActiveSpreadsheet ();
var source = ss.getRange ("Sheet1!A3:S3");
var destSheet = ss.getSheetByName("Historie");
var values = source.getValues().filter(function(e) {return e.some(function(f) {return f})});
destSheet.getRange(destSheet.getLastRow() + 1, 1, values.length, values[0].length).setValues(values);
}

Copy and Delete a column with transpose style

I have in a column the invoice info of a client (name, address, email, phone number) each one in one row of the column A, and I need to Copy it to another range in transpose style.
I used the following script trying to edit it as I need but I do not find how
function copyAndDeleteSalidas () {
var ss = SpreadsheetApp.getActiveSpreadsheet ();
var source = ss.getRange ("Sheet1!A1:A6");
var destSheet = ss.getSheetByName("Sheet2!");
var destRange = destSheet.getRange(destSheet.getLastRow()+1,1);
source.copyTo (destRange, {contentsOnly: true});
source.clear ();
}
You'll need a function for transposing 2D arrays, since it appears there isn't a built-in option for this purpose in Apps Script. There are several versions of such a function on Stack Overflow, I used one of them below.
The main difference from your script is that instead of copyTo, I use setValues and getValues. Also, the destination range now must have the size that matches the size of values inserted in it.
function copyTransposeAndDelete () {
var ss = SpreadsheetApp.getActiveSpreadsheet ();
var source = ss.getRange("Sheet1!A1:A6");
var destSheet = ss.getSheetByName("Sheet2");
var destRange = destSheet.getRange(destSheet.getLastRow()+1, 1, source.getWidth(), source.getHeight());
destRange.setValues(transpose(source.getValues()));
source.clear ();
}
function transpose(array) {
return array[0].map(function(col, i) {
return array.map(function(row) {
return row[i];
});
});
}