Google sheet script about moving row to another tab using dropdown - google-apps-script

Here is a video of what I am trying to do.
[https://soapbox.wistia.com/videos/rVDNWFKiuW][1]
The YT video I am trying to copy is
https://youtu.be/YBd7Bv41A1Q
Here is the script he is using.
Script:
function onEdit(e) {
const src = e.source.getActiveSheet();
const r = e.range;
if (r.columnStart != 3 || r.rowStart == 1 || e.value == src.getName()) return;
const dest = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(e.value);
src.getRange(r.rowStart,1,1,3).moveTo(dest.getRange(dest.getLastRow()+1,1,1,3));
src.deleteRow(r.rowStart);
}

It works like this just using a simple trigger.
NO Need to create an installable trigger. I put a dataValidation in Sheet0 column 3 from a list Sheet1,Sheet2 and it works just fine.
function onEdit(e) {
const sh = e.range.getSheet();
if (e.range.columnStart != 3 || e.range.rowStart == 1 || e.value == sh.getName()) return;
const dest = e.source.getSheetByName(e.value);
sh.getRange(e.range.rowStart,1,1,3).moveTo(dest.getRange(dest.getLastRow()+1,1,1,3));
sh.deleteRow(e.range.rowStart);
}
Demo:

You need to create a Trigger to allow the script to perform the changes once you make a change on the drop down menu.
Example:
In this image I used the same script shown in the video and I added it as a trigger for the script. Note that it was added as an OnEdit type of trigger:

Related

How to delete a row as indicated in a cell in google app script?

What I want to do:
I write a row number in a cell, let's say F1, and the value is 9.
I want to add a button that calls a script that will delete the line as I wrote it into the cell, so in this example, line 9.
So I start with:
var s = SpreadsheetApp.getActive()
var sheet = s.getSheetByName('Books');
var row = sheet.getRange('F1');
However this:
sheet.deleteRow(row.getValue());
will give an out of bounds error. getDisplayValue does not work as well and putting it into an parseint doesn't work either.
The 9 hardcoded
sheet.deleteRow(9);
works of course.
I also debbuged and did a
sheet.getRange('G1').setValue(row.getValue());
to verify that the 9 is indeed there, which it is, the 9 will be copied to cell G1.
sheet.getRange('A'+row.getValue()+':J'+row.getValue()).clearContent();
meanwhile will have it treat it as a A:J and delete every line not just one. Doing toString after getValue did also not change anything.
What am I missing here to turn the cell value into a range?
Sheet.deleteRow(value of F1):
function onEdit(e) {
const sh = e.range.getSheet();
if(sh.getName() == "Your sheet name" && e.range.columnStart == 6 && e.range.rowStart == 1 && e.value) {
sh.deleteRow(e.value)
}
}
Cannot call this function from script editor must save in project and edit F1 of Your Sheet. You also need to edit line 3 and add the name of the appropriate sheet.
Using a checkbox for a button:
function onEdit(e) {
e.source.toast("Entry")
const sh = e.range.getSheet();
if(sh.getName() == "Sheet0" && e.range.columnStart == 1 && e.range.rowStart == 1 && e.value == "TRUE") {
e.source.toast("Gate1")
e.range.setValue("FALSE")
sh.deleteRow(sh.getRange("F1").getValue());
}
}
Demo:

Copying Data from one Sheet to another using Check Boxes

I am trying to figure out a way to "automate" a task in google sheets. I have a data model that lists all the data on one sheet of all the 'hit percentages' of sports props. The data changes as games complete. I'd like to have check boxes(or something similar) next to the rows that when it's checked it copies that row and then adds it into a sheet called 'Logs" after the last row.
I put this sheet together as an example:
https://docs.google.com/spreadsheets/d/1KocfnKXK1sPmBr3uQfcn8dC6MYV0JUWDz5Ql3AgTMEI/edit?usp=sharing
I believe your goal is as follows.
When you checked the checkbox of column "B" of "Changing Data" sheet, you want to copy the row to the next row of the last row of "Log" sheet.
In this case, how about the following modification? In this modification, in order to check whether the checkbox is checked, the simple trigger of OnEdit is used.
Sample script:
Please copy and paste the following script to the script editor of Spreadsheet and save the script. When you use this script, please check the checkbox of column "B" of "Changing Data" sheet. By this, the script is automatically run by the OnEdit trigger.
function onEdit(e) {
const srcSheetName = "Changing Data"; // This is from your sample Spreadsheet.
const dstSheetName = "Log"; // This is from your sample Spreadsheet.
const { range, source } = e;
const sheet = range.getSheet();
if (sheet.getSheetName() != srcSheetName || range.columnStart != 2 || !range.isChecked()) return;
const dstSheet = source.getSheetByName(dstSheetName);
range.offset(0, -1, 1, 2).copyTo(dstSheet.getRange(dstSheet.getLastRow() + 1, 1));
}
Reference:
Simple Triggers
Copy Row To Log Sheet
function onEdit(e) {
//e.source.toast("Entry");
const sh = e.range.getSheet();
if(sh.getName() == "Sheet0" && e.range.columnStart == 7 && e.range.rowStart > 1 && e.value == "TRUE") {
//e.source.toast("Gate1");
e.source.toast("Gate1");
const lsh = e.source.getSheetByName("Log");
const vs = sh.getRange(e.range.rowStart,1,1,sh.getLastColumn()).getValues();
lsh.getRange(lsh.getLastRow() + 1, 1,vs.length,vs[0].length).setValues(vs);
}
}
Sheet0:
Alternative Solution
You can try this another implementation using appendRow() & getValue() methods.
This sample will only run the onEdit() function when column B check-boxes are selected on the Changing Data sheet. The function will only copy the text on Column A row that is adjacent to the selected checkbox.
Script
function onEdit(e) {
e.source.getActiveSheet().getName() == 'Changing Data' && e.range.getColumn() == 2 && e.value == "TRUE" ? e.source.getSheetByName('Log').appendRow([e.source.getSheetByName('Changing Data').getRange('A' + e.range.getRow()).getValue()]) : _ ;
}
Alternate Script if you want to include check-boxes to be also copied:
function onEdit(e) {
e.source.getActiveSheet().getName() == 'Changing Data' && e.range.getColumn() == 2 && e.value == "TRUE" ?
(e.source.getSheetByName('Log').appendRow([e.source.getSheetByName('Changing Data').getRange('A' + e.range.getRow()).getValue()]) ?
(e.source.getSheetByName('Changing Data').getRange('B' + e.range.getRow()).copyTo(e.source.getSheetByName('Log').getRange('B' + e.source.getSheetByName('Log').getLastRow()))) : _) : _;
}
Demo
Changing Data sheet
Logs sheet

Transferring Rows between Sheets via a like Identifier

Evening everyone!
I asked this about a week back, but I think the thread got lost in the ether. We came close, but I'm trying to create a function where "Transfer a range of Rows from sheet 1 to sheet 2. Sheet 1 has order IDs in column E. G will have =unique to show me all current order IDs, with check boxes next to each unique reference. Check the box next to which ones you want to CUT over > Select a menu run add on > Run Script > all Rows from A:E that match the desired ID are moved".
[Picture Reference]
Sheet Reference
function onEdit(e) {
e.source.toast('Entry')
const sh = e.range.getSheet();
if(sh.getName() == "Reference" && e.range.columnStart == 8 && e.range.rowStart > 1 && e.value == "TRUE") {
e.source.toast('Gate1')
let rg = sh.getRange(e.range.rowStart,1,1,5)
let vs = rg.getValues();
const osh = e.source.getSheetByName("Processing");
osh.getRange(osh.getLastRow() + 1,1,1,5).setValues(vs);
rg.deleteCells(SpreadsheetApp.Dimension.ROWS);
e.range.setValue("FALSE");
}
}
Here is what we had so far. Please let me know if anyone can help, thank you!
To get all rows that match the unique ID whose checkbox was ticked, use Array.filter(), like this:
/**
* Simple trigger that runs each time the user hand edits the spreadsheet.
*
* #param {Object} e The onEdit() event object.
*/
function onEdit(e) {
if (!e) {
throw new Error(
'Please do not run the onEdit(e) function in the script editor window. '
+ 'It runs automatically when you hand edit the spreadsheet.'
+ 'See https://stackoverflow.com/a/63851123/13045193.'
);
}
moveRowsByUniqueId_(e);
}
/**
* Triggers on a checkbox click and moves rows that match a unique ID.
*
* #param {Object} e The onEdit() event object.
*/
function moveRowsByUniqueId_(e) {
let sheet;
if (e.value !== 'TRUE'
|| e.range.rowStart <= 1
|| e.range.columnStart !== 8
|| (sheet = e.range.getSheet()).getName() !== 'Reference') {
return;
}
e.source.toast('Moving rows...');
const uniqueId = e.range.offset(0, -1).getValue();
const range = sheet.getRange('A2:E');
const values = range.getValues();
const targetSheet = e.source.getSheetByName('Processing');
const _matchWithId = (row) => row[4] === uniqueId;
const valuesToAppend = values.filter(_matchWithId);
if (uniqueId && valuesToAppend.length) {
appendRows_(targetSheet, valuesToAppend);
range.clearContent();
const remainingValues = values.filter((row) => !_matchWithId(row));
range.offset(0, 0, remainingValues.length, remainingValues[0].length)
.setValues(remainingValues);
e.source.toast(`Done. Moved ${valuesToAppend.length} rows.`);
} else {
e.source.toast('Done. Found no rows to move.');
}
e.range.setValue(false);
}
For that to work, you will need to paste the appendRows_() and getLastRow_() utility functions in your script project.
It work almost like asked but :
it's using a personal lib (available below)
didn't make the part realtiv of removing range and aggregate result, I hope i can add it to the lib some day. However, empty cell are fill with -
for an obscure reason, it doesn't like the TRUE/FALSE cell, but work like a charm with 1/0 or any other texte value, regex, ...
Additional error handling are to be added if not any match or others possibilites
function onEdit(e){
console.log(SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Reference").getRange("H3").getValue())
var tableReference = new TableWithHeaderHelper(SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Reference").getRange("A1").getDataRegion());
var tableReferenceId = new TableWithHeaderHelper(SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Reference").getRange("G11").getDataRegion());
var tableProcessing = new TableWithHeaderHelper(SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Processing").getRange("A1").getDataRegion());
// get value
var id = tableReferenceId.getTableWhereColumn("Move to Sheet").matchValue(1).getWithinColumn("Unique Filter").cellAtRow(0).getValue();
var tableWithinId = tableReference.getTableWhereColumn("Shipment ID").matchValue(id)
for(var i=0 ; i < tableWithinId.length() ; i++){
var rangeRowWithinId = tableWithinId.getRow(i);
tableProcessing.addNewEntry(rangeRowWithinId);
for(var cell in rangeRowWithinId.getRange()) cell.setValue("-");
}
//reset value
tableReferenceId.getTableWhereColumn("Move to Sheet").matchValue(1).getWithinColumn("Move to Sheet").cellAtRow(0).setValue(0)
}
See below the app script file you need to create in order to use this utils function:
https://github.com/SolannP/UtilsAppSsript/blob/main/UtilsGSheetTableHelper.gs

Copy values from a sheet to another sheet when checkbox is checked using Google Script

I have an onEdit function for my Google Sheet where when a checkbox in column X of the source sheet is checked, it will copy the values of the cells in column Y and Z, then paste them into column A and B of the destination sheet. It worked fine previously but it suddenly stopped working and I can't seem to find the problem. I've tried adding a trigger for it to my Script Editor project as well, but nothing happens when I check the checkbox, and there is no error message. I'm quite new to this so any help is much appreciated.
Here's the code that I've been using:
function onEdit(e) {
const src = e.source.getActiveSheet();
const r = e.range;
if(src.getName() !="Source" || r.columnStart != 24 || r.rowStart == 1,2) return;
const dest = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Destination");
src.getRange(r.rowStart,25,1,2).copyTo((dest.getRange(dest.getLastRow()+1,1,1,2)),SpreadsheetApp.CopyPasteType.PASTE_VALUES,false);
}
I believe your goal is as follows.
When the ckeckbox of the column "X" is checked, you want to copy the values of columns "Y" and "Z" from "Source" sheet to "Destination" sheet.
Although, unfortunately, I cannot understand the script of It worked fine previously, when your showing script is modified, how about the following modification?
Modified script:
function onEdit(e) {
const src = e.source.getActiveSheet();
const r = e.range;
if (src.getName() != "Source" || r.columnStart != 24 || r.rowStart <= 2 || !r.isChecked()) return;
const dest = e.source.getSheetByName("Destination");
src.getRange(r.rowStart, 25, 1, 2).copyTo((dest.getRange(dest.getLastRow() + 1, 1, 1, 2)), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
}
I thought that you wanted to do r.rowStart == 1,2 as r.rowStart <= 2.
In order to check the checkbox, isChecked() is used.
Reference:
isChecked()

ReferenceError: "e" is not defined | difficulties with multiple script running on just one sheet

For my work I made a spreadsheet which tracks the maintenance dates for all different tasks of †heir respective machine.
My scripts have been working just fine, but I noticed that it would run on all the pages I have in my Sheet.
So I have been searching for a solution, but I can't seem to make the different solutions I found work for me.
The script I have been using:
function onEdit(e) {
if (e.range.getColumn() == 6) {
e.range.offset(0, 3).setValue("")}
};
function onEdit2(e) {
if ([10].indexOf(e.range.columnStart) != -1) {
e.range.offset(0, 1).setValue(newDate()).setNumberFormat("dd.MM.yyyy | HH:mm")};
}
With this I have been the closest to completing my quest (I think)
function Autoclear(e){
var sheet = event.source.getActiveSheet(e);
if(sheet.getName()=='Onderhoud'){
var editedCell = sheet.getActiveCell();
if (e.range.getColumn() == 6) {
e.range.offset(0, 3).setValue("")}
}
};
function Timestamp(e){
var sheet = event.source.getActiveSheet(e);
if(sheet.getName()=='Onderhoud'){
var editedCell = sheet.getActiveCell();
if ([10].indexOf(e.range.columnStart) != -1) {
e.range.offset(0, 1).setValue(new Date()).setNumberFormat("dd.MM.yyyy | HH:mm")};
}
}
This doesn't give me an error upon saving, but I do get the error message upon running.
(ReferenceError: 'e' is not defined)
The main goal is to make the script work in 1 specific page: "Onderhoud"
How can I make this work? If there is something not correctly formatted or left information I will been more than happy the provide.
Try this script, instead of the ones you have
function onEdit(e) {
var sheet = e.source.getActiveSheet();
var ind = [6, 10].indexOf(e.range.columnStart);
if (sheet.getName() == 'Onderhoud' && ind > -1) {
if (ind === 0) {
e.range.offset(0, 3).setValue(null)
} else {
e.range.offset(0, 1).setValue(new Date()).setNumberFormat("dd.MM.yyyy | HH:mm")
};
};
}
As noted by Amit, edit the designated columns (instead of running the script from the script editor) to check if the script works.
The onEdit trigger should not be run manually. The Spreadsheet service will pass the e object when the trigger is run via any edits in the spreadsheet.