Archive rows to a separate sheet - google sheets - google-apps-script

I have a script for archiving rows into one tab to another tab based on cell edit within the same spreadsheet. However the size of the sheet is getting very large resulting in slow page load. I was just wondering, as I'm not too experienced in scripts, if it were to possible to "archive" rows into a completely separate google sheet (new URL).
Note: At the moment, if you change Column 6 cell value to "Archive" it sends from one sheet ("Content Production Master") to another sheet ("Content Archive").
See code below for what I've got at the moment - any help would be very useful!
// assumes source data in sheet named Content Production Master
// target sheet of move to named Content Archive
// test column with "Archive" is col6
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "Content Production Master" && r.getColumn() == 6 && r.getValue() == "Archive") {
var row = r.getRow();
var lastRow = r.getLastRow(); //Save the last edited row index
var numColumns = s.getLastColumn();
var numRows = lastRow-row + 1; // Corrected this calculation
var targetSheet = ss.getSheetByName("Content Archive");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
//s.getRange(row, 1, 1, numColumns).moveTo(target);
s.getRange(row, 1, numRows, numColumns).moveTo(target); // Take in account the lastRow when archiving the edited range.
//s.deleteRow(row);
for (let i = row; i<=lastRow; i++) {
s.deleteRow(row);
console.log(`Deleted row ${row} at pass number ${i}`);
}
}
}

Since it is not possible to move data from your source sheet to a different spreadsheet using move(target). You can manually get the data to be moved and paste that to another spreadsheet using getValues() and setValues(values).
Sample Code:
function onEdit(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getActiveSheet();
var r = ss.getActiveRange();
if(s.getName() == "Content Production Master" && r.getColumn() == 6 && r.getValue() == "Archive") {
//var targetSs = SpreadsheetApp.openById('1xh0huhm7ghGP7Y_5jNSFh7eaNX4iVoOL4SY95IWqpfs');
var targetSs = SpreadsheetApp.openByUrl('https://docs.google.com/spreadsheets/d/1xh0huhm7ghGP7Y_5jNSFh7eaNX4iVoOL4SY95IWqpfs/edit?resourcekey=0-j6u0gdSEBp-F9SZYlZYi1g#gid=93990300');
var targetSheet = targetSs.getSheetByName("Content Archive");
var row = r.getRow();
var lastRow = r.getLastRow(); //Save the last edited row index
var numColumns = s.getLastColumn();
var numRows = lastRow-row + 1; // Corrected this calculation
//Get data to be moved
var data = s.getRange(row, 1, numRows, numColumns).getValues();
//Paste the values to the target sheet on another spreadsheet
targetSheet.getRange(targetSheet.getLastRow()+1,1,data.length,data[0].length).setValues(data);
//Delete data in the source sheet
s.deleteRows(row, numRows);
}
}
Pre-requisite(use installable onEdit trigger):
What it does?
After checking if the modified cell is in column 6 with value "Archive". Open the target spreadsheet using either openByUrl(url) or openById(id). Then select the target sheet.
Get the row values of the range to be moved using getValues()
Write the values to your target sheet using setValues(values)
Delete the archived rows in your source sheet using deleteRows(rowPosition, howMany)
Output:
Source Sheet (Before)
Source Sheet (After)
Target Sheet (After)

Related

Google Script - creating an archive if one row says "closed"

I borrowed the code from here: Archive rows to a separate sheet - google sheets
but basically I am trying to create an automatic archive where the rows of info delete from my master list on the source sheet but ONLY when I change column C to "Closed".
please help
Here is my code:
function onEdit() {
var ss = SpreadsheetApp.openByUrl('source sheet link');
//Logger.log(ss.getName());
var s = ss.getActiveSheet();
var r = ss.getActiveRange();
if(s.getName() == "Master List" && r.getColumn() == 3 && r.getValue() == "Closed");{
var targetSs = SpreadsheetApp.openByUrl('target sheet link');
//Logger.log(targetSs.getName());
var targetSheet = targetSs.getSheetByName("Archive");
var row = r.getRow();
var lastRow = r.getLastRow(); //save the last edited row index
var numColumns = s.getLastColumn();
var numRows = lastRow-row+2;
//Get data to be moved
var data = s.getRange(row, 1, numRows, numColumns).getValues();
//Paste the values to the target sheet on another spreadsheet
targetSheet.getRange(targetSheet.getLastRow()+1,1,data.length,data[0].length).setValues(data);
//Delete data in the source sheet
s.deleteRows(row, numRows);
}
}

Google Script - Unable to copy from one sheet to another

This is my first Google Script and I am coming from a VBA background so I have likely missed something obvious. I am attempting to copy from one sheet to another, some that is quite simple in VBA, but I am struggling with it and I dont understand what I am missing
The below code I would have though would copy a range in one sheet to another sheet. Not the whole range, just a section of it and only 1 row per an OnEdit()
I checked the ranges I am wanting to copy from and copy to using targetSheet.getRange(targetSheet.get1stNonEmptyRowFromBottom(1) + 1, 1,1,numColumns-1).activate(); & sheet.getRange(row, 1, 1, numColumns-1).activate(); and it selects the range I would expect
Currently the execution doesn't show any fails either
function onEdit(e) {
//This is sheet we will be copied to
const VALUE = ["LEAD","LANDSCAPE"];
//This is the column for the check box
const COLUMN_NUMBER = 25
//The main sheet that is being copied from
const MAIN_SHEET = 'Form Responses 1'
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getActiveSheet();
var cell = sheet.getActiveCell();
var row = cell.getRow();
var lead_or_landscape = sheet.getRange(row,20).getValue();
//This is so we dont run this by mistake on another cell edit or sheet
if((COLUMN_NUMBER == cell.getColumn() && MAIN_SHEET == sheet.getName && cell.isChecked() == true)
&& (lead_or_landscape == VALUE[0] || lead_or_landscape == VALUE[1])){
//copies row from current sheet to the specificed sheet (Lead or landscape)
var numColumns = sheet.getLastColumn();
var targetSheet = spreadsheet.getSheetByName(lead_or_landscape);
var target = targetSheet.getRange(targetSheet.get1stNonEmptyRowFromBottom(1) + 1, 1,1,numColumns-1);
sheet.getRange(row, 1, 1, numColumns-1).copyTo(target());
}
}
Object.prototype.get1stNonEmptyRowFromBottom = function (columnNumber, offsetRow = 1) {
const search = this.getRange(offsetRow, columnNumber, this.getMaxRows()).createTextFinder(".").useRegularExpression(true).findPrevious();
return search ? search.getRow() : offsetRow;
};
You've to use parentheses in sheet.getName() and not use them in copyTo(target())
And you can use sheet.appendRow() method instead of copyTo(), that is easier.
function onEdit(e) {
//This is sheet we will be copied to
const sheets = ["LEAD","LANDSCAPE"];
//This is the column for the check box
const colNumber = 25;
//The main sheet that is being copied from
const mainSheet = 'Form Responses 1';
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getActiveSheet();
var cell = sheet.getActiveCell();
var row = cell.getRow();
var leadOrLandscape = sheet.getRange(row,20).getValue();
//This is so we dont run this by mistake on another cell edit or sheet
if(colNumber == cell.getColumn()
&& mainSheet == sheet.getName()
&& cell.isChecked() == true
&& sheets.includes(leadOrLandscape)){
//copies row from current sheet to the specificed sheet (Lead or landscape)
var numColumns = sheet.getLastColumn();
var targetSheet = spreadsheet.getSheetByName(leadOrLandscape);
targetSheet.appendRow(sheet.getRange(row, 1, 1, numColumns-1).getValues()[0])
}
}
I just took a quick look at your code, are you sure about this line?
sheet.getRange(row, 1, 1, numColumns-1).copyTo(target());
it shouldn't rather be
sheet.getRange(row, 1, 1, numColumns-1).copyTo(target);

script to copy a row of data from one sheet to a specific sheet based on the value of a cell

I'm trying to create a script to copy a row of data from one sheet to a another sheet based on the value of a cell.
But essentially when a new row of information is input in the main sheet it'll copy the row and place that row of data into a another sheet based off the value of a specific cell. In this case it's the utility company.
If, for example, the customer is created and the utility company they have is United Power I want to have the sheet copy that customers information over and add it to the specified United Power sheet and so on and so forth with the other utility company's (3 total)
I keep getting the below error:
TypeError: Cannot read property 'source' of undefined (line 4, file "Code")
I'll paste below what I have so far. (I only have the code for one so far)
I can also link the spreadsheet if need be.
function onEdit(event) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "Contracts" && r.getColumn() == S && r.getValue() == "United Power") {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("United Power");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
}
}
You could have written like this:
You need to change S to a number
function onEdit(e) {
const sh=e.range.getSheet();
if(sh.getName()=="Contracts" && e.range.columnStart==19 && e.value=="United Power") {
const tsh = e.source.getSheetByName("United Power");
const target = tsh.getRange(tsh.getLastRow() + 1, 1);
sh.getRange(e.range.rowStart,1,1,sh.getLastColumn()).moveTo(target);
}
}

Google sheets move row depending on value AND edit values

I've been reading answers on Stack for ages and finally decided to join! So here is my first question:
I found a google apps script here for google sheets that moves a row to another sheet depending on a cell value. This is great. I have tested it and it is working for me with a couple of alterations - first to use a checkbox, and second to copy all columns excluding the 1st column with the checkbox.
However, for it to be really useful to me, what I'd like is to be able to edit a couple of values before adding the row to the new sheet.
So it would be like this:
if Checkbox = true, then copy row, all columns excluding checkbox
Set value of 'location' to 'London' (column 8 for example)
Set value of 'date' to today (column 12 for example)
Add edited row to new sheet at the bottom
Can anyone help me to achieve this? I'm guessing it must be quite simple but I am new to apps script so don't know how I'd do it.
Here is the basic script for moving the row that I found from a 2011 post here:
function onEdit(event) {
// assumes source data in sheet named Needed
// target sheet of move to named Acquired
// test column with checkbox is col 1 or A
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "Needed" && r.getColumn() == 1 && r.getValue() == true) {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("Acquired");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 2, 1, numColumns).copyTo(target);
}
}
Hope someone can help. Thanks in advance!
Try this code, please:
function onEdit(event) {
// assumes source data in sheet named Needed
// target sheet of move to named Acquired
// test column with checkbox is col 1 or A
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "Needed" && r.getColumn() == 1 && r.getValue() == true) {
var row = r.getRow();
var numColumns = s.getLastColumn() - 1;
var data = s.getRange(row, 2, 1, numColumns).getValues();
data[0][8] = 'London';
data[0][12] = new Date();
var targetSheet = ss.getSheetByName("Acquired");
targetSheet.getRange(targetSheet.getLastRow() + 1, 1, 1, numColumns).setValues(data);
}
}
Please, try this and let me know how you go. :)
function onEdit(event) {
//assumes source data in sheet named Needed
//target sheet of move to named Acquired
//test column with checkbox is col 1 or A
var spreadsheet = event.source;
var sheet = spreadsheet .getActiveSheet();
var range = spreadsheet.getActiveRange();
var sheetName = sheet.getName();
var col = range.getColumn();
var value = range.getValue();
if (sheetName === "Needed" && col === 1 && value === true) {
var row = range.getRow();
var numColumns = sheet.getLastColumn();
var targetSheet = spreadsheet.getSheetByName("Acquired");
var lastRow = targetSheet.getLastRow();
var target = targetSheet.getRange(lastRow + 1, 1, 1, numColumns - 1);
//added number of rows and columns to select a range instead of a single cell
var values = sheet.getRange(row, 2, 1, numColumns - 1).getValues();
values[0][7] = values [0][1];
//access value of row 1, column 8 and set to value of row 1, column 2
//the values are captured in an array and are zero-based. The first column is column 0 for example.
values[0][11] = new Date();
//access value of row 1, column 12 and set to date-time value of 'now'.
target.setValues(values);
}
}

Copy over a specific range not whole row to another google sheet based on cell value

I would like to have select cells of a row copied from "Pending" sheet to "Live" sheet based on when a specific cell is edited to say "Yes".
So far I'm able to copy the whole row over when a specific cell in a column is edited to say "Yes".
I would like the specific cells in that row to copy and move onEdit, but not the whole row. For example copy, the contents of column 2,3,5,6 but not 4,7,8 etc. of the row edited in the "Pending" sheet over to the "Live" sheet.
Also though, when copying over to the "Live" sheet having column 2 of the "Pending" sheet line up with column 2 of the "Live" Sheet etc. But for column 5 and 6, they should both move over one column since column 4 wasn't copied over. So "Pending" 5 should take the place of "Live" 4 and "Pending" 6 should take the place of "Live" 5.
function onEdit(event) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "Pending" && r.getColumn() == 1 && r.getValue() == "Yes") {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("Live");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).copyTo(target);
}
}
Try This:
function onEdit(e)
{
var ss=e.source;
var sh=ss.getActiveSheet();
var rg=sh.getActiveRange();
var row=rg.getRow();
var col=rg.getColumn();
Logger.log(col);
if(sh.getName()=="Pending" && col==1 && rg.getValue()=="Yes")
{
var row = rg.getRow();
var liveSht = ss.getSheetByName("Live");
var vA=sh.getRange(row,col,1,6).getValues();
var liveA=['',vA[0][1],vA[0][2],vA[0][4],vA[0][5]];
liveSht.appendRow(liveA);
}
}