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().
Related
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)
I'm trying to write a macro in gsheets that will concatenate two columns and then copy the values back over to the first column. But everything I try the copy to column just gets blanked out.
function CopyandPasteValues() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange('H2').activate();
spreadsheet.getCurrentCell().setFormula('=CONCATENATE(E2,"",G2)');
spreadsheet.getActiveRange().autoFill(spreadsheet.getRange('H2:H249'), SpreadsheetApp.AutoFillSeries.DEFAULT_SERIES);
spreadsheet.getRange('H2:H249').activate();
spreadsheet.getRange('E2').activate();
spreadsheet.getRange('H2:H249').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
SpreadsheetApp.flush();
};
If you only need the values, try the the following:
function CopyandPasteValues() {
var spreadsheet = SpreadsheetApp.getActive();
var values = spreadsheet.getRange('E2:G249').getDisplayValues();
var output = values.map(row => row[0] + row[2]);
spreadsheet.getRange('H2:H249').setValues(output);
};
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
I need some assistance with Google Apps Script. I am working in google sheets and currently have the following script:
function transpose() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange('C3:N3').activate();
spreadsheet.setActiveSheet(spreadsheet.getSheetByName('Sheet21'), true);
spreadsheet.getRange("'A/P'!C3:N3").copyTo(spreadsheet.getActiveRange(),
SpreadsheetApp.CopyPasteType.PASTE_NORMAL, true);
};
Rather than just paste in A1 of Sheet 21, I would like it to find the bottom of column F. I am also wondering how to copy data from whichever sheet I am in, not just the sheet named A/P.
Thank you in advance!
You want to add the values of C3:N3 in the active sheet to the next row of last row on column F in Sheet21. If my understanding is correct, how about this modification?
Modification points :
In your script, if the active sheet is not Sheet21, the active range becomes "A1", because spreadsheet.getRange('C3:N3').activate() at other sheet is changed by spreadsheet.setActiveSheet(spreadsheet.getSheetByName('Sheet21'), true). By this, the values of "'A/P'!C3:N3" are copied for "A1" of Sheet21.
Flow of modified script:
Retrieve the range of source (Active sheet)
Retrieve the destination (Sheet21) sheet.
Retrieve the destination range.
Copy
Modified script : Pattern 1
If the address of last row of column "F" in "Sheet21" is smaller than that of other columns, please use this.
function transpose() {
var spreadsheet = SpreadsheetApp.getActive();
var srcRange = spreadsheet.getActiveSheet().getRange('C3:N3');
var dstSheet = spreadsheet.getSheetByName('Sheet21');
var range = dstSheet.getRange('F1:F');
var values = range.getValues();
var formulas = range.getFormulas();
var i;
for (i = values.length - 1; i >= 0; i--) {
if (values[i][0] != "" || formulas[i][0] != "") break;
}
var dstRange = dstSheet.getRange("F" + (i + 2));
srcRange.copyTo(dstRange, SpreadsheetApp.CopyPasteType.PASTE_NORMAL, true);
};
Modified script : Pattern 2
If the address of last row of column "F" in "Sheet21" is larger or the same with that of other columns, please use this.
function transpose() {
var spreadsheet = SpreadsheetApp.getActive();
var srcRange = spreadsheet.getActiveSheet().getRange('C3:N3');
var dstSheet = spreadsheet.getSheetByName('Sheet21');
var dstRange = dstSheet.getRange("F" + (dstSheet.getLastRow() + 1));
srcRange.copyTo(dstRange, SpreadsheetApp.CopyPasteType.PASTE_NORMAL, true);
};
If I misunderstand your question, please tell me. I would like to modify it.
I'm trying to use the function copyTo(destination, copyPasteType, transposed) to copy a sheet in one file to another sheet in a different file while keeping everything, including column width, the same. Using just the function copyTo(destination), my code works and I get everything I want in a different file, EXCEPT the column width. However, when I try and use copyTo with the copyPasteType argument, the sheet is copied perfectly (with the correct column widths), BUT any subsequent code isn't run. Why is this happening, and how can I fix it?
function createSpreadsheet(foldername) {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getSheetByName('Sheet1');
var folder = DriveApp.getFolderById(foldername);
RESPONSE = FileName(); //a function that prompts the user for a filename
//creates a new spreadsheet which has two sheets, and deletes the "Copy of Sheet1" sheet
var newSpreadsheet = SpreadsheetApp.create(RESPONSE);
var newsheet = newSpreadsheet.getSheetByName('Sheet1');
var copysheet = sheet.copyTo(newSpreadsheet);
sheet.copyTo(newSpreadsheet, SpreadsheetApp.CopyPasteType.PASTE_NORMAL, false);
//when using CopyPasteType argument, everything from here down isn't run
copysheet.getDataRange().copyTo(newsheet.getDataRange());
copysheet.getDataRange().copyTo(newsheet.getDataRange(),
SpreadsheetApp.CopyPasteType.PASTE_NORMAL, false);
newSpreadsheet.deleteSheet(copysheet);
var newSpreadsheetID = newSpreadsheet.getId();
var file = DriveApp.getFileById(newSpreadsheetID);
folder.addFile(file);
DriveApp.removeFile(file);
clearYellow(); //clears contents of yellow cells
clearGray(); //clears contents of gray cells
}
I've also asked this question in Google+
I didn't find an answer as to why the copyTo with three arguments stopped the rest of my function from executing, but I found another way to copy the column widths over to the new spreadsheet that works.
function createSpreadsheet(foldername) {
var oldspreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var oldsheet = oldspreadsheet.getSheetByName('Sheet1');
var folder = DriveApp.getFolderById(foldername);
RESPONSE = FileName();
//creates a new spreadsheet which has two sheets, and deletes the "Copy of Sheet1" sheet
var newSpreadsheet = SpreadsheetApp.create(RESPONSE);
var newsheet = newSpreadsheet.getSheetByName('Sheet1');
var copysheet = oldsheet.copyTo(newSpreadsheet);
copysheet.getDataRange().copyTo(newsheet.getDataRange());
var numberOfColumns = oldsheet.getLastColumn();
for (columnNumber = 1; columnNumber <= numberOfColumns; columnNumber++){
var Width = oldsheet.getColumnWidth(columnNumber);
newsheet.setColumnWidth(columnNumber, Width);
};
newSpreadsheet.deleteSheet(copysheet);
var newSpreadsheetID = newSpreadsheet.getId();
var file = DriveApp.getFileById(newSpreadsheetID);
folder.addFile(file);
DriveApp.removeFile(file);
clearYellow(); //clears contents of yellow cells
clearGray(); //clears contents of gray cells
}