Wants to achieve the same feature with Google Sheets as explained here with MS Excel (https://www.youtube.com/watch?v=5GLjQNeiEeU)
Only use column A
1st Row = Header (Cell A:1)
2nd Row (Cell A:2) should always be the cell that one enters data into.
When you type data and press Enter, the data should move down to Cell A:3 and Cell A:2 should be
empty again in order to accept the next data input, etc.
Can anyone please assist with a basic script?
Many Thanks
UJ Library
You need to create Apps Script that will handle an event such as editing sheets and use the Event Object to determine which cell is being edited.
Events can be catch using Triggers. Triggers let Apps Script run a function automatically when a certain event, like editing a sheet, occurs.
Event Object contains information about the context that caused the trigger to fire.
Example:
Code:
function onEdit(e){
var range = e.range;
if(range.getA1Notation() == "A2"){
//Move A2 value below
range.insertCells(SpreadsheetApp.Dimension.ROWS);
//set A2 as active cell
range.activate();
}
}
Before:
After pressing Enter:
References:
Simple Triggers
Event Object
range.activate()
range.insertCells(shiftDimension)
Related
I have a Google Form that is connected to a Google Spreadsheet. I noticed that if I decide to manually write something on this Google Spreadsheet, the order of entry is not preserved during future responses.
For example: Assume there are 3 rows each with a Google Form response and I manually write something in the 4th row. The next time there is a Google Form response, the spreadsheet will show the new response in the 4th row, and move my manual input to the 5th row.
I was wondering if there was anyway to get the new responses to show up below any manual inputs so that the order is preserved. (Have 3 rows with Google form data, the 4th row with the manual input, and 5th row with the Google Form response.)
You can create an onFormSubmit Trigger that will check if there is a manual input in the spreadsheet by comparing the last row and the response row. If the response row is not equal to the last row, it means a manual input has been made and we move the response to the last row.
Go to Tools -> Script editor and paste the code below:
function moveToLastRow(e) {
var sheet = e.range.getSheet();
var lastRow = sheet.getLastRow();
var row = e.range.getRow();
var data = e.values;
if(lastRow != row){
sheet.deleteRow(row);
sheet.appendRow(data);
}
}
Create an onFormSubmit Trigger:
Open your Apps Script project.
At the left, click Triggers alarm.
At the bottom right, click Add Trigger.
Select and configure the type of trigger you want to create.
Click Save.
For this case, copy these configurations:
Output:
References
Event Object
Installable Trigger
Class Sheet
I have a cell (G7) that is dynamically linked to a website with importHTML, and it has number that is updated periodically. Is there a way to store the current value of that dynamic cell and add it to another cell, and the keep doing that every time it changes?
Cell G7 is my dynamic number and Cell E2 where I want to keep appending changes to G7. So if right now G7 is $16.28, I want to store that in E2, and then let’s say a few months from now G7 updates to $14.5, then I want it to add $14.5 to the $16.28 in cell E2 rather than replace it. So the new number upon updating G7 should be $30.78. Would I have to make another tab and store each iteration of G7 into a list and add them together with SUM in E2? How can I store the number in G7 when certain conditions are met use dates from cells C7, H7, and I7 automatically?
An example of a date condition being if C7<= H7, and I7 is equal to Today's date then append this number from G7 to E7.
Is there another way of doing this without making a history list in another sheet? In a scripting language I think this would be written as E2+=G7. While G7 is constantly changing it is being appended to E2.
Here is a Demo I made of the sheet im working on.
https://docs.google.com/spreadsheets/d/1Wk1kMGeZuVEcSdsnXnGIzdwPHLqYKoyqlD1yYcGXxXs/edit?usp=sharing
Simple Trigger onEdit(e) runs when a user changes a value in a spreadsheet
The onEdit event trigger has an object passed by parameter that you can use depending on the Google Product used, for instance, Spreadsheet events, where the e.source object represents the Google Sheets file to which the script is bound.
For example:
function onEdit(e){
// Set a comment on the edited cell to indicate when it was changed.
var range = e.range;
range.setNote('Last modified: ' + new Date());
}
By having the code above, when a change is made to a single cell, this code runs and sets a note every time the cell is changed/saved.
This is my first go at creating something in Apps Script for Google Sheets and I'm a bit stuck/overwhelmed. In the reading I've done I think what I'm attempting is rather basic. I'm just not getting to the solution, so I need a nudge...
Need:
I have a sheet that is tracking equipment that is checked out and returned to a central area.
The sheet has multiple pages with identical layouts.
On each page I have one column where (3) different options can be chosen from a dropdown list.
IN, OUT, and UNAVAILABLE
For each of the (3) entry options, I would like a popup message to appear when the entry is changed.
So in the range of F2:F100, if the entry is changed to "OUT" from "IN" I would like a pop-up to appear with a message of "Clear all fields to the right." and an "OK" button.
I have found a lot of examples to make a pop up when ANY field is changed, or when a sheet is opened. I'm stuck on limiting these pop-ups to only select fields/ranges/pages
Thank you all for the help.
SOLUTION
You can refer to this sample script below that runs via onEdit trigger, where the pop-up message will only run if any selected cell is under column F & if that cell's value was changed to "OUT" on any sheet on a spreadsheet file:
function onEdit() {
var ss = SpreadsheetApp.getActive();
//Check if selected cell is in column F (or col #6) was changed to "OUT"
if(ss.getActiveCell().getColumn() == 6 & ss.getRange(ss.getActiveCell().getA1Notation()).getValue() == "OUT"){
SpreadsheetApp.getUi().alert('Clear all fields to the right.');
}
}
If ever you need to add more conditions like if you only want to run the script to a specific sheet name, you can add ss.getSheetName() == '[Name of the sheet]' on the if condition separated by & sign, as seen on the sample below:
if(ss.getSheetName() == 'Sheet2' & ss.getActiveCell().getColumn() == 6 & ss.getRange(ss.getActiveCell().getA1Notation()).getValue() == "OUT"){
SpreadsheetApp.getUi().alert('Clear all fields to the right.');
}
Sample Result:
If a selected cell on col F is changed from IN to OUT via a drop-down option:
A pop-up message "Clear all fields to the right." will show on the sheet
I'm using arrayformulas to populate certain columns of my sheet, depending on values in other sheets. Occasionally users accidentally will put some value in these columns, and this will stop arrayformula from working. I want to protect these columns, but still allow adding/editing/deleting rows.
Consider this example spreadsheet: I want Id row to be protected, but allow addition/deletion of rows.
https://docs.google.com/spreadsheets/d/1Dnj7OE5XZL09gllHVwPgv-5GRoM-lxVCxTCI_-kURdM/edit#gid=0
Is this possible at all with Google Sheets?
You can't directly disable input but you can use Data Validation instead
By going to Data > Data Validation and filling it with the following:
Cell range: YourSheet!C2:C
Criteria: Custom formula is - =C2:C = A2:A & "["&B2:B&"]"
On invalid data: Reject input
Appeareance: Optional message
Once you've done this, try to fill some cell in the C column and you'll see a message: There was a problem - Your optional message
As a different approach you can use Apps Script Simple Triggers
By going to Tools > Script Editor and copying the following code:
function onEdit(e) {
var column = e.range.getColumn();
var sheet = SpreadsheetApp.getActiveSheet();
if (column === 3) {
e.range.setValue("");
}
}
Which is more like an "undo" function.
References
Simple Triggers
Event Objects > onEdit
rows could be added by brute force with this formula:
=ARRAYFORMULA(ROW(INDIRECT("1:"&ROWS(A:A)+1)))
but escalation cant be controlled
I have the following simple list in a sheet named "Pipeline":
Whenever a date is entered in column E, those dates get formatted in another sheet named "Calendar" (same document), where I have a calendar that looks like this:
This is the conditional formatting formula: =match(B1,indirect("Pipeline!E:E"),0)
To this point, all good.
Now, when I am in "Calendar", I would like to output the topic from sheet "Pipeline" respective to the date I mouseover, or I select.
For example, if I now select cell V16 in "Calendar", which corresponds to date "18 Jun", I need "Retargeting for Ho" (value of cell A10 in sheet "Pipeline") to be output somewhere.
I don't quite care how. It may be a cell in the the Calendar sheet, or mouseover. Really, the output format is not that necessary.
Hope someone can help.
Thanks in advance.
A.
Approach
This behavior is achievable through an event programming technique. In Google Sheets you can trigger functions based on these events:
Document open
Document edit
Document selection
For this purpose you can use the onSelectionChange(e) function. A handler for the Document selection event.
To handle these events you will need an Apps Script project. You can easily bound one to your Spreadsheet going to Tools>Script Editor.
Output representation
I think that on Google Sheets you can benefit of the Note UI representation to show the wanted information based on the selected cell content.
Code:
Here is an example on how to handle the selection event to append a Note UI element to the selected cell:
function onSelectionChange(e) {
let date = e.range.getValue().toString(); // I will explicitly cast the date object to string to ensure the comparison will work
let range = e.range; // This will return a range of exactly one cell: The selected one
let ss = SpreadsheetApp.getActiveSpreadsheet();
let pipeline = ss.getSheetByName('Pipeline');
let pipelineRows = pipeline.getDataRange().getValues(); // I will load all the Pipline table in a multidimensional array to get the title information
let title = pipelineRows.filter(row => row[5].toString() == date).map(row => row[1]); // I will filter the Pipeline Rows by date and extract the title
range.setNote(title); // Finally I will append the extracted title to a note in the selected cell.
}
Reference
Triggers
Event Object
SpreadsheetApp