I'm new to GAS and am struggling with the OnEdit function to copy and paste data from one sheet to another. I have an input sheet and a master sheet that use OnEdit to read "Submit" from cell D36 and transfer data from "Input" E3:E36 to "MasterList" A5:AG5 as a transpose.
My code (see below) simply deletes all data from the input sheet once "Submit" is selected in the dropdown list. Nothing is showing up on the "MasterList" sheet. Is the selected range getting deleted in this code, and if so how can I ensure that it's pasted in the "MasterList" sheet at the end of the last row of data (shown as row 5 here)?
Is there also a way to retain the formulas from the Input range for future input (I have a vlookup in E8:E10 based off of data entered in E5)?
function onEdit(e) {
if (e.source.getActiveSheet().getName() !== "Input" || e.range.rowStart != 36 || e.range.columnStart != 4 | e.value !== "Submit") return
e.source.getActiveSheet()
.getRange("E3:E36")
.setValue(e.source.getSheetByName("MasterList")
.getRange("A5:AG5")
.getValue())
}
Thanks!
The commands setValue and getValue are for one cell ranges or at most the upper left corner cell of a large range. If you want to get values from multicell ranges use getValues which returns a 2 dimensional array of values and if you want to set values for multicell ranges then use setValues here's a resource link which describes the functions along with some examples.
Also when you're creating new code it's easier to debug if you'll break up your command chains so that you can look at the intermediate answers with the debugger.
Related
I have a sheet that we use as a cash log which is updated daily.
I want to limit the amount of rows that are visible to the person entering data. To that end I added a column (#12/L in this case) which applies the number 1 to each new row of data, and sequentially increases the existing rows.
I have a filter applied to Column L that limits viewing to rows that are less than or equal to 5. This accomplishes what I want, but I have to click Filter/Ok to update the view when new rows are added.
Is there a way I could create an onEdit script to monitor Column L for changes, and reapply a filter when a change happens?
I believe your current situation and your goal as follows.
The Spreadsheet has the basic filter at the column "L".
When the value of the column "L" is updated, you want to refresh the filter. For this, you want to use OnEdit trigger. - This is from your question of Is there a way I could create an onEdit script to monitor Column L for changes, and reapply a filter when a change happens?.
In this case, how about copying the existing basic filter of column "L" and removing it, and creating the copied filter again? I thought that by this flow, your goal might be able to be achieved. When this flow is reflected to the Google Apps Script, it becomes as follows.
Sample script:
Please copy and paste the following script to the script editor of Google Spreadsheet. And, when you want to run this script, please manually edit the cell of the column "L" on the sheet of "Sheet1". By this, the script is run. The script copies the existing basic filter of the column "L" and remove it, and create it as new filter. By this, the filter can be reflected to the new value.
function onEdit(e) {
const sheetName = "Sheet1"; // Please set the sheet name.
const range = e.range;
const sheet = range.getSheet();
if (sheet.getSheetName() != sheetName || range.columnStart != 12) return;
const filter = sheet.getFilter();
const fRange = filter.getRange();
const criterion = filter.getColumnFilterCriteria(12).copy();
filter.remove();
fRange.createFilter().setColumnFilterCriteria(12, criterion);
}
Note:
This script is run by the OnEdit trigger. So when you directly run the script with the script editor, an error occurs. Please be careful this.
When the cell of the column "L" is updated by a script, in that case, I would like to recommend to include above method to the script. Because when the cell is updated by a script, the OnEdit trigger is not fired.
References:
Simple Triggers
Event Objects
Added:
From your following replying,
Thank you so much for your response. I'm definitely filing this one away for future use. I do realize that I was a little fast-and-loose with the word filter. Rather than a filter created as a result of a formula, I need to refresh a Filter View, i.e. one created by selecting the funnel and setting up a Filter by condition... An example of what I have can be viewed here: (docs.google.com/spreadsheets/d/…) Essentially nothing above the #5 (in Column L) should be visible after entering anything in Column A.
I understood that you wanted to refresh the basic filter of the column "L" when the column "A" is edited. From your question, I had thought that you wanted to refresh the basic filter of the column "L" when the column "L" is edited. But I understood that my understanding was not correct.
When you want to refresh the basic filter of the column "L" when the column "A" is edited, how about the following sample script?
function onEdit(e) {
const sheetName = "Sheet1"; // Please set the sheet name.
const range = e.range;
const sheet = range.getSheet();
if (sheet.getSheetName() != sheetName || range.columnStart != 1) return;
const filter = sheet.getFilter();
const fRange = filter.getRange();
const criterion = filter.getColumnFilterCriteria(12).copy();
filter.remove();
fRange.createFilter().setColumnFilterCriteria(12, criterion);
}
Is it possible for a Google Sheet dropdown, to auto select the first item in the list onChange / onEdit?
I'm unable to complete this directly on the sheet (I could be missing something), and I don't know enough about the Google Sheep App Script environment to know if it's possible.
I'm assuming that using Google App Script, this could be done.
I have setup this demo sheet, with everything working (other than what I'm after ;-)
https://docs.google.com/spreadsheets/d/1qzRT8rikVUfpZVOmugebB2yVHdLv_60K_Jwvxi6fX0U/edit?usp=sharing
What I would really like, When a "Tool" is changed/selected, I would like the "Colors" dropdown to select the first item in the list.
So if you select "Pencil", "Blue" would be auto selected into the cel. At the moment, the cel stays blank, until the user selects something.
Thank you.
I believe your goal as follows.
When the dropdown list of the cells "B5:B10" and the dropdown list of the column "C" is updated, you want to set the 2nd value of the updated dropdown list.
For example, when the dropdown list of the cells "B5" is set to "Pencil", you want to set the dropdown list of the cells "C5" to "Blue".
You want to achieve this using Google Apps Script.
In this case, I would like to run the script using the OnEdit trigger of the simple trigger. The sample script is as follows.
Sample script:
Please copy and paste the following script to the script editor of your sample Spreadsheet. And, please change the dropdown list of the column "B". By this, the script is run by the OnEdit trigger.
function onEdit(e) {
const range = e.range;
const sheet = range.getSheet();
if (sheet.getSheetName() != "Sheet1" || range.columnStart != 2 || range.rowStart < 5 || range.rowEnd > 10) return;
const r = range.offset(0, 1);
const value = [...new Set(r.getDataValidation().getCriteriaValues()[0].getValues().flat())].filter(e => e != "--")[0];
r.setValue(value);
}
In this sample, when the script is run, the range of the updated data validation rule is retrieved from the column "C", and retrieve the 2nd value of the dropdown list from the range.
Note:
In this sample script, from your sample Spreadsheet, when the dropdown list of cells "B5:B10" are changed, the script is run. So when you want to expand this range, please modify above script.
This sample script is for your sample Spreadsheet. When you change the sample Spreadsheet, the script might not be able to be used. So please be careful this.
References:
Simple Triggers
getDataValidation()
I own two columns A contains numbers and B contains checkboxes.
If A = 0 I would like to auto-check the checkbox else I would like to let the user checks it (or not). But when I use a IF statement in the checkbox cell I can't check it myself (I lose its behavior).
I need something like :
=IF(A1=0;TRUE;#keep checkbox classical behavior#)
How could I do that ?
Explanation:
I don’t think you can accomplish this behaviour with a google sheet formula without compromises. This auto-check behaviour you describe can only be achieved with a trigger; activated when you edit a cell in column A.
I believe you need to take advantage of Google Apps Script and in particular use an onEdit trigger.
Solution:
Click on Tools => Script editor on the top menu of the spreadsheet file, copy & paste the below code into a blank script and click on save. After that, when you put 0 in column A, the corresponding row in column B will be checked. This behaviour will be applied to a sheet named Sheet1. Change that part of the code to apply it to a sheet with a different name.
function onEdit(e) {
const sheet= `Sheet1`; // change Sheet1 to the name of your sheet
const as = e.source.getActiveSheet();
const col = e.range.getColumn();
const row = e.range.getRow();
if(as.getName()==sheet && col==1 && e.value==0){
as.getRange(row,2).setValue(true);
}
}
Unfortunately you can't do what you wish in one formula. As you discovered, interacting with a checkbox in a cell with a formula is essentially like typing over that formula and would overwrite it.
My suggestion to accomplish this is to add an extra column and use the formula you suggested as the final check to what the state of that row should be (true or false).
=if(A2=0,True,B2)
Where A is your values and B is your user entered checkbox.
Here's a sample sheet with it loaded as an array formula. https://docs.google.com/spreadsheets/d/1z8A4WqVppcxGlGiM3l-kW6q88iYBE6LGw5PyVfRh9Js/edit#gid=0
You could then format that column as checkboxes, but if you use an array formula it will get tripped up when it thinks the checkbox is blocking the formula for each new row.
I was trying to figure out a way to insert Notes automatically, when i enter something in a specific cell. This thread was suggested to me and tried it out: https://support.google.com/docs/thread/13317657?hl=en. I changed the function mentioned a littlebit, to fit my project:
function onEdit(e) {
if(e.source.getActiveSheet().getName() === 'Testsheet') {
if(e.range.columnStart === 8 && (e.range.rowStart > 12 && e.range.rowStart < 21)) {
return e.range.offset(0, -6).setNote(e.value);
}
}
}
This way when I enter values in the range H13:H20, the same values get inserted as Notes on the corresponding (0, -6) offset cells. Which is a step in the right direction, but not yet what I'm truly trying to achieve. The problem is, this only works, when the values are entered manually. But for my project, I need the notes also to be set, when values are filled in automatically, using a function that fills in certain information in a row, depending on the selected dropdown choice.
In my sheet for example:
=if(B17="Test1",Testsheet!C10:Testsheet!H10)
When the Information is filled in that way, it doesn't give me the Note in the offset cell. Is there a way, so that it does?
Here is a link to my Testsheet, where you can see what I'm trying to do : https://docs.google.com/spreadsheets/d/16c2hVDM_FTnHWerKjnOauCopwVZSnKCwAMVi6-Z8vBo/edit?usp=sharing
Thanks for any tips and help in advance!
As you can see in the documentation:
Script executions and API requests do not cause triggers to run. For
example, calling Range.setValue() to edit a cell does not cause the
spreadsheet's onEdit trigger to run.
The only option would be to directly run the notes function with the values as parameter instead of inserting the "row 16" values, as updating the sheet by a script or formula won't trigger the function onEdit().
I have a spreadsheet on Google sheets with 2 sheets, Sheet1 and Sheet2. On Sheet1 I have 2 columns (ID1 and Result1), in which are filled. On Sheet2 I have 2 columns (ID2 and Result2), in which ID2 is filled and Result2 is filled with the word "empty".
Sheet1 in my real spreadsheet is getting data from Google Forms, so every time Sheet1 receives a value on ID1 and Result1, it should search for the ID1 value on Sheet2's ID2 and when finding, paste Result1 value in Result2 in the row it's was found.
Result2 would then only be updated when there's new data on Sheet1 submitted from the form.
I created this editable form and spreadsheet to make it easier to understand (I also added a note explaining it in there). You can see the form here and the spreadsheet here.
In cell B2 of your second sheet I entered the following:
=VLOOKUP(A2,Sheet1!A:B,2,FALSE)
I guess VLOOKUP on Google-Sheets does allow reference across worksheets?
FYI, when entering the formula, after enter the first argument which is your look up criteria, you can click your sheet1 and highlight column A and B, then go back to your sheet2 (with the second argument automatically filled by the system) to finish the formula with the third (result range column position within the look up range) and fourth argument (TRUE for approximate match and FALSE for exact match) and hit Enter to exit the formula.
After looking through the current answers and comments I think I understand what you are looking for.
Answer:
You can do this in Google Apps Script by creating a function that is bound to your Google Form which collects the latest response and does the data processing, and making it run on Form submission.
Steps to take:
Firstly, on your Form, you will need to create a bound script. From the menu in the top right of the Form edit page, click ⋮ > Script editor, which will open a new script page.
From there you can make a script which will automatically do this for you, and make an Installable Trigger which runs when you need.
Code:
After opening the Script Editor, you will see a ready-to-edit function that looks like this:
function myFunction() {
}
Replace the entire script with the following code:
function onSubmit(e) {
var responses = FormApp.getActiveForm().getResponses();
var response = responses[responses.length - 1].getItemResponses();
var connectedSheet = SpreadsheetApp.openById('<your-sheet-id>').getSheets();
var sheet2 = connectedSheet[1];
var result2Column = sheet2.getRange('A1:A').getValues();
for (var i = 0; i < result2Column.length; i++) {
if (response[1] == result2Column[0]) {
sheet2.getRange('B' + (i +1)).setValue(response[0]);
}
}
}
Make sure to replace <your-sheet-id> with the unique ID of your Google Sheeet - you can find this in the URL of the sheet between the d/ and /edit like so:
https://docs.google.com/spreadsheets/d/<your-sheet-id>/edit
Run the script by pressing the play button (►) and authorise the application to run.
Then go to Edit -> Current Project's Triggers and set up a new installable trigger with the following settings:
Choose which function to run: onSubmit
Choose which deployment should run: Head
Select event source: From form
Select event type On form submit
Explanation:
This script will run each time a new form submission is made automatically - it will take the ID from the form response and search Sheet2 for it. If it's found, then the response given for result will be put in Sheet2 also, next to the corresponding ID.
References:
Google Apps Script Installable Triggers
do it simply like this:
=ARRAYFORMULA(IFERROR(VLOOKUP(A2:A, Sheet1!A:B, 2, 0)))
or reset by checkbox: