CONTEXT
In a google spreadsheet, copy entire row to another tab when checkbox is active
The below code works and was found online in Code source
function onEdit(event) {
// source sheet named Source A
// target sheet of move to named Development
// getColumn with check-boxes is currently set to column 21
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "Source A" && r.getColumn() == 21 &&
r.getValue() == true) {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("Development A");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).copyTo(target, {contentsOnly:true});
}
}
PROBLEM
I would like to have this code working in 2 tabs (sheets): Source A and Source B to 2 different destination sheets: Destination A and Destination B
Limitation of one onEdit(event)
WHAT I'VE TRIED
Adding "else if" to the code but it only worked for Source A:
else if if(s.getName() == "Source B" && r.getColumn() == 21 && etc
Instead of using onEdit(event), named each function and then tried to use triggers (onEdit) but nothing worked
Can anyone give me a hand?
Thank you in advance.
function onEdit(e) {
const sh = e.range.getSheet();
const shts = ['Source A','Source B'];
if (~shts.indexOf(sh.getName()) && e.range.columnStart == 21 && e.value == "TRUE") {
//e.range.setValue("FALSE");//reset the checkbox
let tsh = e.source.getSheetByName("Development");
var tgt = tsh.getRange(tsh.getLastRow() + 1, 1);
sh.getRange(e.range.rowStart, 1, 1, sh.getLastColumn()).copyTo(tgt, { contentsOnly: true });
}
}
function onEdit(e) {
const sh = e.range.getSheet();
const shts = ['Source A','Source B'];
const tgts = ['Dest A','Dest B'];
const idx = shts.indexOf(sh.getName());
if (~idx && e.range.columnStart == 21 && e.value == "TRUE") {
//e.range.setValue("FALSE");//reset the checkbox
let tsh = e.source.getSheetByName(tgts[idx]);
var tgt = tsh.getRange(tsh.getLastRow() + 1, 1);
sh.getRange(e.range.rowStart, 1, 1, sh.getLastColumn()).copyTo(tgt, { contentsOnly: true });
}
}
Related
I need some assistance please. I have a spreadsheet that moves data from one sheet(JDE worklist) to the next (Printed) by clicking the textbox next to the row to be moved. When the tickbox is un-ticked after its moved the first time it moves it to a final sheet (PrintedArchive). This part works fine.
The problem is that I need a static date stamp next to the row once it gets moved to the next sheet as to capture start and end dates. The date can be added to column BE.
If I try and add a separated script to add a date stamp the script for moving the data stops functioning. So is there a way to incorporate this into the script that moves the data?
Please note that don't have much experience and I'm still learning and would really appreciate the help.
This is the script im currently using to move the data
function onEdit(event) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "JDE Worklist" && r.getColumn() == 1 && r.getValue() == true) {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("Printed");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
} else if(s.getName() == "Printed" && r.getColumn() == 1 && r.getValue() == false) {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("PrintedArchive");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
}
}
Sample sheet
Try this:
function onEdit(e) {
e.source.toast("Entry");
const s = e.range.getSheet();
if (s.getName() == "JDE Worklist" && e.range.columnStart == 1 && e.value == "TRUE") {
var tsh = e.source.getSheetByName("Printed");
var trg = tsh.getRange(tsh.getLastRow() + 1, 1);
s.getRange(e.range.rowStart, 1, 1, s.getLastColumn()).moveTo(trg);
tsh.getRange("BE" + e.range.rowStart).setValue(new Date());
s.deleteRow(e.range.rowStart);
} else if (s.getName() == "Printed" && e.range.columnStart == 1 && e.value == "FALSE") {
var tsh = e.source.getSheetByName("PrintedArchive");
var trg = tsh.getRange(tsh.getLastRow() + 1, 1);
s.getRange(e.range.rowStart, 1, 1, s.getLastColumn()).moveTo(trg);
tsh.getRange("BE" + e.range.rowStart).setValue(new Date());
s.deleteRow(e.range.rowStart);
}
}
I'm very new to scripts (i.e a total novice).I'm trying to update a work tracker used by several members of a team. It basically logs cases on a separate tab for each person.
I have managed to set up a code that moves a row to another tab when a checkbox is ticked (i.e. when a case is closed they can automatically move the row of data to a "Closed" tab).
What I'm having trouble with is giving the team the option of moving it back should they close it in error. I can make it work but it only moves the data back to the named sheet in the script. How do I get it to find the sheet name by looking up the agent's name? The agents name is listed in column D.
Here is the code I've used this is where I believe I need the help:
var targetSheet = ss.getSheetName("Bob");
Many thanks
Loz
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 5 or E
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "Bob","Billy","Anna","Emma","Joe" && r.getColumn() == 5 && r.getValue() == true) {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("Closed");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
} else if(s.getName() == "Closed" && r.getColumn() == 5 && r.getValue() == false) {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetName("Bob");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
}
}
enter image description here
enter image description here
Getting sheet name from agent's column in sheet Closed I think
Assumed header row is one and Agent's column name is Agent
function onEdit(e) {
//e.source.toast("Entry");
//Logger.log(JSON.stringify(e));
const sh = e.range.getSheet();
const names = ["Bob", "Billy", "Anna", "Emma", "Joe"];
const idx = names.indexOf(sh.getName());
if (~idx && e.range.columnStart == 5 && e.value == "TRUE") {
//e.source.toast('Flag1');
var tsh = e.source.getSheetByName("Closed");
var trg = tsh.getRange(tsh.getLastRow() + 1, 1);
sh.getRange(e.range.rowStart, 1, 1, sh.getLastColumn()).moveTo(trg);
sh.deleteRow(e.range.rowStart);
} else if (sh.getName() == "Closed" && e.range.columnStart == 5 && e.value == "FALSE") {
//e.source.toast("Flag2");
let hA = sh.getRange(1, 1, 1, sh.getLastColumn()).getValues().flat();
//Logger.log(JSON.stringify(hA));
let col = {};
hA.forEach((h, i) => { col[h] = i + 1; });
//Logger.log(JSON.stringify(col));
//Logger.log(sh.getRange(e.range.rowStart, col["Agent"]).getDisplayValue());
var tsh = e.source.getSheetByName(sh.getRange(e.range.rowStart, col["Agent"]).getDisplayValue());
var trg = tsh.getRange(tsh.getLastRow() + 1, 1);
sh.getRange(e.range.rowStart, 1, 1, sh.getLastColumn()).moveTo(trg);
sh.deleteRow(e.range.rowStart);
}
}
If you wish a better answer then please provide image of Closed and one of the Named Sheets
I'm assuming you are unchecking a checkbox in column E in the "Closed" sheet and want to move the row back to the original agent. And the name of the agent or sheet name is in column D of that row. Then you can do this.
let agent = e.range.offset(0,-1).getValue();
let targetSheet = ss.getSheetName(agent);
Reference
Range.offset()
function onEdit(event) {
// assumes source data in sheet named Backorder LIST
// target sheet of move to named Completed
// getColumn with check-boxes is currently set to column 1 or A
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "Backorder LIST" && r.getColumn() == 1 && 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);
}
}
I am having trouble finding a way to move only the values to COMPLETED sheet. Anytime I change .moveTo(target); to .copyTo(target, {contentsOnly: true}); the script fails. Any suggestions would be appreciated. Thank you!
Move values only
function onEdit(e) {
var sh = e.range.getSheet();
if(sh.getName() == "Backorder LIST" && e.range.columnStart == 1 && e.value == "TRUE") {
var tsh = e.source.getSheetByName("Completed");
let vs = sh.getRange(e.range.rowStart, 1, 1, sh.getLastColumn()).getDisplayValues();
tsh.getRange(tsh.getLastRow() + 1, 1, vs.length, vs[0].length).setValues(vs);
sh.deleteRow(e.range.rowStart);
}
}
This question already has an answer here:
Merging or Combining two onEdit trigger functions
(1 answer)
Closed last year.
I have two scripts that I need to work with on Google Sheets. The first one auto sorts all rows if I put a date on column 23. The other script moves the entire row to another sheet called completed when I check a box on row 28. Separate they work perfectly but when I add them to the same script one of them stops working. How can I tweak this?
function autoSort(){
const ss = SpreadsheetApp.getActiveSpreadsheet()
const ws = ss.getSheetByName("Installation")
const range = ws.getRange(2,1,ws.getLastRow()-1,28)
range.sort({column:23, descending:false})
}
function onEdit(e){
const row = e.range.getRow()
const column = e.range.getColumn()
if(!(column === 23 && row >= 2)) return
autoSort()
}
function onEdit(event) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "Installation" && r.getColumn() == 28 && r.getValue() == "Completed") {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("Complete");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
}
}
I believe your goal is as follows.
Your 2 functions of onEdit work fine for each run. You want to merge these functions.
In this case, how about the following modification?
Modified script:
function onEdit(e) {
const r = e.range;
if (r.columnStart === 23 && r.rowStart >= 2) {
autoSort()
return;
}
const s = r.getSheet();
if (s.getSheetName() == "Installation" && r.columnStart == 28 && r.getValue() == "Completed") {
var row = r.rowStart;
var numColumns = s.getLastColumn();
var targetSheet = e.source.getSheetByName("Complete");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
}
}
Reference:
Event Objects
I need to run a script triggered by an onedit(event) to different sheets based on cell values for assignments. I have a dropdown list to select the investigator name and corresponding sheets with each investigator name:
function onEdit(event){
// assumes source data in sheet named [Pending assignment]
// target sheet of move to named [investigator]
// test column with [investigator name] is col 2 or B
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "Pending assignment" && r.getColumn() == 2 && r.getValue() == "Investigator 1") {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("Investigator 1");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
}
}
I am able to get the code to work for only one name at a time. I have tried OR statements and combining functions but no luck (or maybe I am just writing them incorrectly). Is there a way to get this function to work to send the rows to different sheets based on the cell value?
Thanks in advance.
Try this:
function onEdit(e) {
e.source.toast('entry');
const tshs = ['Investigator 1','Investigator 2','Investigator 3'];
const sh = e.range.getSheet();
const idx = tshs.indexOf(e.value);
if (sh.getName() == "Pending assignment" && e.range.columnStart == 2 && ~idx) {
let tsh = e.source.getSheetByName(tshs[idx]);
let tgt = tsh.getRange(tsh.getLastRow() + 1, 1);
sh.getRange(e.range.rowStart, 1, 1, sh.getLastColumn()).moveTo(tgt);
sh.deleteRow(e.range.rowStart);
}
}
Perhaps this will work:
function onEdit(e) {
e.source.toast('entry');
const tshs = ['Investigator 1','Investigator 2','Investigator 3'];
const sh = e.range.getSheet();
const idx = tshs.indexOf(e.value);
if (sh.getName() == "Pending assignment" && e.range.columnStart == 2 && ~idx) {
let tsh = e.source.getSheetByName(tshs[idx]);
let tgt = tsh.getRange(tsh.getLastRow() + 1, 1);
sh.getRange(e.range.rowStart, 1, 1, sh.getLastColumn()).moveTo(tgt);
sh.deleteRow(e.range.rowStart);
}
if(~tshs.indexOf(sh.getName()) && e.range.columnStart == 1 && e.value == 'Completed') {
let tsh = e.source.getSheetByName('Completed');
let tgt = tsh.getRange(tsh.getLastRow() + 1, 1);
sh.getRange(e.range.rowStart,1,1,sh.getLastColumn()).moveTo(tgt);
sh.deleteRow(e.range.rowStart);
}
}