I have a Google Sheet that has form responses. The e-mail address was not required, however it should have been. Either way, I am trying to back-fill the e-mail addresses (in order to make them ready to import as Spiceworks tickets, but I digress). I am going through and typing in usernames, but I want Sheets to auto-fill the domain. I was thinking I could do this by having it detect that the string ended in #, and then just adding the domain to it. Currently I have:
// assumes source data in sheet named Done 14-15
// test column with done is col 9 or I
if(s.getName() == "Done 14-15" && r.getColumn() == 9 && r.getValue() == "?#" ) {
var row = r.getRow();
var value = r.getValue();
r.setValue(value + "example.org");
var numColumns = s.getLastColumn();
s.getRange(row, 1, 1, numColumns).copyTo(target);
}
As you can see, I have a question mark for a wildcard. I have tried using an asterisk or a percentage sign as well, and not gotten anywhere. It will replace if I have literally ?# in there, but I want it to take anything# and append our domain.
RegEx should solve your problem.
Replace the r.getValue() == "?#" with
var regEx = new RegExp('.*#$')
if (regEx.test(r.getValue())) {
// your code
}
Instead of r.getValue() == "?#" you can write r.getValue().endsWith("#")
The email addresses can be easily updated like this:
var newValue = event.value.replace(/#$/,'#example.org');
Where the match is not found, the replacement will not happen... and newValue will equal the original value. Instead of checking for the match before deciding to do something, I'm suggesting doing it then checking the result.
Since you are entering the email addresses by hand, this is a good application of the onEdit() simple trigger and its event object.
function onEdit(event) {
var r = event.range;
var s = r.getSheet();
if (s.getName() == "Done 14-15" && r.getColumn() == 9 && r.getRow() > 1) {
// Replace an # at the end of the string with domain
var newValue = event.value.replace(/#$/,'#example.org');
// If value changed, write it back to spreadsheet
if (event.value !== newValue) {
event.range.setValue(newValue);
}
}
}
If you have rows that have already been edited and need to be checked, this function will take care of them. It uses the technique from How can I test a trigger function in GAS? to create a fake event, then passes it to the onEdit() trigger function.
// Call onEdit for each row in conversion sheet
function convertAllEmails() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName( "Done 14-15" );
var lastRow = sheet.getLastRow();
for (var row=1; row<lastRow; row++) {
var fakeEvent = {
range: sheet.getRange(row,9);
value: range.getValue();
};
onEdit( fakeEvent );
}
}
Related
New to scripting, trying to use the OnEdit() to force lowercase on values in column E
started with a few iteration of the following with no succes...
function onEdit(e) {
var range = e.range;
var value = range.getValue();
if (range.getColumn() = 5 ) {
e.range.setValue(e.value.toLowerCase());
} else {
return;
}
}
Any easy tweak you can think of to force lowercase on edits in cloumn E?
Thank you,
JF
function onEdit(e) {
if (e.range.columnStart == 5) {
e.range.setValue(e.value.toLowerCase());
}
}
Generally scripts limit there activity to a specific set of pages and rows. I suppose you are aware that this trigger will be running for all of your tab/sheets.
I have designed a google spreadsheet to help improve efficiency of material flow. I want to automatically sort the data by 2 different columns to prioritize critical parts that need to be received first once the entire row of data is entered. The problem I am having is that the data is sorting as soon as you enter one of the columns I am calling to sort but the columns I want to sort are not the last column of that row of data that needs to be entered. I am trying to use an if statement to not execute the sort until the last column has been entered else throw an error statement that says you must enter data in this column to proceed. Logically, the code makes sense to me but I have only an adequate understanding of computer language. I keep receiving an error in line 10 that the range is not found. I believe my error is the syntax in trying to call the last column. Any help would be greatly appreciated
**function autosort(){
// Variable Declaration
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var NewsheetName = SpreadsheetApp.getActiveSheet().getName();
var sheetName = sheet.getSheetByName(NewsheetName);
var lastCol = sheetName.getLastColumn();
var lastColBlank = SpreadsheetApp.getActiveSheet().getRange(lastCol).isBlank()
// Find range to sort
var range = sheetName.getRange("A2:G");
// Sorting algorithm
if (lastColBlank == false ){
range.sort([6,5]);
}
else {
throw ("error: If trailer # is unavailable, please enter N/A");
}
}**
Try this code:
function onEdit() {
var sh = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var editedCell = sh.getActiveRange().getColumnIndex();
if(editedCell == 2) {
var range = sh.getRange("A2:B10");
var blank = range.isBlank()
var values = range.getValues();
Logger.log(values)
for (var i = 0; i<values.length; i++) {
//values.length returns 11 for eleven items
// values[10][0] would be the 11th row 1st column
Logger.log(values[i][1])
if (values[i][0] == "" || values[i][1] == "") {
//throw new Error("error: If trailer # is unavailable, please enter N/A");
var ui = SpreadsheetApp.getUi();
var response = ui.alert('If trailer # is unavailable, please enter N/A');
}else{
range.sort({column: 2});
}
}
}
}
If you'll look into the code, the sort depends on the second column to be edited. Then, will check the range if the is still a blanked cell.
Just apply your additional code to meet your goal and I think that will work.
Hope this helps.
I'm trying to set up an email alert system based on a project tracking sheet my team uses at work. I need it to send an email when a task's status is changed to "Done" in column K. I got the code to work on a test sheet, but when I copy it to the live sheet the getValue() code stops working? Since the email is sent based on if() statements, the script runs, but doesn't actually work. I'm not sure if it's a permissions issue since I am not the owner of the live sheet?
I hope that is descriptive enough -- I have taught myself javascript in order to get this working and it seems so close, but I am stuck!!
Here is a screenshot of what the project tracking sheet looks like.
function emailUpdate(e) {
var emailInfoRange = sheet.getRange("B:O");
var edit = e.range.getA1Notation(); // Gets edited cell location
var editColumn = edit.substring(0,1) // Gets column of edited cell
var editRow = edit.substring(1,3) // Gets row of edited cell
if(editColumn == "K") { // gets all relevent information needed for email
var taskTypeCell = emailInfoRange.getCell(editRow,1);
var taskType = taskTypeCell.getValue();
var requestedByCell = emailInfoRange.getCell(editRow,3);
var requestedBy = requestedByCell.getValue();
var emailRequestCell = emailInfoRange.getCell(editRow,4);
var emailRequest = emailRequestCell.getValue();
var projectIdCell = emailInfoRange.getCell(editRow,5);
var projectID = projectIdCell.getValue();
var taskDescriptionCell = emailInfoRange.getCell(editRow,6);
var taskDescription = taskDescriptionCell.getValue();
var claimedByCell = emailInfoRange.getCell(editRow,9);
var claimedBy = claimedByCell.getValue();
var taskStatusCell = emailInfoRange.getCell(editRow,10);
var taskStatus = taskStatusCell.getValue();
if(taskStatus == "Done") {
if(emailRequest == "Yes" || emailRequest == "yes") { // Determines if status is "Done", and email notification is "Yes" or "yes"
var emailAddress;
var getEmailAddress = function(personelArray) { // Defines function to search email address arrays for the one that belongs to requestedBy
for (var i = 0; i < personelArray.length; i++) {
if(requestedBy === personelArray[i]) {
emailAddress = personelArray[i+1];
} } }
// Searches through all email arrays to find the one belonging to requester
getEmailAddress(specialistsAndEmails)
getEmailAddress(coordinatorsAndEmails)
getEmailAddress(managersAndEmails)
// Sends email
MailApp.sendEmail(emailAddress,
"AUTOGEN: " + taskType + " for " + projectID + " " + taskDescription + " completed by " + claimedBy + ".", "This email has been automatically generated by an edit to the work available sheet. \n"
+ "PLEASE DO NOT REPLY");
} else (Logger.log("No email requested"))
} else (Logger.log("Status not changed to done"))
} else (Logger.log("Update not to status cell"))
}
I would make the following changes to help prevent issues with string manipulations. Which could be the cause for your issues with getValues().
function emailUpdate(e) {
var emailInfoRange = sheet.getRange("B:O");
var edit = e.range // Gets edited cell location
var editColumn = edit.getColumn() // Gets column of edited cell
var editRow = edit.getRow() // Gets row of edited cell
if(editColumn == 11) // Column K should correspond to column number 11, if i can count correctly.
{
/// Remainder of the code should be the same as above
}
}
So instead of converting the range to A1 notation, you should get column number and row number using getColumn and getRow() on the range object. This will prevent issues with text to number manipulation and could be the cause of your problems.
I am trying to write a script in google sheets that will send one of two different emails based on the response to a multiple choice question. I can get my if/else statement to send either one or the other of the emails but it will not recognize the text of the multiple choice answer and send the correct email.
Here is the full script:
function sendEmails() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2; // First row of data to process
var numRows = 1;
// Fetch the range of cells A2:B3
var dataRange = sheet.getRange(startRow, 1, numRows, 8)
// Fetch values for each row in the Range.
var data = dataRange.getValues();
for (var i = 0; i < data.length; ++i) {
var row = data[i];
var title = row[1]; // First column
var startDate = row[3]; // Second column
var endDate = row[4];
var description = row[2];
var location = row[6];
var eventImport = row[5];
var emailAddress = row[7];
var multchoice = row[8];
if (multchoice == "Part Time") {
var subject = "New Hire Part Time Email - " + startDate;
var emailBody = "Congradulations"
var htmlBody = "Congradulations! Part time person"
MailApp.sendEmail (emailAddress, subject, emailBody);
} else {
var subject = "New Hire Appointment - " + startDate;
var emailBody = "Congratulations! We are excited"
var htmlBody = "Congratulation! </i><br/> <br/> We are excited"
MailApp.sendEmail(emailAddress, subject, emailBody);
}
}
}
I believe the problem is here:
if (multchoice == "Part Time")
Any help is greatly appreciated! I am a novice
It looks like you are assigning your variables starting with '1' I stead of '0'. Start assigning them with 0 and counting up.
Without an example sheet to use, I won't be able to do a whole lot of debugging for you.
However, Apps Script comes with it's own debugger. Select the function you wish you debug and click the Little bug icon beside the play button.
Click on the sidebar where you want to set a breakpoint, where the code will stop executing.
Once it hits that breakpoint you can see all the variables currently within your scope. So the array, value, and i variables are visible to you.
Use this to your advantage and debug your code to find out where the issue is. Alternatively, you can use Logger.log() to log values at certain points within your code and then read back through the logs to try and determine where the problem lies.
The problem is not with your if/else statement. The problem is with how you are assigning your variables from your row[] array. While you use regular numbers in the getRange() function, the range that is returned is an array of those cells. Arrays always start with an index of [0]. Change var multchoice = row[8] to var multchoice = row[7] and your if/else statement will work (you'll want to change all of your other references, too).
If I copy/paste the information into both cells my script runs correctly and matches the strings in the cells to the correct row for the user so I can lookup their email. If I let my google form fill the first cell however the data in the two cells no longer matches. I'm probably overlooking something obvious about comparing the strings but hopefully someone can point me in the right direction. Here is the code I have so far.
var rows = SpreadsheetApp.getActiveSheet().getLastRow();
var cell = SpreadsheetApp.getActiveSheet().getRange(rows, 2);
var value = cell.getValue().toString();
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.setActiveSheet(ss.getSheets()[1]);
var sheet;
var teacher;
var cc = "no match";
for(var h=1; h <= ss.getLastRow(); h++)
{
sheet = ss.getActiveSheet().getRange(h, 2);
teacher = sheet.getValue().toString();
if (value == teacher)
cc = ss.getActiveSheet().getRange(h, 1).getValue().toString();
}
Try to use watchdog (clicking on line number) or some message box to see what happens
i.e. Browser.msgBox(teacher); bebore testing the value of value ^^
and may be don t use the "value" as a variable name, it could generate problem to execute the script.