Expand formulas when copying - google-apps-script

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

Related

Copying data from a sheet to another with conditions

I have been trying to copy some data from a sheet to another but I have been running into some trouble.
I have to copy data and stop copying until the scripts finds an empty space, and I have to paste this data into another sheet where there's blank space (available space).
This is the code I have so far:
function copyInfo() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var copySheet = ss.getSheetByName("sheet1");
var pasteSheet = ss.getSheetByName("sheet2");
var source = copySheet.getRange(11,1,1,10);
var destination = pasteSheet.getRange(1,1,1,10);
for (i = 1; i < 20; i++) {
if (destination.isBlank() == true) {
destination = pasteSheet.getRange(i, 1, 1, 10);
source = copySheet.getRange(i + 10, 1, 1, 10);
source.copyTo(destination);
} else {
destination = pasteSheet.getRange(i, 1, 1, 10);
}
}
}
It recognizes that the destination has an empty space, although it doesn't really paste it. The for (i = 1; i <20; i++) is for testing purposes.
If your data doesn't have any blank rows in between the first row and last non-empty row, then you can use this:
Sample Data:
sheet1
sheet2
Script:
function copyInfo() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var copySheet = ss.getSheetByName("sheet1");
var pasteSheet = ss.getSheetByName("sheet2");
// get last rows of each sheet
var sLastRow = copySheet.getLastRow();
var dLastRow = pasteSheet.getLastRow();
// get data from sheet1 from row 11 to last row
var source = copySheet.getRange(11,1,sLastRow - 10,10).getValues();
// paste data to sheet2's last row
pasteSheet.getRange(dLastRow + 1,1,source.length,source[0].length).setValues(source);
}
Output:
Alternative:
If you have blank rows in between your sheet1, you can filter the values in sheet1.
Sample Data:
blank row 13 in sheet1
function copyInfo() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var copySheet = ss.getSheetByName("sheet1");
var pasteSheet = ss.getSheetByName("sheet2");
// get last rows of each sheet
var sLastRow = copySheet.getLastRow();
var dLastRow = pasteSheet.getLastRow();
// get data from sheet1 from row 11 to last row
// exclude rows with blank values in all columns
var source = copySheet.getRange(11,1,sLastRow - 10,10).getValues()
.filter(row => row.filter(col => !col).length < row.length);
// paste data to sheet2's first blank row
pasteSheet.getRange(dLastRow + 1,1,source.length,source[0].length).setValues(source);
}
Output:

How to delete rows that do not containing specific text within A column using Google Sheets App?

I'm new to Google Apps Scripts so I am sorry if my question is redundant.
I am working on a variant of the scripts here:
Google Sheets: delete rows containing specified data
(Here is the script that I have been editing -- note the empty IF value.)
function onOpen(){
}
function deleteFunction(){
var sheetName = "Title";
var ss = SpreadsheetApp.getActive();
var sheet = ss.getSheetByName(sheetName);
var dataRange = sheet.getDataRange();
var numRows = dataRange.getNumRows();
var values = dataRange.getValues();
var rowsDeleted = 0;
for (var i = 2; i <= numRows; i++){
var rowValues = values[i-1].toString();
if (rowValues == ""){
sheet.deleteRow(i - rowsDeleted);
rowsDeleted++;
}
I would like to delete rows in a sheet named "Title" that do not contain "| My Text Here". The text is found in a string of text, such as "Here is the string of text that could be random | My Text Here". So if "| My Text Here" is not found in a cell, I want that whole row to be deleted.
The data set I want this to work with will have ~10,000 rows and I want this script to either run when the sheet is opened or once a day.
I have tried to make this work, but I think I'm on the wrong track and so would really apprecaite the communities help!
I can attach a test sheet if needed.
Thank you in advance for your help and guidance
New script:
function main() {
var SS = SpreadsheetApp.getActive();
var SHEET = SS.getSheetByName("Title");
var RANGE = SHEET.getDataRange();
var DELETE_VAL = "| TEST TEXT HERE";
var COL_TO_SEARCH = 0; //Zero is first
var deleteSelectedRows = removeThenSetNewVals();
};
function removeThenSetNewVals(){
var SS = SpreadsheetApp.getActive();
var SHEET = SS.getSheetByName("Title");
var RANGE = SHEET.getDataRange();
var rangeVals = RANGE.getValues();
var DELETE_VAL = "| TEST TEXT HERE";
var COL_TO_SEARCH = 0; //Zero is first
var newRangeVals = [];
for(var i = 0; i < rangeVals.length; i++){
if(rangeVals[i][COL_TO_SEARCH] == DELETE_VAL){
newRangeVals.push(rangeVals[i]);
};
};
RANGE.clearContent();
var newRange =
SHEET.getRange(1,1,newRangeVals.length, newRangeVals[0].length);
newRange.setValues(newRangeVals);
};
}
Your code needs the following modification to work in the way you desire
Use indexOf(). This is a Javascript method that allows you to verify either a sub-string is contained in a string. In your case, it allows you to verify either "| My Text Here" is contained in your cells in column A.
Loop "backwards" from the end row to the start row. Why? Because otherwise the deletion of rows will mess up the row indices of the remaining rows.
function deleteFunction(){
//declarations
var sheetName = "Title";
var ss = SpreadsheetApp.getActive();
var sheet = ss.getSheetByName(sheetName);
var dataRange = sheet.getDataRange();
var values = dataRange.getValues();
for(var i=values.length-1;i>0;i--){
var myValue=values[i][0];
Logger.log(i);
if( myValue.indexOf("| My Text Here")==-1){
Logger.log(myValue);
sheet.deleteRow(i+1);
}
}
}

I have a range issue with a 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

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

Google Sheet Script to Insert new row after column C

I am working on a script to automatically add a new row after column C on a daily basis. Below is my script:
function recordHistory() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("test");
var source = sheet.getRange("c4:U4");
var values = source.getValues();
sheet.insertRowBefore(4);
sheet.getRange("c5:U5").setValues(values);
};
Column A in the "test" sheet is a range imported from another sheet. The code above adds a new row then copies the range C-U to row 5.
But I what I want is to add a row from column C only.
however coz the requirement change i just copy over the the whole line with format instead of value
function addFirstRow() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var firstRow = 3;
var sh = ss.getSheetByName("daily");
var lCol = sh.getLastColumn();
var range = sh.getRange("A4:U4");
var formulas = range.getFormulas();
sh.insertRowsAfter(3,1);
newRange = sh.getRange("A4:U4");
newRange.setFormulas(formulas);
}