Script issue with an array reference - google-apps-script

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

Related

Copy dynamic range from one sheet to another

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

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

Trying to copy a column range on on sheet and paste it in a row on a different sheet and have it inserted to top with each time the script runs

I am trying to copy a column range on on sheet and paste it in a row on a different sheet. I want it inserted to the top each time the script runs. This is what I got so far:
function Copy() {
var sss = SpreadsheetApp.openById('1UbcIcGJRVxsX9WbzunS96Ijf8c2gRc8UYb40lHpWWQU'); //source ID
var ss = sss.getSheetByName('Container Input'); //source Sheet tab name
var range = ss.getRange('B4:B23'); //assigned range to copy
var data = range.getValues();
var tss = SpreadsheetApp.openById('1UbcIcGJRVxsX9WbzunS96Ijf8c2gRc8UYb40lHpWWQU'); //destination ID
var ts = tss.getSheetByName('Container Log'); //destination sheet tab name
ts.getRange(1, 1, data.length, data[0].length).setValues(data); //you will need to define the size of the copied data see getRange()
//range.clearContent(); //clears var range
}
function Copy()
{
var sss = SpreadsheetApp.openById('1UbcIcGJRVxsX9WbzunS96Ijf8c2gRc8UYb40lHpWWQU');
//source ID
var ss = sss.getSheetByName('Container Input'); //source Sheet tab name
var ts = sss.getSheetByName('Cylinder Tracking'); //destination sheet tab name
//var protection = ts.protect();
//protection.setUnprotectedRanges(2,1,1,21);
ts.insertRowsBefore(2, 1);// Adds a new row before row 2 - Keeps the formatting of the
old row 2 for the new row 2
var source_C = 2;
var source_R = 3;
var dest_C = 2;
var dest_R = 2;
SpreadsheetApp.getActive().getRange('Cylinder Tracking!A2').setValue(new Date())
for (var counter = 1; counter <= 20; counter++)
{
var source_range = ss.getRange(source_R,source_C); //assigned range to copy
var data = source_range.getValues();
var dest_range = ss.getRange(dest_C,dest_R);
ts.getRange(dest_R, dest_C).setValues(data); //you will need to define the size of the
copied data see getRange()
source_R++;
dest_C++;
}
}

Multiple sheet copying from a working sheet to an archive sheet

I have had some help with the last line of this code and it works perfectly for a single sheet in the spreadsheet, however I have 5 sheets in the From spreadsheet and identical 5 sheets in the target spreadsheet how can I get the same range in the other 4 sheets to their same named counterpart in the target sheet? So I used below to try and copy each sheet to its corresponding namesake but I have set up the code as below but only importing the first sheet, also is there a way to only need to enter the originating spreadsheet id once for the whole code instead of at each sheet section?
function ImportDataRange() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('AM trip'); //To Sheet Name
var ssraw = SpreadsheetApp.openById('1Z0zU2oGktLPB-QitYMm9XtOGN4Rd-Z-UJJomGX4NIO0'); // 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)
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('PM trip'); //To Sheet Name
var ssraw = SpreadsheetApp.openById('1Z0zU2oGktLPB-QitYMm9XtOGN4Rd-Z-UJJomGX4NIO0'); // From Spreadsheet ID
var sheetraw = ssraw.getSheetByName('PM 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)
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Pool / Beach'); //To Sheet Name
var ssraw = SpreadsheetApp.openById('1Z0zU2oGktLPB-QitYMm9XtOGN4Rd-Z-UJJomGX4NIO0'); // From Spreadsheet ID
var sheetraw = ssraw.getSheetByName('Pool / Beach'); // 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)
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Night Dive'); //To Sheet Name
var ssraw = SpreadsheetApp.openById('1Z0zU2oGktLPB-QitYMm9XtOGN4Rd-Z-UJJomGX4NIO0'); // From Spreadsheet ID
var sheetraw = ssraw.getSheetByName('Night Dive'); // 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)
}
Thank you for any help. Much appreciated.
The code can be simplified using a loop.
You said above that you have 5 sheets but you only have 4 in the code sample, add the other sheet name to var sheetNames.
function onOpen() { // This function adds a custom menu to the spreadsheet (Backup to archive) so you can run the script from there.
var ui = SpreadsheetApp.getUi();
ui.createMenu('Backup to archive')
.addItem('Backup', 'dataBackup')
.addToUi();
}
function dataBackup() {
var inputSS = SpreadsheetApp.openById('1wglM4-5jx873vwtFRPVgC1qk27JjrsYjDwp0fNpl5Xg'); // The file ID of the Input sheet
var archiveSS = SpreadsheetApp.openById('146WU8RghfFqlCpCSX7n6kBAKOyxcpVKt14yhVfvYz-g'); // The file ID of the archive sheet
// The names of the sheets to be copied.
// NOTE: These names must match the names of the sheets in BOTH spreadsheets i.e. the same case the spelling and the same spaces.
var sheetNames = ['AM trip', 'PM trip', 'Pool / Beach', 'Night Dive'];
for (var i = 0; i < sheetNames.length; i++) { // Loop to each sheet listed in 'var sheetNames' and copy the data.
var inputSheet = inputSS.getSheetByName(sheetNames[i]);
var archiveSheet = archiveSS.getSheetByName(sheetNames[i]);
var data = inputSheet.getRange('B7:U38').getValues();
archiveSheet.getRange(archiveSheet.getLastRow() + 1, 2, data.length, data[0].length).setValues(data);
}
}

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