In this sample Google Sheet that you can edit, I'm trying to configure the data validation dropdown menus in B2:B to only display when the adjacent cells in A2:A have data in them. As you can see in my spreadsheet, I have the data validation configured alright, but it inserts dropdown menus all the way down column B, even if there's no data next to it in Column A, and I don't want that.
How can I configure this to where Data Validation dropdown menus only display when there is data in adjacent cells in column A?
Thanks for your help!
You need a script
function onEdit(event){
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if (r.getColumn() == 1 && s.getName() == 'Dropdowns'){
r.offset(0,1).clearContent()
if (r.getValue() == ''){
r.offset(0,1).clearDataValidations();
}
else{
var lists = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Colors');
r.offset(0,1).setDataValidation(SpreadsheetApp.newDataValidation()
.setAllowInvalid(true)
.requireValueInRange(lists.getRange('A2:A'+lists.getLastRow()), true)
.build());
}
}
}
My work has a Google Form where different information is inputted. All this information is then automatically put into a Google Sheet. We will call it "All data sheet".
"All data sheet" has multiple sheets in it, one with all of the data and then one for each type of data which needs to be given to different people. One of those is called 'Caretaker'.
I then have a second Google Sheet (example called 'Sorting') that pulls everything from the 'Caretaker' sheet onto 'Import_range'.
This allows the caretaker to see everything that needs fixing with the oldest thing at the top and the newest at the bottom.
The caretaker would like the newest at the top.
I can easily make another sheet (see 'Sorted') that uses the sort function to put the newest at the top.
However, he would also like another column where he can either check a box to show it's done or write an x.
When new data appears, the checked box does not move down.
Is there any way to sort the data but also have an input column which stays with the sorted data?
Link to example.
You have to use Google Apps Script.
Try this:
To start, go to Tools and click Script editor.
Delete the code in Code.gs
Paste the code provided below and save
Refresh your Spreadsheet and Custom Menu will pop up in the Menu
Go To Custom Menu and Click Update Sorted Sheet
First execution will require user's authorization. Once you authorized the script, make sure to rerun the Custom Menu.
The code below will create a Custom Menu in your Spreadsheet. Clicking the custom menu will execute a function that will update the Sorted Sheet and retain its checkbox values.
I also added comments to explain the function of each line in the code.
Code:
function updateSorted() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getSheetByName("Import_range");
var sortedSh = ss.getSheetByName("Sorted");
/* Use this if the Import_range is from different spreadsheet
var iSS = SpreadsheetApp.openById("Insert Sheet ID here");
var sh = iSS.getSheetByName("Insert Sheet name here");
and comment the var sh = ss.getSheetByName("Import_range"); above*/
/*
Check if the Sorted Sheet has data.
If true, compare Sorted Sheet and Import_range data
else, copy Import_range data to Sorted Sheet.
*/
if(sortedSh.getLastRow() > 1){
var sData = sortedSh.getRange(2, 1, sortedSh.getLastRow()-1, 5).getValues(); //remove unnecessary data
var sDataFiltered = sData.filter(e => e[4]); //get Date column of Sorted sheet
var sDates = sortedSh.getRange(2, 5, sortedSh.getLastRow()-1, 1).getValues().flat();
var sDatesFiltered = sDates.filter((a) => a); //remove unnecessary data
var importDates = sh.getRange(2, 4, sh.getLastRow()-1, 1).getValues().flat(); //get Date column of Import_range
//convert dates to String format
var arr1 = sDatesFiltered.map( dateString => String(dateString))
var arr2 = importDates.map( dateString => String(dateString))
var difference = arr2.filter(x => !arr1.includes(x)); //get the difference between arr1 and arr2
difference.forEach(dates => {
var index = arr2.indexOf(dates); //get new entry position in Import_range
var newEntry = sh.getRange(index+2, 1, 1, 4).getValues().flat(); //get row data of new entry from Import_range
newEntry.unshift(false); //append false in the beggining of the array
sDataFiltered.push(newEntry); //append new entry to sDataFiltered array
})
var range = sortedSh.getRange(2, 1, sDataFiltered.length, 5);
range.setValues(sDataFiltered); //set the values of Sorted sheet using the sDataFiltered array as data
sortedSh.getRange(2, 1, sDataFiltered.length, 1).insertCheckboxes(); //get the checkbox range and insert checkbox
range.sort({column: 5, ascending: false}); //sort the data by Date column
}else{
var range = sh.getRange(2, 1, sh.getLastRow()-1, 4);
var data = range.getValues();
data.forEach(row => {
row.unshift(false)
})
var sortedRange = sortedSh.getRange(2, 1, data.length, 5);
sortedRange.setValues(data);
sortedSh.getRange(2, 1, data.length, 1).insertCheckboxes();
sortedRange.sort({column: 5, ascending: false});
}
}
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Custom Menu')
.addItem('Update Sorted Sheet', 'updateSorted')
.addToUi();
}
Examples:
Populating Empty Sorted Sheet:
Updating Import_range sheet, clicking checkboxes and updating Sorted Sheet:
Implementing Time Driven Triggers:
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 time driven, your trigger setup should somehow look like this:
The example trigger above will update the sheet every minute. The down side of using time driven trigger is the quota limit. Gmail accounts are limited to 90 minutes of total runtime. Exceeding quotas will result to errors. See Quotas for Google Services.
Using Buttons: Alternative to Custom Menu
To create a user friendly button in your Sheet
Go to Insert -> Drawing
Draw the desired button shape and style.
Click Save and Close
Move the button to your desired position
Right click, click the 3 vertical dots and select Assign script
Type updateSorted and click OK
Click the button to run
Note: If you decided to use buttons and want to remove the Custom Menu in your sheet, just remove the onOpen function in your Apps Script.
References:
Google Apps Script on Sheets
Custom Menu
Simple Triggers
Class Sheet
Class Range
Class Spreadsheet
Installable Trigger
I have a form that has a Question that depending upon an answer will direct you to futher questions. The problem is, once you submit the form and then go back and edit your answer, if you choose another answer for the first question and it redirects to a new question because your first answer was different, the response in Google Sheets keeps both answers. How can I fix this so that it only shows the last answers? For example. When I first answer the question, I choose Option 1.
Then when I choose next I get these options.
Which once I submit will give the following response submission in Sheets.
Ok, so then if I go back and Edit my response like so...
It will redirect to a different question based on my first choice.
However, once I submit my final answer, this is what the subission looks like in Sheets.
The problem is, Column C and D answers are no longer relevant based upon the answer in Column B. How can I fix this so that Column C and D are blank as they should be and I only get the answer that is correct based upon the submission in Forms?
Thanks!
You can create a bound script in your Google Sheets with a Form Submit trigger.
Sample Code:
function formSubmission(e) {
Logger.log(JSON.stringify(e));
Logger.log(e.values);
var data = e.values;
var row = e.range.rowStart;
var sheet = SpreadsheetApp.getActive().getSheetByName('Form Responses 1');
if(data[1]=="Option 1"){
//Remove data under Follow-up Question2 and Amount 2 (Column E and F)
sheet.getRange(row,5,1,2).clearContent();
}else if(data[1]=="Option 2"){
//Remove data under Follow-up Question1 and Amount 1 (Column C and D)
sheet.getRange(row,3,1,2).clearContent();
}
}
Pre-requisite:
What it does?
Get the form submitted values using Sheets form submit event object values
Get the form submitted target row using range.rowStart
Get the active spreadsheet and sheet with the name Form Responses 1
Check the Option selected and delete specific columns depending on the option selected.
Output:
Here's how I finally was able to do what I needed Ron M's help:
function formSubmission(e) {
Logger.log(JSON.stringify(e));
Logger.log(e.values);
var data = e.values;
var row = e.range.rowStart;
var sheet = SpreadsheetApp.getActive().getSheetByName('Form Responses 1');
if(data[4]=="Debit"){
sheet.getRange(row,7,1,1).clearContent();
}else if(data[4]=="Credit"){
sheet.getRange(row,6,1,1).clearContent();
}
if(data[7]=="INCOME"){
sheet.getRange(row,10,1,14).clearContent();
}else if(data[7]=="HOME"){
sheet.getRange(row,9,1,1).clearContent();
sheet.getRange(row,11,1,13).clearContent();
}else if(data[7]=="LIVING"){
sheet.getRange(row,9,1,2).clearContent();
sheet.getRange(row,12,1,12).clearContent();
}else if(data[7]=="TRANSPORTATION"){
sheet.getRange(row,9,1,3).clearContent();
sheet.getRange(row,13,1,11).clearContent();
}else if(data[7]=="HEALTH"){
sheet.getRange(row,9,1,4).clearContent();
sheet.getRange(row,14,1,10).clearContent();
}else if(data[7]=="INSURANCE"){
sheet.getRange(row,9,1,5).clearContent();
sheet.getRange(row,15,1,9).clearContent();
}else if(data[7]=="EDUCATION"){
sheet.getRange(row,9,1,6).clearContent();
sheet.getRange(row,16,1,8).clearContent();
}else if(data[7]=="CHARITY/GIFTS"){
sheet.getRange(row,9,1,7).clearContent();
sheet.getRange(row,17,1,7).clearContent();
}else if(data[7]=="SAVINGS"){
sheet.getRange(row,9,1,8).clearContent();
sheet.getRange(row,18,1,6).clearContent();
}else if(data[7]=="OBLIGATIONS"){
sheet.getRange(row,9,1,9).clearContent();
sheet.getRange(row,19,1,5).clearContent();
}else if(data[7]=="ENTERTAINMENT"){
sheet.getRange(row,9,1,10).clearContent();
sheet.getRange(row,20,1,4).clearContent();
}else if(data[7]=="PETS"){
sheet.getRange(row,9,1,11).clearContent();
sheet.getRange(row,21,1,3).clearContent();
}else if(data[7]=="SUBSCRIPTIONS"){
sheet.getRange(row,9,1,12).clearContent();
sheet.getRange(row,22,1,2).clearContent();
}else if(data[7]=="VACATION"){
sheet.getRange(row,9,1,13).clearContent();
sheet.getRange(row,23,1,1).clearContent();
}else if(data[7]=="MISCELLANEOUS"){
sheet.getRange(row,9,1,14).clearContent();
}
}
I am trying to display a browser message box based on a particular value in range. I tried with the following
function onEdit(e){
var sheet = SpreadsheetApp.getActiveSheet();
var panType = sheet.getRange("A4:A100").getValues();
if (panType=="CSF");
Browser.msgBox('Make sure you enter the PAN No in the alloted slot');
}
But the problem is, with each and every edit in any cell, the message box pops up.
The said range A4:A100 has a validation dropdown with options like "New" and "CSF". So whenever the value CSF is chosen, the dialogue box should popup.
Thanks
You just need to check if it is the xorrect sheet, column, and value. Event has these values. If they match, show your messagebox.
function onEdit(event){
var sheet = event.source.getActiveSheet().getName()
var editedCell = event.range.getSheet().getActiveCell();
if(sheet=="Sheet1"){
if(editedCell.getColumn() == 1 && event.value=="CSF"){
Browser.msgBox('Make sure you enter the PAN No in the alloted slot');
}}}
I would like to copy (Not move) the entire row to another sheet when there is a specific word in a cell.
I have a sheet named "List" with 7 columns, in the the 7th column I put notes for each row. Every time I write the word "Lead" in that column, I would like that entire row to be copied to another sheet named "Opportunity". Please note that the word "Lead" will be followed by other words in that cell, example: "Lead, wants tree removed and landscaping service". So its not a single value.
Thank you very much for the help.
You can create your custom function for this.
Steps:
Tools-> Script editor.
For example write:
function myFunction(input) {
return input;
}
Go to Resources -> Triggers of current project -> Add trigger
Choose your function name (myFunction), from table, changes then save
In Google sheet cell write for example
=myFunction(A1)
and change A1 cell. You will get changes.
Code of working function that copy cells value if they have word "Lead" :
function myFunction(input) {
var array = [''];
if(typeof input != 'object') {
return array;
} else {
for (var name in input) {
for (var name2 in input[name]) {
if(input[name][name2].toString().indexOf('Lead') != -1) {
array.push(input[name]);
}
}
}
}
if(array.length > 1) {
array.splice(0, 1);
}
return array;
}
Usage. In second sheet (Opportunity) past in any cell:
=myFunction('List'!A1:G50)
Here is link with working formula.
This should be possible with QUERY(). Assuming the source sheet is 'Sheet1', in sheet 'Opportunity' enter in A1:
=QUERY('Sheet1!A1:G', "where G contains 'Lead'", 1)
Change sheet name and ranges to suit.