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

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)

Related

Copy in new row every time run app script in google sheets

I try to create script to copy one specific row from one sheet to another sheet in new row.
But the script allways copy replace the last one.
I use this code:
function Test() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange('A9:O9').activate();
spreadsheet.setActiveSheet(spreadsheet.getSheetByName('Logs'), true);
spreadsheet.getRange('A24').activate();
spreadsheet.getRange('Log!A9:O9').copyTo(spreadsheet.getActiveRange(),
spreadsheetApp.CopyPasteType.PASTE_VALUES, false);
spreadsheet.setActiveSheet(spreadsheet.getSheetByName('Log'), true);
spreadsheet.getRange('D9:O9').activate();
spreadsheet.getActiveRangeList().clear({contentsOnly: true, skipFilteredRows: true});
};
Your script always copies the data to the activated range - which is always A24
Rewrite your funciton by specifying to where you want to copy your row. If you do not want to overwrite, probably you want to append your row at the bottom of the destination sheet.
You can do it as following:
function Test() {
var spreadsheet = SpreadsheetApp.getActive();
var originSheet = spreadsheet.getSheetByName("Log");
var destSheet = spreadsheet.getSheetByName("Logs");
var rowContents = originSheet.getRange('A9:O9').getValues().flat();
destSheet.appendRow(rowContents);
};
Alternatively, you can copy the data to the first empty row:
function Test() {
var spreadsheet = SpreadsheetApp.getActive();
var originSheet = spreadsheet.getSheetByName("Log");
var destSheet = spreadsheet.getSheetByName("Logs");
var firstEmtyRow = destSheet.getLastRow() + 1;
var destRange = destSheet.getRange('A' + firstEmtyRow + ':O' + firstEmtyRow);
originSheet.getRange('A9:O9').copyTo(destRange,
spreadsheetApp.CopyPasteType.PASTE_VALUES, false);
};
References:
getSheetByName()
appendRow()
flat()
getLastRow()
As pointed out by #Mike Steelson, activating sheets and ranges is not good practice. It is performed in the background if you record a macro, but it is prone to errors, so if you write a script yourself - avoid activate().

Sheet.hide() sometimes works sometimes not

this is my final script
function archive2() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var source = ss.getSheetByName('Lista'); // name of source sheet
var sourceRange = source.getRange('A1:B'); // range to copy
var destination1 = ss.getSheetByName('Sheet2'); // name of log sheet
var lastRow = destination1.getLastRow();
sourceRange.copyTo(destination1.getRange(5000 + 1, 1),{contentsOnly:true});
var source = ss.getSheetByName('Sheet2'); // name of source sheet
var sourceRange = source.getRange('H1:I5000'); // range to copy
var destination2 = ss.getSheetByName('Sheet3'); // name of log sheet
var lastRow = destination2.getLastRow();
destination2.getRange('A1:B').activate();
destination2.getActiveRangeList().clear({contentsOnly: true, skipFilteredRows: true});
var source = ss.getSheetByName('Sheet2'); // name of source sheet
var sourceRange = source.getRange('H1:I5000'); // range to copy
var destination3 = ss.getSheetByName('Sheet3'); // name of log sheet
sourceRange.copyTo(destination3.getRange(1 + 1, 1),{contentsOnly:true});
var spreadsheet = SpreadsheetApp.getActive();
var source = ss.getSheetByName('Sheet3'); // name of source sheet
var sourceRange = source.getRange('A1:B5000'); // range to copy
var destination4 = ss.getSheetByName('Sheet2'); // name of log sheet
var lastRow = destination4.getLastRow();
spreadsheet.setActiveSheet(spreadsheet.getSheetByName('Sheet2'), true);
spreadsheet.getRange('A:B').activate();
spreadsheet.getActiveRangeList().clear({contentsOnly: true, skipFilteredRows: true});
sourceRange.copyTo(destination4.getRange('A:B'),{contentsOnly:true});
var hide1 = ss.getSheetByName('Sheet2');
hide1.hideSheet();
var hide2 = ss.getSheetByName('Sheet3');
hide2.hideSheet();
}
Basically it makes a static copy of some data that I need to sum later. This part works fine.
What isn't working are the last lines, basically I want to hide Sheet2 and Sheet3, which are helper sheets to make the calcs.
The best way would be to make all the calcs without unhide those sheets but I wasn't able to find a solution (so if someone know what I've to change to perform it, would be great), so I'm searching a way to at least hide them after the script run.
With these lines, sometimes they are both hide, sometime just 1 of them (randomly between sheet2 and sheet3, I guess it have something to do with "active", and so I've tried to active both in sequence but still doesn't work).
Could you help me to hide both everytime (or make it works without unhide anything at all) without failures? Thanks
https://docs.google.com/spreadsheets/d/1GREsQNrDAaLqOROwAixajK6tpTRGOhqGHo0kfyyyuGw/edit#gid=0

Paste into a Specific Column - Google Sheets

Good afternoon, I made this script.
But, it's pasting in column A and I need to paste it in column E.
How can I do this?
function Teste() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var source = ss.getRange('Entradas!B9:H29');
var spreadsheet = SpreadsheetApp.getActive();
var destSheet = ss.getSheetByName('BD');
var lastFilledRowInColumnE = getLastPopulatedRow(destSheet.getRange('E:K').getValues());
var destRange = destSheet.getRange(lastFilledRowInColumnE+1,1);
source.copyTo(destRange, {contentsOnly: true});
};
I think the problem could be with the line:
var destRange = destSheet.getRange(lastFilledRowInColumnE+1,1);
There are a few different getRange functions. If you only supply two arguments, you are calling the getRange(row, column) version. You are pasting into the row "lastFilledRowInColumnE+1" and column 1, which is A.
You may simply need to write "5" instead of "1" to represent column "E".

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];
});
});
}

Issue with my script to store Google spreadsheet data daily

I've been having trouble getting my scripts to work for my investment portfolio spreadsheet. They were working fine until early May and I've been unable to get them to work since. What I'm trying to do is store the performance of my portfolio each day to a separate sheet. The script should be finding the next empty row and putting the current date in the first column and the value in the 2nd column. What it's doing is overwriting the row each time the script is run.
Here is my script:
function storePerf() {
SpreadsheetApp.flush();
var ss = SpreadsheetApp.getActiveSpreadsheet();
SpreadsheetApp.setActiveSheet(ss.getSheets()["0"]);
var source = ss.getRange ("Performance!G28");
var destSheet = ss.getSheetByName("Performance Historical");
var numRows = source.getNumRows();
var numColumns = source.getNumColumns();
var nextColumn = numColumns +1;
// Determine the first empty row to paste to.
var destRange = destSheet.getRange(destSheet.getLastRow()+1,2);
source.copyTo (destRange, {contentsOnly: true});
// Print date in the cell to the right of the latest price
destSheet.getRange(destSheet.getLastRow(),1).setValue(new Date());
SpreadsheetApp.flush();
}
Any help would be much appreciated.
thanks
Also add the +1. Or add the flush function before. The script is faster then the added row.
SpreadshertApp.flush()
destSheet.getRange(destSheet.getLastRow(),1).setValue(new Date());
But then Isuggest you use appendRow and make it a lot easier:
var source = ss.getRange ("Performance!G28");
var destSheet = ss.getSheetByName("Performance Historical");
//make a new row
var newRow = [source.getValue(), new Date()]
destSheet.appendRow([newRow]);
SpreadsheetApp.flush();