Google spreadsheet and conditional checkbox - google-apps-script

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.

Related

How to round a cell after user input in Google Sheets?

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

Refresh a filter onEdit() in Google sheets when number is less than x

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

Input datetime when double click on a cell

I have 6 columns in google sheet doc.
(A) Date (B)Order (C)ID DEPARTMENT (D)Time sent (E)Time received (F)Delivery time
I want each time I double click column a cell under Time Sent or Time received columns - current date and time is inputted.
Date and time should stay forever (like the time of double click).
Can you please help me to create this code?
Explanation:
There is no doubleClick event in Google Apps Script.
However, you can use onSelectionChange to capture single click events.
The following script will set the value of a cell in column D or E with the current datetime upon a single click.
To prevent a cell from being updated after you selected again, you can add an extra condition to set values only when the selected cell is empty. If the cell has already a date in it, then don't update it. In this way, the original/first datetime will remain intact.
Solution:
function onSelectionChange(e) {
const as = e.source.getActiveSheet();
const row = e.range.getRow();
const col = e.range.getColumn();
if (as.getName() == 'Sheet1' && row>1 && [4,5].includes(col) && e.range.getValue()==''){
e.range.setValue(new Date());
}
}
To use this solution, simply copy & paste it to the script editor and save the changes. After that, it will automatically be used upon single click events. In this solution I used Sheet1 as the sheet name. Feel free to change that according to your specific case.

Fill cell based on another sheets value

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:

How to fix this error in programmatically (with trigger) active() the last occupied row in a Google sheet?

Supose you have a sheet with several hundred rows long. You could to this to go to the last row and start your work:
1) after opening the spreadsheet, do Ctrl End; Ctrl leftArrow; Ctrl
upArrow
this will take you to the last occupied row cell in column A 2) before closing the spreadsheet, select the last occupied cell in
column A and assign it range name endRow then when you open the
spreadsheet do Edit > Named ranges then click on endRow this will take
you to the last occupied row cell in column A;
I just find a way to programmatically implement this, it's really simple, but worked only in the oldspreadsheet. I just put this line inside onOpen() trigger and just works fine: activeSheet.getRange(activeSheet.getLastRow(), 1).activate();.
But it didn't work in the new Google Sheets (a new one with some thousands of rows).
So, I tried the Zig advice, write this function:
function goToLastRow() {
var s = SpreadsheetApp.getActiveSpreadsheet();
var range = s.getRange(s.getLastRow()+1, 1);
range.activate();
}
And set the trigger manually (Script Editor>>Resources>>Triggers from this project>>Ad new trigger). But it still didn't work.
Any suggestion?
I found this way to accomplish what you need:
function onOpen() {
var sheet = SpreadsheetApp.getActiveSheet();
sheet.hideRows(1,sheet.getLastRow());
}
This hides all rows with data from the active sheet, places the cursor on the next (empty) row, so you can start typing away.
when done with the row, simply click the little triangle to the left of the hidden rows, and they will reappear if you need so.
Might cause problems if more than one person enters new rows at the same time.
★ Here is another cool way to accomplish this without any scripting, plus works even with simultaneous users (the script version above could hide a row being entered if another person opens the spreadsheet with edit permissions.)
This 2nd no-script solution will only work if your data has a column with a fixed set of values (¹), for example a column with only the possible values 'pending', 'doing' and 'done'. So find such column, which I assume its on column 'A' in this example.
➮ Lets use "Filter Views" in the "Data" menu (only in the new sheets versions.)This feature allows for personalized filters that only the user applying them sees. Create a filtered view called "Enter new rows mode" with no values checked for column 'A' (click filter:"clear" when you drop-down the column filter menu).
➮ Now, when you enter the spreadsheet, the filtered view is applied automatically and all rows with data will go away.Start typing away. If other users start entering new rows, your row only goes away for them, not for you until you refresh the browser window.
➮ If other users remove the filtered view, its removed only for them, not for you.
You can also do something similar with the "old" filters but it has the same dissadvantage as the script solution regarding multiple users.
*¹ A fixed set of values is needed because the spreadsheet filters automatically add new items as checked in the view. You cant use a date column because you will always get new future values.To configure the filter you need to already have at least one row per possible value, so that you can uncheck them in the column filter.If new values are later entered, you need to edit the view to uncheck it.
I just find the way, it's really very simple, just put this line inside onOpen() trigger and just works fine: activeSheet.getRange(activeSheet.getLastRow(), 1).activate();.
But it didn't work in the new Google Sheets.
So, I tried the Zig advice, write this function:
function goToLastRow() {
var s = SpreadsheetApp.getActiveSpreadsheet();
var range = s.getRange(s.getLastRow()+1, 1);
range.activate();
}
And set the trigger manually (Script Editor>>Resources>>Triggers from this project>>Ad new trigger).
Any suggestion?
Change getActiveSpreadsheet to getActiveSheet. The spreadsheet is all the file, a sheet is just a sheet :P. But you will find that you cant go to any part of a spreadsheet in an onOpen trigger.
The best way is to create a menu for this.
At the end the code goes like this:
function onOpen() //the same to create a onOpen trigger
{
SpreadsheetApp.getUi().createMenu("Go to").addItem("Last Row", "goToLastRow").addToUi();
}
function goToLastRow() {
var s = SpreadsheetApp.getActiveSheet();
Logger.log(s.getLastRow());
var range = s.getRange(s.getLastRow()+1, 1);
range.activate();
}