I'm trying to use a pretty standard copy row from one sheet to another sheet code when Column B shows 'Start', but Column B has the following formula in it:
=IF(A2 = "Complete","Start","Not Yet")
and this code doesn't seem to recognize the formula changing from 'Not Yet' to Start'. Any help would be greatly appreciated. Thanks!
function onEdit(event) {
// assumes source data in sheet named Needed
// target sheet of move to named Acquired
// test column with yes/no is col 4 or D
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "Temp" && r.getColumn() == 1 && r.getValue() == "Complete") {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("Start");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
}
}
The issue is not that it does not "recognize" the formula changing value. If you look at your formula again after it is copied you should notice that the reference changes from A2 to Temp!A2.
moveTo works like if you individually cut-n-paste each cell into their new operation. This results in this "maintaining" of the reference to their original cells.
If this is not desired, maybe you should switch to copyTo. Which might have other side effects in your formulas. But should work fine for this simple one you exemplified.
s.getRange(row, 1, 1, numColumns).copyTo(target); //try copyTo here
Related
this is my very first attempt at programming period so I apologize for what may come across as a simple question to you experienced folks. I'm working through Google Sheets scripting for this.
ISSUE: I have a file with multiple tabs, the key tabs with this question are marked as "submit" and "db". Within the "submit" tab I will have information (including formulas) in many rows from columns A to Y. When I enter "run" in column Z for a particular row I would like the information in that row only from columns A to Y to copy and paste as values to the next available row in the "db" tab. Once this is complete I would like the original trigger cell to be deleted (not cleared as I have a border around it) and the row above it to be deleted from columns A to Y as well (not cleared as I have borders and data validation)
I hope this makes sense.
Below is the code I've been using. I have been able to successfully move the information from the "submit" tab to the "db" tab but that has been about it. I've been playing with the copyValuesOnly, moveValuesOnly, clearContent, getFormulas/setFormulas however I simply cannot crack the code.
Thank you in advance!
function onEdit(event) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "submit" && r.getColumn() == 26 && r.getValue() == "run") {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("db");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1,1,1,numColumns);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.range.clearContent();
}
}
EDIT:
I've included a link to the sheet below, hopefully I provided the correct rights to it. As an example of what I want to do is if I were to select "run" in cell Z12 of the "submit" tab it would do the following:
copy the information from A12 to Y12 and paste as values to the "db" tab cells A2 to Y2 (as it's the next available row, once this copy is complete...
cell Z12 on the "submit" tab (trigger cell) would be would be deleted (border and data validation should remain)
the above row from cells D11 to Y11 should be deleted (border and data validations intact)
https://docs.google.com/spreadsheets/d/1VAnFExL7jJVnqvZ_hq_2ihVQFFuV9szCEnT3NLK8m4Y/edit?usp=sharing
Use this:
function onEdit(event) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "submit" && r.getColumn() == 26 && r.getValue() == "run") {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("db");
var target = targetSheet.getRange(targetSheet.getLastRow()+1,1);
s.getRange(row, 1, 1, numColumns).copyTo(target,{contentsOnly:true});
//Clear column Z content
r.clearContent();
//Clear previous row Column D-Y
s.getRange(row-1,4,1,22).clearContent();
}
}
Explanation:
The reason why Sheet "submit" row 12 format and content was cleared is because you are using Range.moveTo(target) to copy the content to sheet "db". moveTo() cuts and pastes (both format and values) from this range to the target range.
To fix this, you can use Range.copyTo(destination, options)
To clear content of the modified cell (retain data validation and format), use clearContent(). Hence to clear the content of modified cell in column Z, use r.clearContent();
To clear the content of the previous row from column D-Y, get its range first then use clearContent(). Done using s.getRange(row-1,4,1,22).clearContent();
Output:
(Before)
(After)
Notice that the formula is still available in row 12
It looks like all you need to do is:
change that last row to
s.getRange(row, 1, 1, numColumns).clearContent();
"s.range" isn't doing anything.
It is unclear, you want to maintain the datavalidation and borders, right?
also unsure whether you were clearing out two rows or one, if it is two
s.getRange(row-1, 1, 2, numColumns).clearContent();
Does this get you closer?
whole code (added for clarity)
function onEdit(event) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "submit" && r.getColumn() == 26 && r.getValue() == "run") {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("db");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1,1,1,numColumns);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.getRange(row, 1, 1, numColumns).clearContent();
}
}
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);
}
}
To expand on the surface level detail of my question; I have one google sheet tab which updates automatically with data each Monday. What I need to be able to do is copy that row from it's tab within the Google Sheet to another tab within the same over arching sheet. This copied row needs to be placed one down from the previous row (week 1 would be row 1, week 2 row 2 etc).
So far I have set up a trigger for this script to run each Monday (so I've managed the easy part...) but I still cannot figure out how to do the main body of work! I've had a look at some similar bits of code (one of which I've pasted down below) where data gets moved across to a new sheet when a box is ticked or when a certain value is noticed in a cell, but I couldn't modify either of these to work in my case.
I'm completely new to using Google Script and with no background in any language so help on this would be amazing! Or if anybody knows a way of performing this function without the need of Script that would be even better! (I've looked into using =today() and using the dates i would be looking for as triggers, but of course that comes up with an error as the text of the cell is '=today()' and not the actual date...)
function onEdit(event) {
// assumes source data in sheet named main
// target sheet of move to named Completed
// getColumn with check-boxes is currently set to colu 4 or D
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "main" && r.getColumn() == 4 && r.getValue() == true) {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("Completed");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
} else if(s.getName() == "Completed" && r.getColumn() == 4 && r.getValue() == false) {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("main");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
}
}
I'm working on a spreadsheet for my boss and I've been trying to add a feature where the entire row moves from Sheet1 to Sheet2 when the checkbox in column1 is checked. The code I'm using works, except sometimes it moves two rows at once even though only one box is checked. Here's my code:
function onEdit(event) {
// assumes source data in sheet named Sheet1
// target sheet of move to named Sheet2
// test column with yes/no is col 1 or A
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "Sheet1" && r.getColumn() == 1 && r.getValue() == true) {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("Sheet2");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
}
}
I am NOT experienced with code at all. I got this from Joshua Doan's reply to someone else's question: Google script for move rows depending on checkbox - Google sheet
So my question is, how do I get it to stop moving two rows at once??
Thanks much!
function onEdit(e) {
var sh=e.range.getSheet();
if(sh.getName()!='Sheet1')return;
if(e.range.columnStart==1 && e.value=="TRUE") {
var row1=sh.getRange(e.range.rowStart,1,1,sh.getLastColumn());
var tsh=e.source.getSheetByName('Sheet2');
row1.moveTo(tsh.getRange(tsh.getLastRow()+1,1));
sh.deleteRow(e.range.rowStart);
}
}
I am super novice and wanted to get someone's input on how to make this work. I have been looking around and this has been the main topic. Which would send an ENTIRE row to another tab as the destination tab. But how to do you specify only to have one cell's information to the next tab. For example, I have names on Column A and I would only like to send the name and none of the information after that to the next google sheet tab once I get the value true.
function onEdit(event) {
// assumes source data in sheet named main
// target sheet of move to named Completed
// getColumn with check-boxes is currently set to column 4 or D
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "Interviewer Training" && r.getColumn() == 16 && r.getValue() == true) {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("General IC SWE");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
} else if(s.getName() == "General IC SWE" && r.getColumn() == 16 && r.getValue() == false) {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("Interviewer Training");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1;
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
}
}
To move a single cell value from the current sheet to the next sheet.
function onEdit(e) {
//e.source.toast('flag1');
var sh=e.range.getSheet();
var idx=sh.getIndex();
var tsh=nextSheet(e);
//e.source.toast('Next Sheet: ' + tsh.getName());
if(sh.getName()!="Sheet1")return;
if(e.range.columnStart==1 && e.value=='TRUE' && !e.range.offset(0,1).isBlank() ) {
//e.source.toast('flag2');
tsh.getRange(e.range.rowStart,e.range.columnStart + 1).setValue(e.range.offset(0,1).getValue());
}
}
function nextSheet(e) {
//e.source.toast('flag3');
var sh=e.range.getSheet();
var shts=e.source.getSheets();
return shts[(sh.getIndex())%shts.length];
}
This is my sheet 1:
This is the next sheet:
I'm using the click of a checkbox to trigger the onEdit() function to make the transfer of the data immediately to the right of the selected check box and I move it to the same cell in the next sheet. The next sheet is the sheet immediately to the right or if it's the last sheet on the right it moves to the first sheet.
Sheet.getIndex()
Remainder or Modulo Operator
To move just a single cell you would only need to change your s.getRange()
s.getRange(row, 1, 1, numColumns).moveTo(target);
To get cell in row X column B
s.getRange(row, 2, 1, 1).moveTo(target);
The get range uses these parameters;
.getRange(Row Number, Column Number, Number of Rows, Number of Columns)
You only need to edit Column Number and Number of Columns
So row X column C & D would be
s.getRange(row, 3, 1, 2).moveTo(target);