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:
Related
I am using GAS to generate a Google Form via Google Sheets. After the Form is generated and the "Responses" tab is added to the Sheet, the script adds a formula to cell E1 that is just supposed to copy the Timestamp from the A column to the E column. It looks like this:
ss.getSheets()[0].getRange("E1").setFormula("={\"Timestamp Moved\"; ARRAYFORMULA(IF($A$2:$A<>\"\",$A$2:$A,\"\"))}");
And shows this in the cell:
={"Timestamp Moved"; ARRAYFORMULA(IF($A$2:$A<>"",$A$2:$A,""))}
The formula drops into place just fine and looks right when I go to the Sheet and click on E1. However, whenever the Form is submitted, the "A$2:$A" moves down one row. So after the first submission, the formula in E1 changes to:
={"Timestamp Moved"; ARRAYFORMULA(IF($A$3:$A<>"",$A$3:$A,""))}
And so on. However, if I go into E1 and manually type the formula ={"Timestamp Moved"; ARRAYFORMULA(IF($A$2:$A<>"",$A$2:$A,""))} it works just fine. The A2 will stay A2 across all submissions.
The setFormula function is only running once, so it isn't like the GAS script is updating it. Any ideas why it is moving itself down?
EDIT
To minimally reproduce this, open GAS from within a Google Sheet and add this script:
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.getSheets()[0].getRange("C1").setFormula("={\"Timestamp Moved\"; ARRAYFORMULA(IF($A$2:$A<>\"\",$A$2:$A,\"\"))}");
}
Next, from within the Sheet, select "Tools" and "Create a new form". Make a one question Form, then run the script. Go to the Responses tab and you should see this:
Then, fill out the Form once and you will now see this:
The timestamp is not moved and the formula shifts.
Google form response is inserted right after the row of the last response.
So the range changes from A2:A tp A3:A.
You should either add the formula after there is a response in row 2,
or use INDIRECT("A2:A") instead of A2:A.
It should be a very simple function but I can't find anything that functions the way I need.
I want to have a cell where a number can be entered, then after its entered it is replaced by that number rounded to its nearest 0.25
For example:
I enter 5.26 into cell A1, after i press enter the cell now says 5.25
This should only happen with cell A1, so if i enter 5.26 elsewhere it will stay as 5.26
Any help? Thanks in advance and sorry if this a common question.
This can be achieve by using Google Apps Script and onEdit Trigger.
Follow these steps to achieve the desired goal.
In your Google Sheet, go to Tools -> Script editor.
Delete any code in the script editor and paste code provided below.
Click Save.
Go back to your Google Sheet and type numbers in cell A1.
Press enter and wait the value to change.
Code:
function onEdit(e) {
var range = e.range;
var input = e.value;
if(range.getA1Notation() == "A1" && !isNaN(input)){
var number = (Math.round(input * 4) / 4).toFixed(2);
range.setValue(number);
}
}
Demo:
Triggers let Apps Script run a function automatically when a certain
event, like opening a document, occurs. In your case, we need to use
onEdit since it runs automatically when a user changes the value of
any cell in a spreadsheet. Apps Script passes the
triggered function an event object that contains information about the
context in which the event occurred (usually named e).
In the demo above, I created a condition that will check if the edited cell is A1 and if the inputted value is number. If both satisfy the condition, the script will calculate the value and use range.setValue() to change the value of A1.
References:
Class Range
Range.setValue(value)
Simple Triggers
Event Object
I'm looking for a script that I can add to a Google sheet that will auto generate an email and include some of the fields in the spread sheet.
I had created a Google Form and I have that data going to the Google spreadsheet, the idea is when the user submits the form it sends that data to the spreadsheet and the spreadsheet sends an automated email.
I found this script and edited it some but it fails on the 4th line (var theEvent = e.values[1]):
function AutoConfirmation(e){
var theirFirst = "Bill";
var theirEmail = johndoe#example.com;
var theEvent = e.values[1];
var subject = "Form Submitted";
var message = "Thank you, " + theirFirst + " for the expressed interest in our " + theEvent;
MailApp.sendEmail (theirEmail, subject, message);
}
Shouldn't line 4 pull the data from column 1 in my google sheet? Is this old an script and it doesn't work now?
In my google sheet I have Site instead of event as a column and another that has Complete as a header.
Let me know what I have missed here as it seems that this should be simple.
I tried to run this and this is the result: screenshot of the error I get
I get the same type of error when running the code above so I thought I would run a logger to see if I get anything with that and the result is in the screen shot. Click the link to see it.
It looks that the script that you found is function to be put in a Apps Script project bounded to a Google spreadsheet and called by an installable trigger.
Shouldn't line 4 pull the data from column 1 in my google sheet?
No. e.values returns an Array which use a zero based index. This means that index for Column A, the first column, is 0.
Issue:
The error you are getting:
TypeError: Cannot read property 'values' of undefined
Means that the event object (e) is undefined, which means that you are trying to run this function manually. Functions that are attached to a trigger are supposed run when the corresponding trigger event happens: in this case, when a user submits the Form. You don't have to run it manually.
Solution:
Step 1: Install the trigger: If you haven't done so yet, install the trigger, either manually, following these steps, or programmatically, by copy the following function to your bound script and running it once:
function createOnFormSubmitTrigger() {
var ss = SpreadsheetApp.getActive();
ScriptApp.newTrigger("AutoConfirmation")
.forSpreadsheet(ss)
.onFormSubmit()
.create();
}
Step 2: Submit the form!: Once the trigger is installed, when a user submits the Form that is attached to your Spreadsheet (that is, assuming that you have attached the Form to the Spreadsheet), AutoConfirmation runs automatically, and the event object, containing these properties, is passed as an argument. If you run it manually, e is undefined (no event object is passed as parameter), and you get the error.
Note:
e.values[1] will retrieve the same value that is written to column B when the form is submitted, since JavaScript arrays are zero-indexed. You might want to use e.namedValues['yourProperty'] instead, to make sure your are retrieving the desired information.
Reference:
SpreadsheetTriggerBuilder.onFormSubmit()
Event Objects: Form submit
I am trying to document in a certain column, for each row, the user info as it is shown when using the "show edit history" option (by right-clicking a cell).
More specifically- for a given row, if the cell in column G was last modified by me- the cell in column B should say "Yaniv A" or "yaniva#emaildomain.com". Of course this should apply the same way for any other editor.
New information should replace any old in column B one anytime the coresponding cell in column G is modified.
On Apps Script you can set up an onEdit trigger that retrieves the username of the editor and cell where the change was made; but you will have to keep in mind that there may be cases where the username is not retrievable (mainly if the user haven't accepted the script scopes), you can read more about those situations on getActiveUser docs.
You can achieve what you are requesting with the following function. It will use the event object to check if the change was made on the G column, and if it was, the email of the user (or Unknown if the scopes weren't accepted) will be written on the B column of the same row.
function onEdit(e) {
var range = e.range;
var editor = e.user.getEmail();
if (editor == '' || editor == null) {
editor = 'Unknown';
}
if (range.getA1Notation().search('G') != -1) {
range.offset(0, -5).setValue(editor);
};
}
After saving this function you will have to create a installable trigger. To do so, go to Edit 🡆 Current project's triggers. After that, click on + Add Trigger and fill this settings:
Choose which function to run: onEdit
Choose which deployment should run: Head
Select event source: From spreadsheet
Select event type: On edit
Failure notification settings: as you wish
After saving the trigger you could test the function by yourself modifying a cell in the G column. Please, do not hesitate to ask for any clarification about my answer or the code itself.
I look for a solution to copy a specific cell value in the Source spreadsheet from tab "Sum all" to another Spreadsheet to the Target Spreadsheet Tab "Copy all". It should work every time i change the Value of Cell G10. Access to the Target sheet is granted before i enter any Value to G10.
(Source Tab Name is "Sum all:G10" - Sheet has 10 different Tabs)
(Target Tab Name is "CopyData:T12" - Sheet has 10 different Tabs)
Easy way
Use the built-in IMPORTRANGE() function in Google Apps:
In your Target cell, type the following formula
=IMPORTRANGE("FILE_ID_HERE","Sum all!G10:G10")
The syntax for this function is
=IMPORTRANGE("FILE_ID","SHEET_NAME!RANGE_START:RANGE_END")
When you first type in this function, you'll get an error in the cell. Simply click on it and select "Allow" to link the two sheets together. This error will occur even if it is the same spreadsheet. This function can link two separate spreadsheets, too, as long as you have edit access to both.
Hard Way
I'm assuming from your question that you want to copy values to and from the same spreadsheet document, but to different cells that are located on different sheets of the spreadsheet. The Google Apps Script API calls tabs "sheets" and the overall document "spreadsheet".
First, open the script editor
Open your spreadsheet that you'd like to make this script for.
Select "Tools" in the toolbar, then "Script Editor"
Second, make a function for onEdit.
Making a function named onEdit will create a function that runs every time the edit trigger is fired, using a no-authorization "simple trigger". Google Sheets automatically sends this event every time a cell is edited by a user. The argument e for the function is the event passed by the trigger.
function onEdit(e) {
// Get the sheet named "Sum all" from the active spreadsheet (i.e. the one you are editing)
var source = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sum all");
// Returns the active cell
var cell = source .getActiveCell();
// Compare to see if its the right cell you're looking for
// getRow and getColumn methods return integers for the row and column of the cell
// A = 1, B = 2, ... G = 7
if (cell.getRow() == 10 && cell.getColumn() == 7) {
// If its the right cell, copy to the other cell
var target = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("CopyData");
// set the value of the desired cell in the target sheet
target.getRange("T12").setValue(cell.getValue());
}
}
Third, save the script
Save the script, reload the file, and test it out.
If your tabs are on different spreadsheets
Change this line:
var target = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("CopyData");
to this:
var target = SpreadsheetApp.openById("FILE_ID").getSheetByName("CopyData");
and insert the file ID for the target spreadsheet where I've written FILE_ID.
You will also need to use an "installed trigger", since a simple trigger cannot open a remote spreadsheet. To do this, change the name (so it is no longer a simple trigger function), and follow the steps here