I have a range issue with a script - google-apps-script

I want to create a button that moves a given number of cells from one sheet into another sheet. The starting range cell is always the same (A9) and there will be always 8 columns in total. The final row will depend on how many rows the user completes. How can I indicate this behaviour in my range code?
I think this needs to be instructed in range field, but couldn't obtain what I need.
function finishReport() {
var ss = SpreadsheetApp.getActiveSpreadsheet()
sheet = ss.getActiveSheet(),
sheetName = sheet.getName(),
data = sheet.getDataRange().getValues();
if (sheetName == "Main") {
var range = sheet.getActiveRange(),
startRow = range.getRowIndex(),
numRows = range.getNumRows(),
numCols = range.getNumColumns()
if (numCols == 8 {
if (data.length > 1) {
var values = range.getValues(),
nextSheet = ss.getSheetByName("History record")
lastRow = nextSheet.getLastRow();
nextSheet.getRange(lastRow+1,1,numRows,8).setValues(values);
sheet.deleteRows(startRow,numRows);
}
}
}
}
I expect that all rows entered by user in tab Main are moved to tab History record. Any thoughts?

Query
You want to copy a range starting at cell A9 and stretching over 8 columns until the last row containing contents
Problem
You are using getActiveRange() which returns you only the selected (=highlighted) range - if no range is highlighted in the sheet, only the active cell will be returned as a range
Solution
Select the range manually by retrieving the last content containing row and column with
mainLastRow = sheet.getLastRow();
mainLastColumn = sheet.getLastColumn();
and defining
var numRows = mainLastRow-startRow+1;
var numCols = mainLastColumn-startColumn+1;
Full Code
function finishReport() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
sheet = ss.getActiveSheet();
sheetName = sheet.getName();
if (sheetName == "Main") {
var startRow = 9;
var startColumn=1;
var mainLastRow = sheet.getLastRow();
var mainLastColumn = sheet.getLastColumn();
var numRows = mainLastRow-startRow+1;
var numCols = mainLastColumn-startColumn+1;
var range = sheet.getRange(startRow,startColumn,numRows,numCols);
Logger.log(numRows);
Logger.log(numCols);
Logger.log(mainLastRow);
Logger.log(mainLastColumn);
if (numCols == 8) {
if (numRows >= 1) {
var values = range.getValues();
nextSheet = ss.getSheetByName("History record");
lastRow = nextSheet.getLastRow();
nextSheet.getRange(lastRow+1,1,numRows,8).setValues(values);
sheet.deleteRows(startRow,numRows);
}
}
}
}
Annotation
You could also retrieve the range with getDataRange(), but you would have to correct manually for the fact that dataRange starts by definition in cell A1.

I hope this works for you.
function onOpen(e) {
// Add a custom menu to the spreadsheet.
SpreadsheetApp.getUi()
.createMenu('Report')
.addItem('Finish', 'FinishReport')
.addToUi();
}
function FinishReport(){
var sp = SpreadsheetApp.getActiveSpreadsheet();
var sh = sp.getActiveSheet();
var as =sp.getSheetByName('Main').activate();
var MainRange = sp.getRange('A9:H9').activate();
var MainLastRow = sp.getLastRow();
var selection = sp.getRange('A9:H' + MainLastRow).activate();
sp.getCurrentCell().activateAsCurrentCell();
sp.setActiveSheet(sp.getSheetByName('History record'), true);
var lastRow = sp.getLastRow();
var newRow = lastRow+1;
sp.getRange('A'+newRow+':H'+newRow).activate();
sp.getCurrentCell().activateAsCurrentCell();
sp.getRange('Main!' + selection.getA1Notation()).moveTo(sp.getActiveRange());
}
REFERENCE
Spreadsheet Custom Menu
Apps Script, SpreadsheetApp

Related

TypeError: lastrow.setValues is not a function

I'm trying to copy past a particular range to another spreadsheet serving as a database. The goal is to copy past values that are in the range(a43:n54), to the last row of the database page, then to clear the range (d11:n22) of the source sheet.
I've already used part of code I saw on another thread (the get/set values part). But here when I run the function, it says that line 35 "lastrow.setValues(values) is not a function". I know it means my function is not valid and most likely it will do the same with all the setValues section...
function myfunction()
{
// spreadsheet identification
const sourcesheet = SpreadsheetApp.getActiveSpreadsheet();
const destination = SpreadsheetApp.openByUrl("page_url")
// identification of the ranges to copy and to delete
const ws = sourcesheet.getSheetByName ("Récap");
const source_range_to_delete = ws.getRange("d11:n22");
const source_range_to_copy = ws.getRange("a43:n54");
// get last row of target spread sheet
const destpage = destination.getSheetByName("Feuille 1");
var destrange =destpage.getRange("A1:n").getValues();
var lrIndex;
for( var i = destrange.length-1;i>=0;i--){
lrIndex = i;
if(!destrange[i].every(function(c){ return c == "";})) {
break;
}
}
var lastrow =lrIndex +1;
//get values
var values = source_range_to_copy.getValues()
var bGcolors = source_range_to_copy.getBackgrounds();
var colors = source_range_to_copy.getFontColors();
var fontSizes = source_range_to_copy.getFontSizes();
// set values
lastrow.setValues(values);
lastrow.setBackgrounds(bGcolors);
lastrow.setFontColors(colors);
lastrow.setFontSizes(fontSizes);
source_range_to_delete.clearContent({contentsOnly:true});
}
function myfunction() {
// spreadsheet identification
const sourcesheet = SpreadsheetApp.getActiveSpreadsheet();
const destination = SpreadsheetApp.openByUrl("page_url");
// identification of the ranges to copy and to delete
const ws = sourcesheet.getSheetByName("Récap");
const source_range_to_delete = ws.getRange("d11:n22");
const source_range_to_copy = ws.getRange("a43:n54");
// get last row of target spread sheet
const destpage = sourcesheet.getSheetByName("Feuille 1");
var data = sourcesheet.getRange("a1:n").getValues();
for (var lastrow = data.length-1; lastrow >= 0; lastrow--) {
if (data[lastrow].some(c => c != "")) break;
}
//get values
var values = source_range_to_copy.getValues();
var bGcolors = source_range_to_copy.getBackgrounds();
var colors = source_range_to_copy.getFontColors();
var fontSizes = source_range_to_copy.getFontSizes();
// set range right after the last row on destination sheet
var destrange = destpage.getRange(lastrow + 2,1,values.length,values[0].length);
// set values of destination range
destrange.setValues(values);
destrange.setBackgrounds(bGcolors);
destrange.setFontColors(colors);
destrange.setFontSizes(fontSizes);
source_range_to_delete.clearContent();
}
setValues() is a method of class Range. lastrow is an integer.

Google sheets script for copying data and pasting in another sheet on the same row as a specific numer

I have the following data:
[Source] Sheet 1 (Quote Generator):
Sheet 1, Cell A4: Dropdown menu to select a job reference
Sheet 1, Cells K4>Q4:= figures pulled from google maps & calculations dependant on A4 menu selection
[Destination] Sheet 2 (Quote Log):
Sheet 2, Column B: Quote References
Sheet 2, Columns V>AB: Travel data and calculations from sheet 1
I'm after a script that will copy the data in Sheet 1, Cells K4:Q4, and paste them in to Sheet 2, Columns V:AB on the same row as the selected job ref '100001' on Sheet 1, Cell A4, which will also be present in Sheet 2, Column B
Any help would be greatly appreciated
TIA
The data range you have specified is large than the range you want to put data in hence I have reduced the source range in the code. Try this.
function copyrow() {
var ss = SpreadsheetApp.getActive();
var source = SpreadsheetApp.openById('SheetID');
var dest = SpreadsheetApp.openById('SheetID');
var sourcerange = source.getRange('B4:H4');
var sourcerangevalue = sourcerange.getValues();
var checkval = source.getRange('A4').getValue();
var lastrow = dest.getLastRow();
var destrange = dest.getRange('B1:B');
var destrangevalue = destrange.getValues();
for (i = 1; i <= lastrow; i++) {
if (checkval == destrangevalue[i]) {
dest.getRange('A15').setValue(destrangevalue[i])
dest.getRange("V" + i + ":AB" + i).setValues(sourcerangevalue)
};
};
};
function myFunction() {
// get active spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
// get data from Sheet1
var s = ss.getSheetByName("Sheet1");
var cel = s.getRange("A4").getValue();
var data = s.getRange("K4:Q4").getValues();
// get to Sheet2 and get values from column 'B'
var s = ss.getSheetByName("Sheet2");
var col = s.getRange("B1:B").getValues();
// find the row number in columnn B that contain the value
var row = col.flat().findIndex( c => c == cel ) + 1;
// put the 'data' into the cells of this row
if (row) s.getRange("V" + row + ":AB" + row).setValues(data);
}
Updated version:
function onEdit(e) {
if (e.range.getA1Notation() !== "Q6") return;
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getSheetByName("Sheet1");
var cel = s.getRange("A4").getValue();
var data = s.getRange("K4:Q4").getValues();
var s = ss.getSheetByName("Sheet2");
var col = s.getRange("B1:B").getValues();
var row = col.findIndex(c => c[0] == cel) + 1;
if (!row) return;
s.getRange("V" + row + ":AB" + row).setValues(data);
var s = ss.getSheetByName("Sheet1");
ss.getRange("A1").clear();
ss.getRange("F5").clear();
}

Is there any function to make right align for numbers through out the Spreadsheet in app-script

Does a function exist to right align numbers throughout a spreadsheet in Google Apps Script?
var lastRow = sheetName.getDataRange().getLastRow();
var lastCol = sheetName.getDataRange().getLastColumn();
sheetName.getRange(1,1,lastRow,lastCol).setFontSize(12).setHorizontalAlignment("left").setFontFamily("Calibri");
Here's a quick solution I just tried on a test Google spreadsheet.
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var range = sheet.getDataRange();
var values = range.getValues();
var lastRow = range.getLastRow();
var lastColumn = range.getLastColumn();
for ( rowIndex = 0; rowIndex < lastRow; rowIndex++ ) {
for ( colIndex = 0; colIndex < lastColumn; colIndex++ ) {
var val = (values[rowIndex][colIndex]);
console.log(val);
if (!isNaN(parseFloat(val))) {
sheet.getRange(rowIndex+1, colIndex+1).setHorizontalAlignment('right');
}
}
}
}
Basically, the process is this:
Get all the data values on the sheet.
Iterate through all the data now stored in the values variable
For each value (variable val), Check if it is a numeric value and if it is numeric, set the horizontal alignment to the right.

Expand formulas when copying

The script copy-pastes all formulars one column to the right but The formula has to expand to the right too.
Example: A1+A3 -> B1+B3
right now the formula just gets duplicated when running the sript
function copyFormulas() {
var activeSheet,numberOfSourceColumnsToGet,sourceColumnStart,sourceFormulas,sourceRange,
sourceRowStart,targetColumn,targetRange,targetRowStart;
//USER INPUT
sourceRowStart = 1; //Row to start getting formulas from
sourceColumnStart = 4; //Column to start getting formulas from
numberOfSourceColumnsToGet = 1; //Number of columns to get formulas from
targetRowStart = 1; //Row to start copying formulas to
targetColumn = 5; //Column to start copying formulas to
//END OF USER INPUT
activeSheet = SpreadsheetApp.getActiveSheet();
sourceRange = activeSheet.getRange(sourceRowStart, sourceColumnStart, activeSheet.getLastRow(), numberOfSourceColumnsToGet);
sourceFormulas = sourceRange.getFormulas();//Get only formulas from the source range
targetRange = activeSheet.getRange(targetRowStart,targetColumn,sourceFormulas.length,sourceFormulas[0].length);
targetRange.setFormulas(sourceFormulas);//Copy the formulas to the target range
}
As #АлександрЕрмолин says, you are using the wrong command. Try this:
function so5657743702() {
var ss = SpreadsheetApp.getActiveSpreadsheet()
var sheetname = "56577437";
var sheet = ss.getSheetByName(sheetname);
var sourcerange = sheet.getRange("A4");
var targetrange = sheet.getRange("B4");
sourcerange.copyTo(targetrange, SpreadsheetApp.CopyPasteType.PASTE_FORMULA, false);
}

How to get and set column number based on value in source spreadsheet

Trying to copy a range (L2:L9) to another spreadsheet based on a data validation selection (ID #) in a specific cell (G11) on the source spreadsheet.
The ID#s are all in alphanumeric order on the target spreadsheet along row 5, so all I need is to get the column number that corresponds to the choice made in the data validation field.
Before I had to convert the ID#s to Alphanumeric values, I simply had numeric values and the script worked fine. Now I'm having trouble converting the script to work with this modification.
function Submit() {
var ss = SpreadsheetApp.getActiveSpreadsheet(); // ss = source spreadsheet
var source_sheet = ss.getActiveSheet();
if (source_sheet.getName() == "Pre-Season CC") {
var SRange = source_sheet.getRange('L2:L9');
var A1Range = SRange.getA1Notation();
var SData = SRange.getValues();
var target = SpreadsheetApp.openById('1MpKdxFyBrVQT3EumePQvtCZpgzcDW5xlYe4B1DKZCA8');
var target_sheet = target.getSheetByName('Pre-Season');
var idNumber = source_sheet.getRange('Pre-Season CC!G11').getValue();
for (var i = 0; i < idNumber.length; i++) {
for (var j = 0; j < idNumber.length;j++){
if (target_sheet[4][j] == idNumber){
Logger.log((j+1))
return j+1;
target_sheet.getRange('B6:B13').offset(0,valueA1 = ss.getRange('Pre-Season!G11').getValue(idNumber)+1).setValues(SData);
}
}
}
}
At that point, I need the data copied from source spreadsheet onto the target spreadsheet in it's designated column, according to the ID#. Please help!
Try below code.
function Submit() {
var ss = SpreadsheetApp.getActiveSpreadsheet(); // ss = source spreadsheet
var source_sheet = ss.getActiveSheet();
if (source_sheet.getName() == 'Pre-Season CC') {
// source sheet items
var SData = source_sheet.getRange('L2:L9').getValues();
var idNumber = source_sheet.getRange('Pre-Season CC!G11').getValue();
// target sheet items
var targetSS = SpreadsheetApp.openById('1MpKdxFyBrVQT3EumePQvtCZpgzcDW5xlYe4B1DKZCA8');
var target_sheet = targetSS.getSheetByName('Pre-Season');
// 5 = row where IDs are
var TData = target_sheet.getRange(5, 1, 1, target_sheet.getLastColumn()).getValues()[0];
// column index of #ID in target sheet
var colIndex = TData.indexOf(idNumber) + 1;
// write data in that column, rows from 6 to 13
target_sheet.getRange(6, colIndex, SData.length, 1).setValues(SData);
}
}