I have a real estate office that uses google sheets to show address, buyer name, realtor name, and seller name. For the realtor name column I created a dropdown so they can select from a list of names. What I need to do is be able to update that list range when a new name is entered into the dropdown. For example if a new realtor lists a property and their name is not in the list the person entering the info just has to type it in the dropdown and the list will automatically update for next time.
Thank you
With the following script, if name is not listed in the dropdown list, then the user can enter their name in the dropdown and this will add the name to the list of names.
function script2(e) {
var s = SpreadsheetApp.getActiveSpreadsheet();
var sht1 = s.getSheetByName('2022'); //sheet where you have the dropdown
var sht2 = s.getSheetByName('Realtors'); //sheet where you have the list of names
var range = sht2.getRange('A:A'); //range for the list of names
var columnP = 16;
var columnQ = 17;
//get value of active cell if active cell is within columns P or Q
if (e.range.getColumn() === columnP || e.range.getColumn() === columnQ){
var cellValue = sht1.getActiveCell().getValue();
var result = hasValue(range, cellValue);
}
//if value is not found then it will add name to the list
if (result == false){
sht2.getRange('A2').getNextDataCell(SpreadsheetApp.Direction.DOWN).offset(1,0).setValue(cellValue);
}
else{
}
}
//this function searchs a value in a range
function hasValue(range, value) {
return range.getValues().flat().includes(value);
}
Related
Suppose I have a Google Sheet where columns A:G are dropdown lists.
I would like to add an option to lock choices in columns A:G using a checkbox in column H, where checking the box in this column will lock columns A:G so they can not be edited (unless the checkbox in column H is de-selected).
Is it possible to do this on Google Sheets?
I have created the following script that is based on a previous script I found in a response here in StackOverflow a long time ago.
function onEdit(e)
{
var editRange = {
top : 1,
bottom : 1000,
left : 2,
right : 2
};
var cell = e.range;
// Exit if we're out of range
var thisRow = cell.getRow();
if (thisRow < editRange.top || thisRow > editRange.bottom) return;
var thisCol = cell.getColumn();
if (thisCol < editRange.left || thisCol > editRange.right) return;
var val1 = e.range.getRow();
var val2 = e.range.getColumn();
var validation = SpreadsheetApp.getActive().getSheetByName("Testing Sheet").getRange(val1, val2-1);
if(cell.isChecked()){
var rule = SpreadsheetApp.newDataValidation().requireValueInList(['Red', 'Blue']).build();
}
else{
var rule = SpreadsheetApp.newDataValidation().requireValueInList(['Black', 'White']).build();
}
validation.setDataValidation(rule);
}
I modified the range at the beginning so it only recognizes the change in column B, but you can just change it to 8 for column H. Since the script uses an onChange trigger, what you need to validate first is if the edit was made in the range where the checkboxes are, then I set the range of the cell that I was going to change based on the value from the checkbox and created the data validation rule with the expected values depending on the conditional.
In your case you can just add the rest of the ranges for the other columns with more validation variables and change the column parameter to -2, -3, or -4 depending on the cells you will be editing for example, and then create more validation rules according to the data you need in the dropdowns.
Here is an example of how this would work:
References:
onEdit()
Data Validation
need some help with script on google sheets
I'm having some issues to try to use "setVisibleValues" and I got an error saying "Exception: Visible values are not currently supported. As an alternative specify a list of hidden values that excludes the values that should be visible.". But my problem is, I've a huge number of employee names on a list, and I wanna filter just based in one person.
I cant show some information, but the thing is: "I just wanna filter one value, and I don't know how to do it using "setHiddenValues".
function Filtersheet() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange('A3:S').activate();
spreadsheet.getRange('H3').activate();
var criteria = SpreadsheetApp.newFilterCriteria()
.setHiddenValues([''])
var criteria = SpreadsheetApp.newFilterCriteria()
.setVisibleValues(['tayzer'])
.build();
spreadsheet.getActiveSheet().getFilter().setColumnFilterCriteria(8, criteria);
}
Lets say that the names of the Employees are : jorge, lucas, nuno, fernando, marta, beatriz, tayzer, larissa, and I wanna use the filter script to only show on the column the information related to tayzer
But my way to change the filter employee will be on a cell outside the script (cause I've around 200 employees)
Thanks in advance for the help
try this
function setFilter() {
// replace 'sheet name' with you sheet
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('sheet name');
var range = ss.getDataRange();
var filter = range.getFilter() || range.createFilter()
var criteria = SpreadsheetApp.newFilterCriteria().whenTextContains('tayzer');
filter.setColumnFilterCriteria(8, criteria);
}
if i am not wrong if you put "jorge" in cell_C4 you want it to filter "jorge" in column E, if so try below code.
function setFilter() {
// replace 'sheet name' with you sheet
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('sheet name');
var range = ss.getDataRange();
var filter = range.getFilter() || range.createFilter()
var criteria = SpreadsheetApp.newFilterCriteria().whenTextContains(ss.getRange('C4').getValue()).build();
filter.setColumnFilterCriteria(8,criteria)
}
I have a workbook that I am working on for our company and need a little help on this one. Normally I can figure things out pretty easy. In my worksheet there are several tabs the ones I am working with now are NEW, In Progress, On Hold, Scheduled and Complete. Permits are added to the New tab Via google form input, what I would like to happen that when the status changes in Column K is that it goes to the corresponding tab. I had this all set up in Excel but we are no longer allowed to use Excel at work. TK's Daily Production Any help would greatly be appreciated
In sheet, click Tools > Script Editor.
Paste below code. This code assumes Column K has header 'status' and this column values have corresponding tabs = sheets in Spreadsheet. As an example, if Column K has value 'NEW', there must be a tab named 'NEW'. If you edit value in this column, say from 'NEW' to 'Complete', that row will be copied to 'Complete' tab and optionally deleted from 'NEW' tab if corresponding code is activated.
// onEdit trigger
function onEdit() {
moveToTab();
}
function moveToTab() {
// active SS
var ss = SpreadsheetApp.getActiveSpreadsheet();
// active cell/range
var range = ss.getActiveRange();
// active column
var col = range.getColumn();
Logger.log(col);
// active sheet
var aSheet = ss.getActiveSheet();
// get active column header
var header = aSheet.getRange(1,col,1,1).getValue();
Logger.log(header);
// here i assume, Column K has a header 'status'
// change 'status' string to what you have as Column K header
// if column is not 'status', do nothing
if (header.toLowerCase() !== 'status') return;
// get value
var target = range.getValue();
// trim and check there is a value
if (target.toString().trim() === '') return;
// do nothing if same sheet
if (target.toString().toLowerCase() === aSheet.getName().toLowerCase()) return;
// try {
// try move
// target sheet based on Column K value
var sheets = ss.getSheets();
var tSheet = sheets.filter(function(sheet) {
if (sheet.getName().toLowerCase() == target.toLowerCase()) return true;
else return false;
})[0];
if (!tSheet) return;
// active cell row
var row = range.getRow();
// get active row values
var values = aSheet.getRange(row, 1, 1, aSheet.getLastColumn()).getValues();
// append values to target row
tSheet.appendRow(values[0]);
// optionally delete row from old sheet
// un-comment if required
aSheet.deleteRow(row);
// } catch(e) {}
}
Project description: Begin with a roster spreadsheet with multiple tabs (one for each group), each tab with a list of members for rows. Columns are rehearsal or program dates. Second sheet contains scanned attendance records. Open the attendance record sheet and read each record. One column contains tab name of sheet on the roster sheet. Change to that sheet and search for the scanned member. Mark the column matching the date with an X to denote attendance. Mark the scanned attendance record with an X to denote processed.
Everything is working save the final writing of the X to the sheet opened by ID. I can't figure out the syntax to update the appropriate row/col cell.
I'd appreciate some help. Thanks!
function processAttendanceRecords(){
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var ss = SpreadsheetApp.openById("1234567");
var data = ss.getDataRange().getValues();
for (var i = 1; i < data.length; i++) {
var rhrsDate = Utilities.formatDate(data[i][3], "PST", "M/d");
sheet.setActiveSheet(sheet.getSheetByName(data[i][1]));
var members = sheet.getDataRange().getValues();
var col = members[0].indexOf(rhrsDate);
for (var j = 1; j < members.length; j++) {
if (data[i][6] == members[j][0] && data[i][7] == members[j][1]) {
SpreadsheetApp.getActiveSheet().getRange(j+1,col+1).setValue('X');
SpreadsheetApp.getActiveSheet(ss).getRange(i+1,9).setValue('X');
}
}
}
}
If you are accessing spreadsheet by ID then it is good practice to mention the sheet name or else it will take the first sheet by default.
var ss = SpreadsheetApp.openById("123456").getSheetByName("Sheet1");
Since you haven't defined the sheet name you can't use getRange(Row, Column). So your need to mention the sheet name like above and then change the last line.
ss.getRange(i+1,9).setValue('X');
I'm trying to create a dynamic HYPERLINK formula that will automatically create the link based on the sheet name in Column A, but I'm not sure how (or if it's possible) to get the URL of the sheet based on the name.
Here's the setup:
Single Google Spreadsheet with multiple tabs
Tab names: 1500, 1501, 1502, Consolidated
On the Consolidated tab, I have two columns: Column A is the Sheet Name, and Column B is a HYPERLINK formula, that when clicked should open the corresponding sheet.
Is there a way to programmatically get the URL for the sheet based on the sheet name in Column A? Perhaps I could use a script to populate Column C with the URL, then use the following formula: =HYPERLINK(C2,A2)?
Thanks for the help!
Surprised to see this as a top search on Google but with no answer.
Anyway, here's the method I found that works for me: combine Hyperlink with values from a different column using the &, a basic example is shown below:
If you are trying to automatically generate direct URL's to specific sheets based on their name, and do not want to use scripts, you are out of luck. Currently, the only way to link directly to specific sheets is by appending the correct gid number to the spreadsheet URL. A gid must be either copied manually from the active sheet's URL, or automatically extracted with a custom function, created using scripts.
Since you're open to using scripts, it looks like i found a detailed tutorial of how to do this. https://www.benlcollins.com/spreadsheets/index-sheet/
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Index Menu')
.addItem('Create Index', 'createIndex')
.addItem('Update Index', 'updateIndex')
.addToUi();
}
// function to create the index
function createIndex() {
// Get all the different sheet IDs
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
var namesArray = sheetNamesIds(sheets);
var indexSheetNames = namesArray[0];
var indexSheetIds = namesArray[1];
// check if sheet called sheet called already exists
// if no index sheet exists, create one
if (ss.getSheetByName('index') == null) {
var indexSheet = ss.insertSheet('Index',0);
}
// if sheet called index does exist, prompt user for a different name or option to
cancel
else {
var indexNewName = Browser.inputBox('The name Index is already being used,
please choose a different name:', 'Please choose another name',
Browser.Buttons.OK_CANCEL);
if (indexNewName != 'cancel') {
var indexSheet = ss.insertSheet(indexNewName,0);
}
else {
Browser.msgBox('No index sheet created');
}
}
// add sheet title, sheet names and hyperlink formulas
if (indexSheet) {
printIndex(indexSheet,indexSheetNames,indexSheetIds);
}
}
// function to update the index, assumes index is the first sheet in the workbook
function updateIndex() {
// Get all the different sheet IDs
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
var indexSheet = sheets[0];
var namesArray = sheetNamesIds(sheets);
var indexSheetNames = namesArray[0];
var indexSheetIds = namesArray[1];
printIndex(indexSheet,indexSheetNames,indexSheetIds);
}
// function to print out the index
function printIndex(sheet,names,formulas) {
sheet.clearContents();
sheet.getRange(1,1).setValue('Workbook Index').setFontWeight('bold');
sheet.getRange(3,1,names.length,1).setValues(names);
sheet.getRange(3,2,formulas.length,1).setFormulas(formulas);
}
// function to create array of sheet names and sheet ids
function sheetNamesIds(sheets) {
var indexSheetNames = [];
var indexSheetIds = [];
// create array of sheet names and sheet gids
sheets.forEach(function(sheet){
indexSheetNames.push([sheet.getSheetName()]);
indexSheetIds.push(['=hyperlink("#gid='
+ sheet.getSheetId()
+ '","'
+ sheet.getSheetName()
+ '")']);
});
return [indexSheetNames, indexSheetIds];
}