How can I find a sheet name by looking up a column - google-apps-script

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()

Related

Script to move data between sheets and adding a static date stamp (Google sheets)

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

Move rows onedit(event) to different sheets based on cell values

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

Move row based on cell selection

I have a script that moves the whole row to a different tab and deletes it from the tab it was moved based on a "list" selection.
The script is the following:
// Script Move & Delete
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();
// In Review Trigger
if(s.getName() == "Applied" && r.getColumn() == 1 && r.getValue() == "In Review") {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("In Review");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
}
// In Review Trigger
else if(s.getName() == "Applied" && r.getColumn() == 1 && r.getValue() == "Failed") {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("Failed");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
}
So for example, if the row on Tab "Applied" and value of cell on column 1 = In Review then the row is moved to tab "In Review" but if the value of cell on column one = to Failed then row is moved to tab Failed.
That part works like charm and I know having multiple tabs will have a lot of else ifs, I'm not much of a dev, so I was wondering how can I do to move the row if the status (Column 1) is changed to Applied is moved to tab one or failed tab if value is changed to failed?
Basically, move the rows between tabs based on value of column one of each row/tab.
Thanks in advance!
This worked for me:
function onMyEdit(e) {
//e.source.toast('entry');
const s = e.range.getSheet();
if (s.getName() == "Sheet1" && e.range.columnStart == 1 && e.value) {
//e.source.toast('cond')
const names = ['Sheet2', 'Sheet3'];
let idx = names.indexOf(e.value);
if (~idx) {
//e.source.toast('sheet');
let tsh = e.source.getSheetByName(names[idx]);
let tgt = tsh.getRange(tsh.getLastRow() + 1, 1);
s.getRange(e.range.rowStart, 1, 1, s.getLastColumn()).moveTo(tgt);
s.deleteRow(e.range.rowStart);
}
}
}
I made some name changes to make it easier for me to debug so look it over to make sure all of the sheet names are right for your needs.
If you require more complex functionality in moving rows, take a look at the moveRowsFromSpreadsheetToSpreadsheet_ script. It is unfortunately too long to quote here directly.

Google Sheets onEdit moving rows between sheets with different columns

I'm trying to create a simple shipment processing flow and want to move rows between two sheets(tabs) using an onEdit checkbox trigger.
Here's a link to my project: https://docs.google.com/spreadsheets/d/1SPO21kAyNX5fEqwkXVjmPASkfHvZ5Tzbq4s7e22VdYg/edit#gid=2005756436
The basic concept is that shipments made up of multiple pieces are input on the first sheet and then copied to the WB_Log sheet. When planning what to load into a truck, a checkbox is used to move the pieces from the WB_Log sheet to the Load_Plan sheet where their loading location will be determined in a column to the right of the checkbox. If a piece or pieces of a shipment will not fit in a particular truck, I want to uncheck the box on Load_Plan and have the row moved back to the WB_Log Sheet.
Here is the onEdit function I found that almost works:
function onEdit(event) {
// assumes source data in sheet named WB_Log
// target sheet of move to named Load_Plan
// getColumn with check-boxes is currently set to column 14 or N
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "WB_Log" && r.getColumn() == 14 && r.getValue() == true) {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("Load_Plan");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
} else if(s.getName() == "Load_Plan" && r.getColumn() == 14 && r.getValue() == false) {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("WB_Log");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
}
}
My issue is that Load_Plan has columns to the right of the checkbox that I don’t want moved back to WB_Log. How do I adjust the code so that only the information from columns A:N move from Load_Plan back to WB_Log when the checkbox is unchecked (False)?
Any advice or ideas anyone can lend would be very much appreciated.
Modification points:
When I saw your shared Spreadsheet, "WB_Log" sheet has the checkboxes in the column "N". And the checkboxes are put to the bottom of the sheet. By this, targetSheet.getLastRow() + 1 returns the next row of the buttom of sheet. I think that this is the reason of your issue.
I think that in your situation, when the last row of after row of "B4" is retrieved, the row number can be used.
And, in your script, the columns "A" to "O" in "Load_Plan" sheet are retrieved by var numColumns = s.getLastColumn(). But "WB_Log" sheet has the columns "A" to "N". I think that the retrieved columns are required to be reduced 1 column.
When above points are reflected to your script, it becomes as follows.
Modified script:
Please modify your script as follows.
From:
} else if(s.getName() == "Load_Plan" && r.getColumn() == 14 && r.getValue() == false) {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("WB_Log");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
}
To:
} else if(s.getName() == "Load_Plan" && r.getColumn() == 14 && r.getValue() == false) {
var row = r.getRow();
var numColumns = s.getLastColumn() - 1; // Modified
var targetSheet = ss.getSheetByName("WB_Log");
var lastRow = targetSheet.getRange("B4").getNextDataCell(SpreadsheetApp.Direction.DOWN).getRow(); // Added
var target = targetSheet.getRange(lastRow + 1, 1); // Modified
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
}
Reference:
getNextDataCell(direction)

Copying Row of Data To New Sheet when checking the check box

I have about 20 rows in 5 different sheets and I would like the row to copy to a separate sheet once I check the checkbox. I would like the rows to remain in its source sheet when the row is copied.
I found code that copies the entire row over the separate sheet and then copies the row back once it's un-checked, but it obviously needs tweaking to be applicable to my scenario. Here it is:
function onEdit(event) {
// assumes source data in sheets named Brushed Nickel, Chrome, Matte Black, Brass/Gold, Tile and Paint
// target sheet of move to named Desing Specs
// getColumn with check-boxes is currently set to column 11 or K
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "Brushed Nickel", "Chrome", "Matte Black", "Brass/Gold", "Tile and Paint" && r.getColumn() == 11 && r.getValue() == true) {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("Desing Specs");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
} else if(s.getName() == "Desing Specs" && r.getColumn() == 11 && r.getValue() == false) {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("Brushed Nickel", "Chrome", "Matte Black", "Brass/Gold", "Tile and Paint");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
}
}
Screen Shot:
Can someone please help?
Thank you in advance!
function onEdit(e) {
var s = e.range.getSheet();
var shts=["Brushed Nickel", "Chrome", "Matte Black", "Brass/Gold", "Tile and Paint"];
if(shts.indexOf(s.getName()!=-1) && e.range.columnStart==11 && e.value == "TRUE") {
var targetSheet=e.source.getSheetByName("Design Specs");
var target=targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(e.range.rowStart, 1, 1, s.getLastColumn()).copyTo(target);
}
}