GoogleSheet script editor - onEdit event with conditions / if statement - if-statement

guys!
I'm new to this website and also not good with coding. So I would really appreciate some help.
Right now I'm in need of a specific code to make a google sheet work perfectly.
To further explain:
I have a google sheet that a few information will be input by other co-workers. What I need is a code that will register the date in a specific cell and by whom the input was made on another cell.
So far this is what I have:
function onEdit(event) {
var sheet = event.source.getSheetByName("Input");
// Note: actRng = return the last cell of the row modified
var actRng = event.source.getActiveRange();
var index = actRng.getRowIndex();
var cindex = actRng.getColumnIndex();
// Note: date = return date
// Note: user = return the user email
var userCell = sheet.getRange(index,14);
var dateCell = sheet.getRange(index,2);
var inputdate = Utilities.formatDate(new Date(), "GMT+0200", "yyyy-MM-dd");
// Note(with hour): var inputdate = Utilities.formatDate(new Date(), "GMT+0200", "yy-MM-dd HH:mm");
//var user = event.user; // Note: event.user will not give you collaborator's Id
var user = Session.getEffectiveUser();
// Note: setValue = Insert in the cell the date when this row was modified
if (userCell.Value == null) {
userCell.setValue(user);
dateCell.setValue(inputdate)
}
}
My main problems/questions are:
I don't exactly need the last modifier, but the person who first input info on the cells. Therefore I tried that last IF (If the cell that is supposed to have the last modifier e-mail is blank, it means that nobody changed that row before, so the code should add the user on the userCell), although it is not working since every change I make it ignores the verification.
I also want to add that the event will only happen if you add values, if you delete them, nothing happens. (so far even when I delete cells, it counts as modification)
Most of the sheet is protected to avoid that people by accident erase some of the formulas, so the cells that this code changes are also protected. Is there a way to make the code bypass cell protection?
Please, help me identify what I'm doing wrong and hopefully I'll get this working perfectly! Thanks for the help !

If you want to prevent the script from firing when a cell is deleted, try:
var editedCell = SpreadsheetApp.getActiveSheet().getRange(e.range.getRow(), e.range.getColumn());
if (editedCell == "") {
return;
}
I would change Session.getEffectiveUser() to session.getActiveUser().
The last if statement is unnecessary. You want whoever most recently edited the field to be identified, along with the date.

Related

Google Sheets - Fill in date from another cell if empty

Thanks in advance for your help! Our team has a Google Sheet that is used to manage projects.
There is a Start Date (Column E) and a **Due Date **(Column F) that can be set for any task, however some require it, some don't. For example, for call tasks, we put the same start/end date. We need both cells to be filled in so we can display a gantt chart with all activities.
Is there a way to automatically fill in the Start Date cell with the End date (and vice versa), if one of them is empty?
I didn't want to populate those cells with a formula to keep things simple an played around with the formulas in conditional formatting but couldn't find a way!
This code is not very elegant (I'm still pretty new), but this may work if you are just looking to add a start date where there is an end date and vice versa.
EDIT: Using your implementation plan, I was able to get a version of this script to work. There was an issue where the startDate and endDate arrays held time data (ex: 4/21/2022, 12:00 PM). I was able to work around this by splitting the element from the comma so that it would only show the date.
function FillDate() {
let sheet = SpreadsheetApp.openById('YOUR_SHEET_ID').getSheetByName('YOUR_SHEET_NAME');
let dateColumns = sheet.getRange(13,4,sheet.getLastRow(),2).getValues();
let startDate = dateColumns.map(function(r){return r[0].toLocaleString();});
let endDate = dateColumns.map(function(r){return r[1].toLocaleString();});
let headerRows = 13; //you may want to change this if you have more than one header row
for (i=0; i<sheet.getMaxRows(); i++)
{
if (((startDate[i] != '') && (endDate[i] != ''))||((startDate[i] === '') && (endDate[i] === '')))
{
//This is empty because you don't want to do anything if both Start and End Dates are empty or full.
}
else
{
if((startDate[i] == '') && (endDate[i] != ''))
{
let splitEndDate = endDate[i].split(",");
sheet.getRange(headerRows+i,4).setValue(splitEndDate[0]);
}
else
{
let splitStartDate = startDate[i].split(",");
sheet.getRange(headerRows+i,5).setValue(splitStartDate[0]);
}
}
}
}

IF ELSE statement to set variable value

I am creating a site where clients can construct a price quote.
I have used Tabulator to show the data in a table.
The Tabulator data is in its own .JS file "buildTabulator.js", while the Quote scripts are in another .JS file "quote.js".
I am able to extract the data and get it mostly doing what I want so far.
But, when I try to create an IF ELSE statement in the quote.js file to determine which price should be displayed based on the unit of measure (UOM) of the item, it will not work correctly. It always shows the EACH or EA price of the item which is in the IF part of the IF ELSE statement.
More specifically, if the user adds an item to the quote that is sold by the EACH it should show one price, but if they choose an item that is sold by the CASE it should display a different price.
Please see the attached screenshots and code below and advise if you can...
I am hoping this is something simple that a noob like me has missed by mistake.
First screenshot is showing the code in VSC.
Second screenshot is showing an example in the console log of the browser. This example is using an item that is sold by the CASE and should show the case price of the item but instead shows a "-" because the EACH price of this item is a dash since its not sold by the each.
In the log it shows CS for CASE which is correct but the "-" should actually be 0.2937 which is shown in the table above the console.
Please let me know if there is any more information I can provide or any questions you may have.
Thank you so much in advance!!
CODE FROM "buildTabulator.js"
cellClick: function (e, cell) {
globalThis.itemImage =
"imgsQuote/" + cell.getRow().getData().IMAGE + ".png";
globalThis.itemCode = cell.getRow().getData().CODE;
globalThis.itemDescription = cell.getRow().getData().DESCRIPTION;
globalThis.itemBx = cell.getRow().getData().BX;
globalThis.itemCs = cell.getRow().getData().CS;
globalThis.itemUom = cell.getRow().getData().UOM;
globalThis.itemCost = cell.getRow().getData().COST;
globalThis.itemBox = cell.getRow().getData().BOX;
globalThis.itemHalf = cell.getRow().getData().HALF;
globalThis.itemLess = cell.getRow().getData().LESS;
globalThis.itemCase = cell.getRow().getData().CASE;
globalThis.itemBxWt = cell.getRow().getData().BXWT;
globalThis.itemCsWt = cell.getRow().getData().CSWT;
// globalToLocal();
setItemPrice();
},
CODE FROM "quote.js"
function setItemPrice() {
console.log(globalThis.itemUom);
var itemPrice;
if ((globalThis.itemUom = "EA")) {
itemPrice = globalThis.itemBox;
} else {
itemPrice = globalThis.itemCase;
}
console.log(itemPrice);
}
after another 3 hours or so of searching I found an answer that works:
setting variable with ternary expression

Been trying to automate the Find and Replace in Google Sheets but did not work

My sheet is a query-sheet from database. Some of them contain html hex-code color which I need to manually use edit>Find and Replace every time it is refreshed.
I am very new to Google App Script and been trying to use the following code:
function Clearcode() {
var lookupone = new RegExp(/{color:#.{7}/);
var rep = "";
var spreadSheet = SpreadsheetApp.getActive();
var querySheet = spreadSheet.getSheetByName("QUERY");
var lastRow = querySheet.getLastRow();
var lastColumn = querySheet.getLastColumn();
var data = querySheet.getRange(2, 1, lastRow-1, lastColumn).getValues();
var textfinder = querySheet.createTextFinder(lookupone);
var found = textfinder.replaceAllWith(rep);
return (found);
}
Yet, when I run this function in the sheet it did not work. Any thought?
P.S. I planned to eliminated "[color]" part of the hex-code as well by create the similar function.
P.S.2 I have attached a snapshot of a table as you requested. The red line is just for confidentiality of the data. Below the line is just a normal text.
Pay attention to types!
CreateTextFinder accepts String as argument NOT a regexp object.
To use strings as regular expressions, useRegularExpressions needs to be set to true
querySheet.createTextFinder("\\{color:#?.{0,6}\\}")//only 6 characters
.useRegularExpressions(true)
.replaceAllWith("")

Remove Characters from Google Sheets up to # sign

I have a column of E-mail addresses in a Google Sheet and want to remove all of the domain names and '#' symbol and copy this to a new column. For example:
Column-A
test#test.com
testb#gmail.com
testc#yahoo.com
Copied and removing the domains to:
Column-B
test
testb
testc
all you need is:
=ARRAYFORMULA(IFNA(REGEXEXTRACT(A1:A&"", "(.+)#")))
use this function on google App script:
function myFunction() {
// Your spreadsheet
var ss = SpreadsheetApp.getActive()
//if you got only one sheet
var sheet = ss.getSheets()[0];
// This is in the case that your sheet as a header, if not replace 2 by 1 and (sheet.getLastRow()-1) by sheet.getLastRow()
var valuesColumnA = sheet.getRange(2,1,(sheet.getLastRow()-1)).getValues();
//Just to have each value in the same array
var valuesColumnAMapped = valuesColumnA.map(function(r){return r[0]});
valuesColumnAMapped.forEach(function(value, index){
var split = value.split("#");
sheet.getRange((index+2),2).setValue(split[0]);
})
}
My answer as per my understanding maybe I'm wrong so please follow if I'm right to understand.
use split to get this
Go to Data
Click on Split Text to Columns
Pick Custom From Drop Down
enter # and you get your result.

parse google document for text and copy result to sheet

I wish to parse a series of documents in a Google Drive folder using regular expressions.
The documents contain equipment model and serial numbers. I wish to then copy the results to a google sheet row by row. I have managed a similar task with emails successfully but to no avail with google docs.
Can anyone offer some guidance. I have tested the regular expressions in the 'find and replace' menu in google docs and they work fine. The following is simply an attempt to see if I can capture some data and write it to a cell in the active sheet.
function write() {
var ss= SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var doc =
DocumentApp.openById('1ZNqJjSJo1wkD3eaCRTY64g98hYEY77D4MDU6XpvA4MI');
var body = doc.getBody();
var text = body.findText('(\W|^)GSS\d{2}H(\W|$)')
ss.getRange(1,1).setValue(text);
}
You want to retrieve all values matched by (\W|^)GSS\d{2}H(\W|$) in the document, and put the result to spreadsheet with row by row. If my understanding is correct, how about this modification? I think that there are several answers for your situation. So please think of this as one of them.
Modification points :
Retrieve text from document.
Retrieve all matched values using the regex.
For this situation, I used RegExp#exec.
Put the result to spreadsheet.
Modified script :
function write() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var doc = DocumentApp.openById('1ZNqJjSJo1wkD3eaCRTY64g98hYEY77D4MDU6XpvA4MI');
var body = doc.getBody();
// Modified script
var text = doc.getBody().getText();
var result = [];
var r = /(\W|^)GSS\d{2}H(\W|$)/g;
while ((res = r.exec(text)) !== null) { // or while (res = r.exec(text)) {
result.push([res[0]]);
}
ss.getRange(ss.getLastRow() + 1, 1, result.length, 1).setValues(result);
}
If this was not what you want, I'm sorry. At that time, could you please provide the sample input and output you need? I would like to modify my answer.