searching and replacing does not record in google sheets - google-apps-script

How I record an action for this function?
Basically I have to do this and others actions everyday and always is the same.

searching and replacing does not record in google sheets
That is right, the find and replace function is not accessible via Google App Scripts and is not therefore able to be recorded. You need to create your own code to accomplish a behavior similar to the behavior you want manually.
Here is one of many example ways of doing it: https://webapps.stackexchange.com/questions/104157/auto-find-and-replace-in-google-sheets-with-scripts

Thanks i used that code and i edited a litle bit.
function Herramienta() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange('A1:A69').activate();
spreadsheet.getRange('A1:A69').splitTextToColumns();
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange("a2:a69");
var to_replace = "HH-";
var replace_with = "";
replaceInSheet(sheet,range, to_replace, replace_with);
function replaceInSheet(sheet, range, to_replace, replace_with) {
//Confirm
var ui = SpreadsheetApp.getUi();
var spread = SpreadsheetApp.getActiveSpreadsheet();
var result = ui.alert(
"Will update " + to_replace + " to " + replace_with + " ",
'Are you sure you want to continue?',
ui.ButtonSet.YES_NO);
// Process the user's response.
if (result == ui.Button.YES) {
// User clicked "Yes".
spread.toast("Will update " + to_replace + " to " + replace_with + " ", "ALERT");
var data = range.getValues();
var oldValue="";
var newValue="";
var cellsChanged = 0;
for (var row=0; row<data.length; row++) {
for (var item=0; item<data[row].length; item++) {
oldValue = data[row][item];
newValue = data[row][item].replace(to_replace, replace_with);
if (oldValue!=newValue)
{
cellsChanged++;
data[row][item] = newValue;
}
}
}
range.setValues(data);
spread.toast(cellsChanged + " cells changed", "STATUS");
}
else {
// User clicked "No" or X in the title bar.
spread.toast("No action taken", "ABANDONED");
}
}
}

Related

Apps Script Google Sheets POP up selecting yes or no always sends the email regardless

I have a google sheet with a dropdown menu. When the cell the drop down is in is equal to a certain string a pop up shows up on screen. You answer yes or no.
When you answer yes it sends the email. If you answer no it does not send the email and resets the cell to its previous state.
The issue I am having is that if you select no it does reset to the previous data, but it still sends the email regardless. Please help. I am fairly new and still learning.
UPDATE:
Please see the update below. The only var I had to fix was for rData, other than that the script works as intended now. Thank you so much for your time and input. This was a headache for some time.
function sendMailEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ui = SpreadsheetApp.getUi();
if (ss.getSheetName() == 'Project List' &
ss.getActiveCell().getColumn() == 3 &
ss.getActiveCell().getValue() == "_Complete") {
var alertPromptText = 'Are you sure you want to select Complete? ' +
'This action will notify all parties in the next process that this job is ready for fabrication.';
var promptResponse = ui.alert(alertPromptText, ui.ButtonSet.YES_NO);
if (promptResponse == ui.Button.YES) {
// CHECK START
// variable email needs to be fixed. It gets the column of values.
// it needs to be converted to a comma separated list of recepients
var email = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Email").getRange(1, 1, 100).getValues();
// CHECK END
var rData = e.source.getActiveSheet().getRange(e.range.rowStart,1,1,12).getValues();
sendEmail(email,rData);
} else { // For both 'No' and cancel response to pop-up
fix(e);
}
}
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
function sendEmail(email,rData) {
var first = 0;
var email = 1;
var emailTemp = HtmlService.createTemplateFromFile("send");
var ws = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Email");
var data = ws.getRange("A1:B" + ws.getLastRow()).getValues();
var lj = rData[0][1];
var j = rData[0][5];
var d = rData[0][3];
var p = rData[0][4];
var m = rData[0][7];
var desc = rData[0][11];
var now = new Date().toLocaleString("en-US");
var msg1 = "Laser Job Number: " + lj + " (" + now + ")" +
"\nProject Job Number: " + j +
"\nDesigner: " + d +
"\nDate Project was Submitted to Programming: " + p +
"\nMaterial used: " + m +
"\nDescription: " + desc;
var subject = "Project Ready for Fab";
Logger.log(msg1);
data.forEach(function(row){
emailTemp.fn = row[first];
emailTemp.msg = msg1;
emailTemp.j = j;
emailTemp.d = d;
emailTemp.lj = lj;
emailTemp.p = p;
emailTemp.m = m;
emailTemp.desc = desc;
//emailTemp.cart = cart;
const htmlMessage = emailTemp.evaluate().getContent();
GmailApp.sendEmail(row[email], subject, "Please open with an email client that supports HTML",
{htmlBody: htmlMessage});
return;
});
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
function fix(e) {
e.range.setNote(e.oldValue);
e.range.setValue(e.range.getNote());
e.range.clearNote();
}
You need to set a variable to capture the response to the pop-up.
And then compare the value of the variable for the go-no-go part of the script.
For example:
var response = ui.prompt('Alert', 'Are you sure you want to select Complete?', ui.ButtonSet.YES_NO);
And then
if (response.getSelectedButton() == ui.Button.YES) { ... }
More here in the documentation.
Update
Try the following script. You'll need to set the onEdit trigger to run the function SendMailEdit
Also, check the code for getting the list of email recepients. Not sure if it will work.
function sendMailEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ui = SpreadsheetApp.getUi();
if (ss.getSheetName() == 'Project List' &
ss.getActiveCell().getColumn() == 3 &
ss.getActiveCell().getValue() == "_Compvare") {
var alertPromptText = 'Are you sure you want to select Compvare? ' +
'This action will notify all parties in the next process that this job is ready for fabrication.';
var promptResponse = ui.alert(alertPromptText, ui.ButtonSet.YES_NO);
if (promptResponse.getSelectedButton() == ui.Button.YES) {
// CHECK START
// variable email needs to be fixed. It gets the column of values.
// it needs to be converted to a comma separated list of recepients
var email = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Email").getRange(1, 1, 100).getValues();
// CHECK END
var rData = ss.getRange(ss.getActiveCell().getRow(), 1, 1, 12).getValues();
sendEmail(email, rData);
} else { // For both 'No' and cancel response to pop-up
fix(e);
}
}
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
function sendEmail(email, rData) {
var lj = rData[0][1];
var j = rData[0][5];
var d = rData[0][3];
var p = rData[0][4];
var m = rData[0][7];
var desc = rData[0][11];
var now = new Date().toLocaleString("en-US");
var msg = "Laser Job Number: " + lj + " (" + now + ")" +
"\nProject Job Number: " + j +
"\nDesigner: " + d +
"\nDate Project was Submitted to Programming: " + p +
"\nMaterial used: " + m +
"\nDescription: " + desc;
Logger.log(msg);
GmailApp.sendEmail(email, "Project Ready for Fab", msg);
return;
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
function fix(e) {
e.range.setNote(e.oldValue);
e.range.setValue(e.range.getNote());
e.range.clearNote();
}

Get value from formula cell to trigger email sending

I am trying to get an e-mail to be sent when the value in a cell that contains a formula goes below a certain number.
I have achieved this for various other spreadsheets that have the cell value manually entered, but for this specific one sheet where the value on the cell results from a simple SUM formula, the e-mail is not being sent. Now if I enter the value manually into the cell, the e-mail is sent right away.
Below is the code and here is a copy of my spreadsheet:
https://docs.google.com/spreadsheets/d/1gnmJfkmIKHyNqLqTFK-bdOZnh2Ejkia6xo3r_3cjwkk/edit?usp=sharing
function CheckBasketsInventory(e) {
var ss = e.source;
var inventorySheet = ss.getSheetByName("Baskets");
var rowIndex = e.range.getRow();
var columnIndex = e.range.getColumn();
var numCols = 11;
var row = inventorySheet.getRange(rowIndex, 1, 1, numCols).getValues()[0];
var editedInventory = row[10];
var editedMinimum = row[8];
var sheetName = ss.getActiveSheet().getName();
// Checking that: (1) edited cell is an inventory quantity, and (2) Inventory is below minimum
if(editedInventory <= editedMinimum && sheetName == "Baskets" && columnIndex == 11 && rowIndex > 1) {
var inventoryValues = inventorySheet.getDataRange().getValues();
var emailBody = "";
for(var i = 1; i < inventoryValues.length; i++) {
var inventory = inventoryValues[i][10];
var minimum = inventoryValues[i][8];
if(inventory <= minimum) {
var productName = inventoryValues[i][0] + " " + inventoryValues[i][1] + " " + inventoryValues[i][2];
var productUnits = minimum + " " + inventoryValues[i][9];
var messagePart1 = "Inventory for " + productName + " has gone under " + productUnits + ". ";
var messagePart2 = "Organise purchase order. Inventory as of today is: " + inventory + " " + inventoryValues[i][9];
var message = messagePart1.concat(messagePart2);
var newItem = "<p>".concat(message, "</p>");
emailBody += newItem;
}
}
var emailSubject = "Low inventory alert";
var emailAddress = "danielrzg#gmail.com";
// Send Alert Email
if(emailBody != "") {
MailApp.sendEmail({
to: emailAddress,
subject: emailSubject,
htmlBody: emailBody
});
}
}
}
Thank you.
As you can see in the documentation:
Script executions and API requests do not cause triggers to run. For
example, calling FormResponse.submit() to submit a new form response
does not cause the form's submit trigger to run.
This includes values edited by a Sheet Formula not triggering an onEdit trigger.

Automatically Find&Replace

I work with surveymonkey and when someone doesn't answer my question, my cell is filled with "Not Answered".
The goal is to merge multiple rows into one.
Possible solutions are:
I need a script to automatically find and replace. Which will replace (more precisely delete "Not Answered") with an empty cell. So my TEXTJOIN will work. I've tried some code but it doesn't work for the whole sheet.
The problem with the TEXTJOIN function (delimiter, ignore_empty, text1, [text2, ...]) is that the second parameter igrone_empty is boolean and only works with TRUE or FALSE and cannot write "Not Answered" there. So with this I have to find another solution to ignore or delete the word "Not Answered".
Alternative to TEXTJOIN where the word "Not Answered" is ignored.
Or if it is possible to delete this option in SurveyMonkey?
I have tried this solution but doesn't work for entire sheet/table.
var result = ui.alert(
"Will update " + to_replace + " to " + replace_with + " ",
'Are you sure you want to continue?',
ui.ButtonSet.YES_NO);
// Process the user's response.
if (result == ui.Button.YES) {
// User clicked "Yes".
spread.toast("Will update " + to_replace + " to " + replace_with + " ", "ALERT");
var data = range.getValues();
var oldValue="";
var newValue="";
var cellsChanged = 0;
for (var row=0; row<data.length; row++) {
for (var item=0; item<data[row].length; item++) {
oldValue = data[row][item];
newValue = data[row][item].replace(to_replace, replace_with);
if (oldValue!=newValue)
{
cellsChanged++;
data[row][item] = newValue;
}
}
}
range.setValues(data);
spread.toast(cellsChanged + " cells changed", "STATUS");
}
else {
// User clicked "No" or X in the title bar.
spread.toast("No action taken", "ABANDONED");
}
}
Try this:
function replaceNotAnswerWithBlank(e) {
var ss=e.source;
var sh=ss.getActiveSheet();
var rg=sh.getDataRange();
var tf=sh.createTextFinder('Not Answered').findAll();
for(var i=0;i<tf.length;i++) {
sh.getRange(tf[i].getRow(),tf[i].getColumn()).setValue('');
}
}
How about this:
function onOpen(e) {
replaceNotAnswerWithBlank(e);
}
I needed a trigger so this is how I solved the problem. If there is a simpler functional solution write it down. Thank you Cooper.
function onOpen() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getActiveSheet();
var rg=sh.getDataRange();
var tf=sh.createTextFinder('Not Answered').findAll();
replaceNotAnswerWithBlank(ss, sh, rg, tf);
}
function replaceNotAnswerWithBlank(ss, sh, rg, tf) {
for(var i=0;i<tf.length;i++) {
sh.getRange(tf[i].getRow(),tf[i].getColumn()).setValue('');
}
}

Auto find and replace Google Sheet every time I run the script

I find this code but it doesn't work like expected.
function onOpen() {
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange("'Feuille 1'!1:1137");//This line is most likely the culprit
var to_replace = ".";
var replace_with = ",";
replaceInSheet(sheet,range, to_replace, replace_with);
}
function replaceInSheet(sheet, range, to_replace, replace_with) {
//Confirm
var ui = SpreadsheetApp.getUi();
var spread = SpreadsheetApp.getActiveSpreadsheet();
var result = ui.alert(
"Will update " + to_replace + " to " + replace_with + " ",
'Are you sure you want to continue?',
ui.ButtonSet.YES_NO);
// Process the user's response.
if (result == ui.Button.YES) {
// User clicked "Yes".
spread.toast("Will update " + to_replace + " to " + replace_with + " ", "ALERT");
var data = range.getValues();//I think error is occurring here
var oldValue="";
var newValue="";
var cellsChanged = 0;
for (var row=0; row<data.length; row++) {
for (var item=0; item<data[row].length; item++) {
oldValue = data[row][item];
newValue = data[row][item].replace(to_replace, replace_with);
if (oldValue!=newValue)
{
cellsChanged++;
data[row][item] = newValue;
}
}
}
range.setValues(data);
spread.toast(cellsChanged + " cells changed", "STATUS");
}
else {
// User clicked "No" or X in the title bar.
spread.toast("No action taken", "ABANDONED");
}
}
I got this error :
TypeError: Impossible d'appeler la méthode "getValues" de undefined. (ligne 25, fichier "Code")
Could you help me I'm a noob
Regards
So apparently this line has a problem:
var range = sheet.getRange("'Feuille 1'!1:1137");
The range is the problem it should be something like 'Sheet1!A1:A1137'.
So may be this will work: var range = sheet.getRange("'Feuille 1'!A1:A1137");
Since I can't see your sheet you will have to determine the appropriate range.

Google Script E-mail Array

I have the following Google Script. It runs through a spreadsheet and imports information into a Google Calendar. However, I also want it to populate an array with the uploaded data and send it in a Google email. Is this possible? Here is what I have so far.
var MAINTENANCE_EXPORTED = "MAINTENANCE_EXPORTED";
var MAINTENANCE_ERROR = "MAINTENANCE_ERROR";
var ss = SpreadsheetApp.getActiveSpreadsheet();
function onOpen() {
var menuEntries = [{name: "Upload CS Maintenance Schedule", functionName: "importCalendarCS"}, {name: "Upload EP Maintenance Schedule", functionName: "importCalendarEP"}];
ss.addMenu("Maintenance Scripts", menuEntries);
}
//
//Coral Street Import Function
//
function importCalendarCS() {
var sheet = ss.getSheetByName('CS');
var startcolumn = 1; // First column of data to process
var numcolumns = sheet.getLastRow(); // Number of columns to process
var dataRange = sheet.getRange(startcolumn, 1, numcolumns, 13) // Fetch values for each column in the Range.
var data = dataRange.getValues();
for (var i = 0; i < data.length; ++i) { // this is a "for loop" that asks the script to run through all rows.
var column = data[i];
var building = column[0]; // 1st column in spreadsheet "BLDG"
var cart = column[1]; // 2nd column in spreadsheet "CART OR LAB"
var room = column[2]; // 3rd column in spreadsheet "LOCATION OF CART OR ROOM"
var deviceType = column[3]; // 4th column in spreadsheet "TYPE OF DEVICES"
var deviceQuantity = column[4]; // 5th column in spreadsheet "# of Devices"
var maintenancePerson = column[5]; // 7th column in spreadsheet "Maintenance Person"
var maintenanceDate = column[6]; // 6th column in spreadsheet "Maint Date"
var maintenanceImported = column[13];
var title = building + " - " + room;
var description = "Building: " + building
+ "\n" + "Room: " + room
+ "\n" + "Cart: " + cart
+ "\n" + "Device Type: " + deviceType
+ "\n" + "Device Quantity: " + deviceQuantity;
var calendarName = "Cart Maint Schedule";
if (maintenancePerson == "Bobby Obvious") {
var email = "example#example.com"
}
else {
var email = "example#example.com"
}
if ((maintenanceImported != MAINTENANCE_EXPORTED) && (maintenanceImported != MAINTENANCE_ERROR) && (building != "BLDG") && (cart != "Cycle 1 Checklist") && (cart != "Cycle 2 Checklist")) { // Prevents importing duplicates
var cal = CalendarApp.openByName(calendarName);
var advancedArgs = {description: description, location: ("Cart: " + cart)};
var itsEmail = "example#example.com";
if
if (maintenanceDate != "") {
cal.createAllDayEvent(title, new Date(maintenanceDate), advancedArgs);
var sheet2 = ss.getSheetByName('CS');
sheet.getRange(startcolumn + i, 14).setValue(MAINTENANCE_EXPORTED);
SpreadsheetApp.flush();
}
else {
var sheet2 = ss.getSheetByName('CS');
sheet.getRange(startcolumn + i, 14).setValue(MAINTENANCE_ERROR);
SpreadsheetApp.flush();
}
}
}
}
Yes it's possible. Use the MailApp class.
https://developers.google.com/apps-script/reference/mail/mail-app
or the GmailApp Class:
https://developers.google.com/apps-script/reference/gmail/gmail-app
Try to use the MailApp.sendEmail method. It accepts an address.