In an effort to organize a set of bank account and credit card statements, I download them. Then I open them in Excel or Google Sheets, reorganize them in matching columns, put all in one tab (TOTAL), and then sort.
The question is now how I do the copy from the individual sheets. I think I'm pretty close after pasting and repeating (the manual way) some function I found by searching. The problem is that this function removes all formatting from the source rows
Example sheet
The last tab example_TOTAL is put there only to show how I want tab TOTAL to look after the process is done.
Here's my function so far which does the most, but erases formatting (colors).
function Copy() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var ss = spreadsheet.getSheetByName('TabA'); //replace with source Sheet tab name
var range = ss.getRange('A1:L'); //assign the range you want to copy
var data = range.getValues();
var ts = spreadsheet.getSheetByName('TOTAL'); //replace with destination Sheet tab name
ts.getRange(ts.getLastRow()+1, 1, data.length, data[0].length).setValues(data);
var ss = spreadsheet.getSheetByName('TabB'); //replace with source Sheet tab name
var range = ss.getRange('A1:L'); //assign the range you want to copy
var data = range.getValues();
ts.getRange(ts.getLastRow()+1, 1, data.length, data[0].length).setValues(data);
var ss = spreadsheet.getSheetByName('TabC'); //replace with source Sheet tab name
var range = ss.getRange('A1:L'); //assign the range you want to copy
var data = range.getValues();
ts.getRange(ts.getLastRow()+1, 1, data.length, data[0].length).setValues(data);
var ss = spreadsheet.getSheetByName('TabD'); //replace with source Sheet tab name
var range = ss.getRange('A1:L'); //assign the range you want to copy
var data = range.getValues();
ts.getRange(ts.getLastRow()+1, 1, data.length, data[0].length).setValues(data);
}
function copyFromTo() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var ss = spreadsheet.getSheetByName('TabA');
var copy = ss.getRange('A1:L');
var target = spreadsheet.getSheetByName('TOTAL');
var dest = target.getRange('A1:L');
copy.copyTo(dest);
var ss = spreadsheet.getSheetByName('TabB');
var copy = ss.getRange('A1:L');
copy.copyTo(dest);
var ss = spreadsheet.getSheetByName('TabC');
var copy = ss.getRange('A1:L');
copy.copyTo(dest);
var ss = spreadsheet.getSheetByName('TabD');
var copy = ss.getRange('A1:L');
copy.copyTo(dest);
}
How can I append from these sheets and still keep the formatting?
Related
Background
I wrote script for copying range of cells from one document to another. It works correctly. But depending on volume of data it could run for 10+ minutes. Which is odd, because manual copy-pasting of this data without script will took 2 minutes. I ran some tests that revealed most time-consuming piece of code that needs to be speed up
Question
What is the quickest method of copying range of cells from one Google Spreadsheet document to another? Or how should I change my code to speed it up?
// Copying 1st batch of data
var srcLastRow = srcSheet1.getLastRow();
var srcLastCol = srcSheet1.getLastColumn();
var srcRange = srcSheet1.getRange(2, 1, srcLastRow-1, srcLastCol);
var transfValues = srcRange.getValues();
destSheet.getRange(destLastRow + 1,1,srcLastRow-1, srcLastCol).setValues(transfValues);
Appendix
And here is full script, that runs correctly but slow, just in case
function sborka() {
// Destination sheet variables
var destSpreadSheet = SpreadsheetApp.getActiveSpreadsheet();
var destSheet = destSpreadSheet.getSheetByName("destination");
// Source sheet variables
var srcSpreadSheet1 = SpreadsheetApp.openById('xxxxxx');
var srcSheet1 = srcSpreadSheet1.getSheetByName("source 1");
var srcSpreadSheet2 = SpreadsheetApp.openById('ууууууу');
var srcSheet2 = srcSpreadSheet2.getSheetByName("source 2");
// Clear all except 1st row with headers
var destLastRow = destSheet.getLastRow();
destSheet.deleteRows(2,destLastRow)
// What is last row in destination sheet?
var destLastRow = destSheet.getLastRow();
// Copying 1st batch of data
var srcLastRow = srcSheet1.getLastRow();
var srcLastCol = srcSheet1.getLastColumn();
var srcRange = srcSheet1.getRange(2, 1, srcLastRow-1, srcLastCol);
var transfValues = srcRange.getValues();
destSheet.getRange(destLastRow + 1,1,srcLastRow-1, srcLastCol).setValues(transfValues);
// What is last row in destination sheet now?
var destLastRow = destSheet.getLastRow();
// Copying 2nd batch of data
var srcLastRow = srcSheet2.getLastRow();
var srcLastCol = srcSheet2.getLastColumn();
var srcRange = srcSheet2.getRange(2, 1, srcLastRow-1, srcLastCol);
var transfValues = srcRange.getValues();
destSheet.getRange(destLastRow + 1,1,srcLastRow-1, srcLastCol).setValues(transfValues);
// Done
}
Try this:
var srcSheet1 = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var destSS = SpreadsheetApp.openById("destination ss id");
//Copy Source Sheet
srcSheet1.copyTo(destSS);
var newSrcSheet1 = destSS.getSheetByName("Copy of "+srcSheet1.getName());
Logger.log(newSrcSheet1);
//Copy range
var destSheet = destSS.getSheetByName("Sheet1");
var srcLastRow = newSrcSheet1.getLastRow();
var srcLastCol = newSrcSheet1.getLastColumn();
var srcRange = newSrcSheet1.getRange(2, 1, srcLastRow-1, srcLastCol);
srcRange.copyTo(destSheet.getRange(destSheet.getLastRow() + 1,1));
//Delete Sheet
destSS.deleteSheet(newSrcSheet1);
I copied first the source sheet to the destination spreadsheet. The name of the copied sheet will be "Copy of [original sheet name]". Refer to Sheet.copyTo()
Then, I copied the range from the new source sheet to the destination sheet using Range.copyTo(destination)
Lastly, I deleted the new source sheet.
With this script ( Generate new spreadsheet from a selected row based on template ) I can generate a new spreadsheet (and so not a tab), based on a template tab (in this case, the tab "xxx") only when I select a specific row and rename this Spreadsheet as the value in the cell in column B for that corresponding row.
Now, I would copy the value of the cell A2 from the source spreadsheet into the tab "xxx" in the cell A3.
How to do that?
function onOpen() {
SpreadsheetApp.getUi().createMenu('Genera Scheda')
.addItem('Genera Scheda', 'createSpreadsheet')
.addToUi()}
function createSpreadsheet() {
var ss = SpreadsheetApp.getActive();
// the following line means that the function will search for the spreadsheet name in the active sheet, no matter which one it is
var sheet = ss.getActiveSheet();
//the selected row
var row = sheet.getActiveCell().getRow();
// column 2 corresponds to "B"
var name = sheet.getRange(row, 2).getValue();
var templateSheet1 = ss.getSheetByName('xxx');
var templateSheet2 = ss.getSheetByName('xxx2');
var newSpreadsheet = SpreadsheetApp.create(name);
var fileId = newSpreadsheet.getId();
var file = DriveApp.getFileById(fileId);
var folderId ="-----";
var folder = DriveApp.getFolderById(folderId);
templateSheet1.copyTo(newSpreadsheet).setName("Scheda");
templateSheet2.copyTo(newSpreadsheet).setName("Import")
newSpreadsheet.deleteSheet(newSpreadsheet.getSheetByName("Foglio1"));
folder.addFile(file);
DriveApp.getRootFolder().removeFile(file);
}
To copy individual cell values between tabs and spreadsheets, a good solution is to use getValue() and setValue()
This methods must be applied to range objects (that is the cells).
Sample:
...
// define sheet either as the active sheet or specify it with sheet = ss.getSheetByName("XXX");
var myValue = sheet.getRange("A2").getValue();
newSpreadsheet.getSheetByName("xxx").getRange("A3").setValue(myValue);
...
Note that if you want to get / set values of more than one cell simulataneously, you need to use getValues() and setValues() instead.
UPDATE
Full code based on your situation:
function onOpen() {
SpreadsheetApp.getUi().createMenu('Genera Scheda')
.addItem('Genera Scheda', 'createSpreadsheet')
.addToUi()}
function createSpreadsheet() {
var ss = SpreadsheetApp.getActive();
// the following line means that the function will search for the spreadsheet name in the active sheet, no matter which one it is
var sheet = ss.getActiveSheet();
//the selected row
var row = sheet.getActiveCell().getRow();
// column 2 corresponds to "B"
var name = sheet.getRange(row, 2).getValue();
var templateSheet1 = ss.getSheetByName('xxx');
var templateSheet2 = ss.getSheetByName('xxx2');
var newSpreadsheet = SpreadsheetApp.create(name);
var fileId = newSpreadsheet.getId();
var file = DriveApp.getFileById(fileId);
var folderId ="-----";
var folder = DriveApp.getFolderById(folderId);
templateSheet1.copyTo(newSpreadsheet).setName("Scheda");
templateSheet2.copyTo(newSpreadsheet).setName("Import")
var myValue = sheet.getRange("A2").getValue();
newSpreadsheet.getSheetByName("Scheda").getRange("A3").setValue(myValue);
newSpreadsheet.deleteSheet(newSpreadsheet.getSheetByName("Foglio1"));
folder.addFile(file);
DriveApp.getRootFolder().removeFile(file);
}
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'm trying to make a script that will copy a cursor selection range to an other sheet, script is partially working
The script is coping some values, some of the values selected from the target sheet
function copy(){
var sh = SpreadsheetApp.getActiveSheet();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var range = ss.getActiveRange();
var srange = range.getA1Notation();
var crange= ss.getRange(srange);
var data = crange.getValues();
var tss = SpreadsheetApp.openById('id');
var ts = tss.getSheetByName('Tracker');
ts.getRange('B16:K200').setValue(data)
}
The script should copy the selected value with the mouse from the selected sheet in the specified location for the target sheet
The key is to identify the activerange, and the relevant get row and column values. Then using "B16" as a starting point for the outout, you simply add the number of Rows and number of Columns calculated from the activerange.
Highlight any range, run the function, and the contents of the range will be copied to the same sheet with cell "B16" in the top lefthand corner.
It's a simple matter to modify the code to create the output range and copy the values to another spreadsheet.
function so5666559701() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheetname = "56665597";
var sheet = ss.getSheetByName(sheetname);
var myrange = sheet.getActiveRange();
var myvalues = myrange.getValues();
//Logger.log("DEBUG: the active range = "+myrange.getA1Notation());
var myfirstRow = myrange.getRow();
var mylastRow = myrange.getLastRow();
var myfirstCol = myrange.getColumn();
var mylastCol = myrange.getLastColumn();
//Logger.log("DEBUG: details of the selectred range: row: first row="+myfirstRow+", first column="+myfirstCol+", last row="+mylastRow+" last column:"+mylastCol);
// target cell = B16 = row 16, column 2
var targetrange = sheet.getRange(16,2,mylastRow-myfirstRow+1,mylastCol-myfirstCol+1);
//Logger.log("DEBUG: the target range = "+targetrange.getA1Notation());
targetrange.setValues(myvalues);
}
Script would run in the source workbook.
function CopyDataToNewFile() {
var sss = SpreadsheetApp.openById('1yeS6_qhURUYHVkImLNMjdGUeMWhPDwQKdLNgpygiwG4'); // sss = source spreadsheet
var ss = sss.getSheetByName('Sheet1'); // ss = source sheet
//Get full range of data
var SRange = ss.getDataRange();
//get A1 notation identifying the range
var A1Range = SRange.getA1Notation();
//get the data values in range
var SData = SRange.getValues();
var tss = SpreadsheetApp.openById('1KQBsMJ0vgBQwkM89d166RPyVahIZY3DRSOWVCB4zapE'); // tss = target spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
var first = ss.getSheetByName('Sheet1');
sheet.clear({ formatOnly: false, contentsOnly: true });
var tss = SpreadsheetApp.openById('1KQBsMJ0vgBQwkM89d166RPyVahIZY3DRSOWVCB4zapE');
var ts = tss.getSheetByName('Sheet1'); // ts = target sheet
//set the target range to the values of the source data
ts.getRange(A1Range).setValues(SData);
}
Would set to trigger on form submit. Would copy the data from a sheet in one workbook to a sheet in another workbook. Format of both sheets will be same AND must remain unaltered. Row & column count/size will be same on each sheet.
Here a code that will go through all the sheet of your source workbook and copy data in the current workbook. Sheet name will be the same of source spreadsheet and only data are copied.
EDIT : Code changed to not copy but import data from spreadsheet to a dest spreadsheet where we assume that the sheet is already created. If sheet does not exist we create it.
function importWorkBook(){
var idSource = "IdOfTheSheetSource";
var sheets = SpreadsheetApp.openById(idSource).getSheets();
var current = SpreadsheetApp.getActiveSpreadsheet();
for(var i in sheets){
var sheet = sheets[i];
var data = sheet.getDataRange().getValues();
var destSheet = current.getSheetByName(sheet.getName());
if(destSheet){
destSheet.getRange(1,1,destSheet.getMaxRows(),destSheet.getMaxColumns()).clearContent();
destSheet.getRange(1,1,data.length,data[0].length).setValues(data);
Logger.log(sheet.getName() + " imported");
}else{
var newSheet = current.insertSheet(sheet.getName());
newSheet.getRange(1,1,data.length,data[0].length).setValues(data);
Logger.log(sheet.getName() + " created");
}
}
}
Stéphane