Copy dynamic range from one sheet to another - google-apps-script

I am using the below code to copy my data from sheet1 to sheet2 and append the data in sheet2 if script runs again? The issue is that my range is not fixed in sheet 1,I want to copy whatever range contains the content should be copied to sheet2 Can anyone guide that what to change in the below code to get the result?
function copyInfo() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var copySheet = ss.getSheetByName("sheet1");
var pasteSheet = ss.getSheetByName("sheet2");
var source = copySheet.getrange(2,1,200,7);
var destination = pasteSheet.getRange(pasteSheet.getLastRow()+1,1,200,7);
source.copyTo(destination, {contentsOnly:true});
var data = copySheet.getRange(2,1,200,6)
data.clearContent()
}

Method1:
Include:
var paste_lr = pasteSheet.getLastRow()
Modify:
var source = copySheet.getrange(paste_lr+1,1,200,7);
Similarly change 200 using same function.
Method2:
var sp = PropertiesService.getScriptProperties();
var SourceLr = sp.getProperty("Source_Data_Rows") || 0;
var source = copySheet.getrange(SourceLr+1,1,200,7);
var Source_Lr = copySheet.getLastRow();
sp.setProperty("Source_Data_Rows", Source_Lr);

Related

How do i paste into another file through app script

I am using this code:
function copyInfo() {  
var ss = SpreadsheetApp.getActiveSpreadsheet();  
var copySheet = ss.getSheetByName("Product-analyse");  
var pasteSheet = ss.getSheetByName("Blad18"); // get source range  
var source = copySheet.getRange(93,7,39,6);  // get destination range  
var destination = pasteSheet.getRange(pasteSheet.getLastRow()+1,1,39,6); // copy values to destination range  
source.copyTo(destination);  // clear source values
source.clearContent();
} 
Now its pasting in "Blad18". Instead I want it to be pasted in another file.
I tried adding {contentOnly: TRUE}. Though this didnt seem to work
I cannot figure this out unfortunately. Everything else is correctly set already.
Any help is greatly appreciated.
Updated script I am using:
function copyInfo() {
var ssSource = SpreadsheetApp.getActiveSpreadsheet();
var copySheet = ssSource.getSheetByName("Product-analyse");
var ssPaste = SpreadsheetApp.openById("1qhnA8L3ZkU-iEyOJtszAC4OW58sg2TJZSa_rmN_EXBI"); // the id of the other spreadsheet
var pasteSheet = ssPaste.getSheetByName("Submitted Data"); // get source range
var source = copySheet.getRange(93,7,39,6); // get destination range
var destination = pasteSheet.getRange(pasteSheet.getLastRow()+1,1,39,6); // copy values to destination range
source.copyTo(destination); // clear source values
source.clearContent();
}
Try this:
function copyInfo() {
var ss = SpreadsheetApp.getActive();
var csh = ss.getSheetByName("Sheet0");
var psh = ss.getSheetByName("Sheet1");
const cshsr = 2;
var crg = csh.getRange(cshsr, 1, csh.getLastRow() - cshsr + 1, csh.getLastColumn());
var prg = psh.getRange(psh.getLastRow() + 1, 1);
crg.copyTo(prg);
}
I believe what you want to do is copy from one spreadsheet file to another spreadsheet file. Here is an example
function copyInfo() {
var ssSource = SpreadsheetApp.getActiveSpreadsheet();
var copySheet = ssSource.getSheetByName("Product-analyse");
var ssPaste = SpreadsheetApp.openById("dfsfhsfhskfhaskjfhsjkfas"); // the id of the other spreadsheet
var pasteSheet = ssPaste.getSheetByName("Blad18"); // get source range
var source = copySheet.getRange(93,7,39,6); // get destination range
var destination = pasteSheet.getRange(pasteSheet.getLastRow()+1,1,39,6); // copy values to destination range
source.copyTo(destination); // clear source values
source.clearContent();
}
Reference
SpreadsheetApp.openById()

Run function on 1 sheet only instead of .forEach

I believe this will be a super easy question for you. I downloaded a YT script to automatically update YT views on Google Sheets which you can find here (https://developers.google.com/gsuite/solutions/youtube-tracker).
I have a spreadsheet with 12 tabs and the code has a function to go through every tab in the spreadsheet.
function markVideos() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();
// Runs through process for each tab in Spreadsheet.
sheets.forEach(function(dataSheet) {
var tabName = dataSheet.getName();
var range = dataSheet.getDataRange();
var numRows = range.getNumRows();
var rows = range.getValues();
var headerRow = rows[0];
I want to change it to apply to a specific tab only, let's say "Sheet12", instead of running it for every tab.
function markVideos() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet12");
// Runs through process for each tab in Spreadsheet.
function NameOfTheFunction(dataSheet) {
var tabName = dataSheet.getName();
var range = dataSheet.getDataRange();
var numRows = range.getNumRows();
var rows = range.getValues();
var headerRow = rows[0];
I tried this but had no luck because it doesn't seem to be applying the function to the specific sheet. I believe this is super easy fix but I have no idea about programming.
Remove the forEach statement and use getSheetByName instead of getSheets:
function markVideos() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var tabName = 'Sheet12';
var dataSheet = ss.getSheetByName(tabName)
var range = dataSheet.getDataRange();
var numRows = range.getNumRows();
var rows = range.getValues();
var headerRow = rows[0];
}
Array ForEach() Method calls a function once for each element in an array. That is why a function must be defined that will take an array element function(dataSheet)
Since you only need to access 1 sheet based on its sheet name.
You don't need to define a function to access the properties of that sheet.
Sample:
Sample Code:
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheetByName("Sheet1");
var tabName = sheets.getName();
var range = sheets.getDataRange();
var numRows = range.getNumRows();
var rows = range.getValues();
var headerRow = rows[0];
Logger.log(tabName);
Logger.log(numRows);
Logger.log(rows);
Logger.log(headerRow);
}
Logger Log Output:
References:
Class Sheet Methods
SpreadsheetApp Methods

Script issue with an array reference

Please excuse the length of the post I was getting help but the person has not been online for the last week so thought I would try here to get the last few kinks out. Thank you for any extra help.
Here is my original script.
function ImportDataRange() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("AM trip"); //To Sheet Name
var ssraw = SpreadsheetApp.openById("1n4**4HzvVS****RQhPHndUbn0N0nkpOE5NpO2U"); // From Spreadsheet ID
var sheetraw = ssraw.getSheetByName("AM trip"); // From Sheet name
var range = sheetraw.getRange("B9:U38");
var data = range.getValues();
sheet.getRange("C1").setValues(data)
}
My adjusted script:-
function ImportDataRange() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('AM trip'); //To Sheet Name
var ssraw = SpreadsheetApp.openById('18h-UAy10EvANHZXLebspZsUbE2fisyEBAFnUYV9JBHs'); // From Spreadsheet ID
var sheetraw = ssraw.getSheetByName('AM trip'); // From Sheet name
var range = sheetraw.getRange('B7:U38');
var data = range.getValues();
var lastRow = sheet.getRange(sheet.getLastRow()+1,3).setValue(data);
}}
This takes B7 from the original spreadsheet and places it in the next blank row down and in Column C but not B7:U38, if i change setValue(data) to setValues(Data) I get the range height error.
Then below, I got from you and below the script is the error it produces:-
function ImportDataRange() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('AM trip'); //To Sheet Name
var ssraw = SpreadsheetApp.openById('18hAy10EvANHZXLebspZsUbE2fisyEBAFnUYV9JBHs'); // From Spreadsheet ID
var sheetraw = ssraw.getSheetByName('AM trip'); // From Sheet name
var range = sheetraw.getRange('B7:U38');
var data = range.getValues();
var lastRow = sheet.getLastRow()+1;
setValues(sheet, lastRow, 3, data);
The reason for the error is range height should match the height of the data being input.
You will have to modify the code like so
function ImportDataRange() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('AM trip'); //To Sheet Name
var ssraw = SpreadsheetApp.openById('18hAy10EvANHZXLebspZsUbE2fisyEBAFnUYV9JBHs'); // From Spreadsheet ID
var sheetraw = ssraw.getSheetByName('AM trip'); // From Sheet name
var range = sheetraw.getRange('B7:U38');
var data = range.getValues();
var lastRow = sheet.getLastRow()+1;
sheet.getRange(lastRow,3,data.length,data[0].length).setValues(data)
}
Basically, get the length of the data array use array.length gives you number of rows. You find more details on it here
Details on setValues can be found here, similarly details on getRange can be found here
Hope that helps

Copy value and format from a sheet to a new google Spreadsheet document?

I need to copy a sheet on google SpreadSheet to another SpreadSheet document.
I´ve done my research, and I found two methods that do this, however both have problems that I don´t know how to fix.
The first method copies the sheet with format, but it keeps the referenced cells, so I get a reference error in the new document (#ref). I need a function that copies the format and the values (not references).
function copySheet() {
var source = SpreadsheetApp.getActiveSpreadsheet();
var sheet = source.getSheets()[0];
var destination = SpreadsheetApp.openById("15ucPbZrIYXZAOCYVdpK6OA0oyQT1NcsmuiJmDRfdpHQ");
sheet.copyTo(destination);
}
This second method copies the values without references, however it copies only values, without format.
function copySheetValues()
{
var source = SpreadsheetApp.getActiveSheet();
var sourcename = source.getSheetName();
var sourceDataRange = source.getDataRange();
var sourceSheetValues = sourceDataRange.getValues();
var sourceRows = sourceDataRange.getNumRows();
var sourceColumns = sourceDataRange.getNumColumns();
var destination = SpreadsheetApp.openById('15ucPbZrIYXZAOCYVdpK6OA0oyQT1NcsmuiJmDRfdpHQ');
destination.insertSheet(sourcename, 0);
destination.getDataRange().offset(0, 0, sourceRows, sourceColumns).setValues(sourceSheetValues);
}
How do I write a function that keeps the format and copies the values?
Since you seem to know how to get and set values using the whole data range, just use the other methods to get and set all the other parameters.
The script editor autocomplete is a great help in this case to try not to forget one !
I hope the list is complete, it is a bit of a pain to write though !.
code below, if one of them is not useful to you just delete it (in both directions (set and get).
function copySheetValues(){
var source = SpreadsheetApp.getActiveSheet();
var sourcename = source.getSheetName();
var sValues = source.getDataRange().getValues();
var sBG = source.getDataRange().getBackgrounds();
var sFC = source.getDataRange().getFontColors();
var sFF = source.getDataRange().getFontFamilies();
var sFL = source.getDataRange().getFontLines();
var sFFa = source.getDataRange().getFontFamilies();
var sFSz = source.getDataRange().getFontSizes();
var sFSt = source.getDataRange().getFontStyles();
var sFW = source.getDataRange().getFontWeights();
var sHA = source.getDataRange().getHorizontalAlignments();
var sVA = source.getDataRange().getVerticalAlignments();
var sNF = source.getDataRange().getNumberFormats();
var sWR = source.getDataRange().getWraps();
var destination = SpreadsheetApp.openById('15ucPbZrIYXZAOCYVdpK6OA0oyQT1NcsmuiJmDRfdpHQ');
var destinationSheet = destination.insertSheet(sourcename, 0);
destinationSheet.getRange(1,1,sValues.length,sValues[0].length).setValues(sValues)
.setBackgrounds(sBG)
.setFontColors(sFC)
.setFontFamilies(sFF)
.setFontLines(sFL)
.setFontFamilies(sFFa)
.setFontSizes(sFSz)
.setFontStyles(sFSt)
.setFontWeights(sFW)
.setHorizontalAlignments(sHA)
.setVerticalAlignments(sVA)
.setNumberFormats(sNF)
.setWraps(sWR);
}
Edit :
Bryan's answer and your comment made me think of another solution, much more simple and that handles merged cells as well. Here is the code :
function copySheetValuesV2(){
var source = SpreadsheetApp.getActiveSheet();
var sourceName = source.getSheetName();
var sValues = source.getDataRange().getValues();
var destination = SpreadsheetApp.openById('15ucPbZrIYXZAOCYVdpK6OA0oyQT1NcsmuiJmDRfdpHQ');
source.copyTo(destination)
var destinationSheet = destination.getSheetByName('Copy of '+sourceName)
destinationSheet.getRange(1,1,sValues.length,sValues[0].length).setValues(sValues);// overwrite all formulas that the copyTo preserved
}
In both script be sure that the destination sheet name does not already exist. I didn't handle that case although it is quite easy to do with a try/catch structure.
Another route to try that I think Serge was alluding to here.
function myFunction() {
var source = SpreadsheetApp.openById('SOURCE_ID');
var sourceSheet = source.getSheetByName('Sheet1');
var sourceRange = sourceSheet.getDataRange();
var sourceValues = sourceRange.getValues();
var tempSheet = source.getSheetByName('temp');
var tempRange = tempSheet.getRange('A1');
var destination = SpreadsheetApp.openById('DEST_ID');
sourceRange.copyTo(tempRange); // paste all formats?, broken references
tempRange.offset(0, 0, sourceValues.length, sourceValues[0].length)
.setValues(sourceValues); // paste all values (over broken refs)
tempSheet.copyTo(destination); // now copy temp sheet to another ss
}
This is a variation upon Sergei's answer.
This script will copy all visible sheets and export them in to a new spreadsheet with " Final" appended to the document title.
function copySheetValuesV4(){
var sourceSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sourceSheets = sourceSpreadsheet.getSheets();
var destination = SpreadsheetApp.create(sourceSpreadsheet.getName()+' Final');
for (var i = 0; i < sourceSheets.length; i++){
var sourceSheet = sourceSheets[i];
if (!sourceSheet.isSheetHidden()) {
var sourceSheetName = sourceSheet.getSheetName();
var sValues = sourceSheet.getDataRange().getValues();
sourceSheet.copyTo(destination)
var destinationSheet = destination.getSheetByName('Copy of '+sourceSheetName).setName(sourceSheetName);
destinationSheet.getRange(1,1,sValues.length,sValues[0].length).setValues(sValues);// overwrite all formulas that the copyTo preserved */
}
destination.getSheetByName("sheet1").hideSheet() // Remove the default "sheet1" */
}
}

Collect Data from several Spreadsheets and copy it into another sheet

I want to copy data from one spreadsheet into another one. But
1. The Data are on several sheets
2. Only certain Columns (just to speed it up, don't need all columns)
For the beginning I used the following script:
function CopyDataToNewFile() {
var sss = SpreadsheetApp.openById('0AjN7uZG....'); // sss = source spreadsheet
var ss = sss.getSheetByName('Monthly'); // 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('8AjN7u....'); // tss = target spreadsheet
var ts = tss.getSheetByName('RAWData'); // ts = target sheet
//set the target range to the values of the source data
ts.getRange(A1Range).setValues(SData);
}
I took this one from user2741, which was posted here:
..this one works fine for one sheet.
But now I am unsure how to get the data from more sheets and actually sort it. Does anybody has a good idea on how to do this?
Thank you all,
Sascha
This one here works, if everything happens in the same spreadsheet
SpreadsheetApp.getActiveSpreadsheet().getSheetByName("SummarySheet").clear();
mergeSheet2("SummarySheet", "123");
mergeSheet2("SummarySheet", "345");
mergeSheet2("SummarySheet", "748");
mergeSheet2("SummarySheet", "293");
function mergeSheet2(targetSheetName, sourceSheetName) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sourceSheet = ss.getSheetByName(sourceSheetName);
var lastRow = sourceSheet.getLastRow();
var lastCol = sourceSheet.getLastColumn();
var source = sourceSheet.getRange(1,1,lastRow,lastCol); // Error after some iterations: The coordinates or dimensions of the range are invalid. (line 11, file "copy-m.js") -> might be empty spreadsheet
var destSheet = ss.getSheetByName(targetSheetName);
var destRange = destSheet.getRange(destSheet.getLastRow()+1,1);
source.copyTo(destRange, {contentsOnly: true});
}
but for some reason I don't get it run when using different spreadsheets
Error: "Target range and source range must be on the same spreadsheet"
I tried it with:
SpreadsheetApp.getActiveSpreadsheet().getSheetByName("SummarySheet").clear();
SpreadsheetApp.openById('ID');
mergeSheet2("SummarySheet", "123");
function mergeSheet2(targetSheetName, sourceSheetName) {
var ss = SpreadsheetApp.openById('ID');
var ssd = SpreadsheetApp.openById('ID');
var sourceSheet = ss.getSheetByName(sourceSheetName);
var lastRow = sourceSheet.getLastRow();
var lastCol = sourceSheet.getLastColumn();
var source = sourceSheet.getRange(1,1,lastRow,lastCol); // Error after some iterations: The coordinates or dimensions of the range are invalid. (line 11, file "copy-m.js") -> might be empty spreadsheet
var destSheet = ssd.getSheetByName(targetSheetName);
var destRange = destSheet.getRange(destSheet.getLastRow()+1,1);
source.copyTo(destRange, {contentsOnly: true});
Any ideas?
The solution is simpler than what you tried, since you want to copy values only and knowing that copyTo only works in the same spreadsheet, just get the values from source and paste it in destination like this:
function copyFromSourceToTarget(targetSheetName, sourceSheetName) {
var ss = SpreadsheetApp.openById('ID');
var ssd = SpreadsheetApp.openById('ID');
var sourceSheet = ss.getSheetByName(sourceSheetName);
var sourceData = sourceSheet.getDataRange().getValues();
var destSheet = ssd.getSheetByName(targetSheetName);
destSheet.getRange(destSheet.getLastRow()+1,1,sourceData.length,sourceData[0].length).setValues(sourceData);
}
To make it more flexible I'd recommend to use 4 parameters and simplify again the code :
function copyFromSourceToTarget(targetSheetName,targetSsId, sourceSheetName,sourceSsId) {
var ss = SpreadsheetApp.openById(sourceSsId)getSheetByName(sourceSheetName);
var ssd = SpreadsheetApp.openById(targetSsId).getSheetByName(targetSheetName);
var sourceData = ss.getDataRange().getValues();
ssd.getRange(ssd.getLastRow()+1,1,sourceData.length,sourceData[0].length).setValues(sourceData);
}