.getUsername() not functioning properly within Workspace account - google-apps-script

A two part question:
The script below is intended to watch for edits in column 6 of a specific sheet and when triggered, execute the three parts of the script (marked A-C below). All works properly for me as the owner of the sheet within a Workspace account. For other users who edit the sheet, part A works properly, but not B or C. All users are part of the same Workspace account.
As an alternative to watching just Col 6, any suggestions as to how I could rewrite the script to record the location of the most recently edited cell on a given row?
Thank you.
function onEdit(e) {
if (
e.source.getSheetName() == "STATUS" &&
e.range.columnStart == 6 &&
e.range.columnEnd == 6 &&
e.range.rowStart >= 2 &&
e.range.rowEnd <= 2000
) {
var range = e.range;
var status = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("STATUS");
//A: on modified row, copy live status to permanent
status.getRange(range.getRow() , 11).copyTo(status.getRange(range.getRow() , 7), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
//B: set time & date modified
status.getRange(range.getRow() , 8).setValue(new Date());
//C: set user who last modified ID column
status.getRange(range.getRow() , 9).setValue(Session.getEffectiveUser().getUsername());
}
else
{ return; }
}

With getEffectiveUser() you get the user under whose authority the script is running, change this to getActiveUser(). See the documentation. To get the column & row of the onEdit range try this:
e.range.getRow()
e.range.getColumn()

In a simple onEdit() trigger, Session.getEffectiveUser() is equivalent to Session.getActiveUser(), which states:
The circumstances in which the email address is available vary: for example, the user's email address is not available in any context that allows a script to run without that user's authorization, like a simple onOpen(e) or onEdit(e) trigger...
You should be able to generalize "email address" to username or any other personally identifiable information. That kind of information requires authorization.
The only way to make this work would be to have your other users authorize this script first.
If you don't want the trigger to be restricted to edits in Column 6, remove that condition from your if statement.
// These lines specify column 6
e.range.columnStart == 6 &&
e.range.columnEnd == 6 &&

Related

Add note based on value of another cell

For all I researched, I know there is not an integrated funcion that can do this, but I know it can be done with scripts. I want a script to create note in one specific cell based on another specific cell value.
example in the sheet I'll share
https://docs.google.com/spreadsheets/d/1I7ictcN_tEQyZXFljAVFm1VqZzafIezF1xR5AYW5pVc/edit?usp=sharing
I want the note on D12 to reflect any changes in the value of A8 for example.
Best case would be, if I could use this script as a function calling whatever cell I wanted.
I saw some examples using onEdit as trigger but I don't know if that would work because the cell in question wouldnt even be touched.
I also saw some exemples using get range to target the cells but then I would have to make a new script for each iteration.
Recording User Edits in A8 in the Notes of D12
function onEdit(e) {
const sh = e.range.getSheet();
if(sh.getName() == "Sheet name" && e.range.columnStart == 1 && e.range.rowStart == 8) {
sh.getRange(12,4).setNote(sh.getRange(12,4).getNote() + '\n' + e.value);
}
}

How to enable other (non-registered) editors to use the Google Apps Script attached to a Google Sheet?

Hi fellow Stack Overflowers,
Yesterday I used Google Apps Script for the first time and I tried to hide certain rows given on user input. For me this works absolutely fine. Everybody else can access the sheet if they have the link to it and they are allowed to edit certain cells. Another user verified that he can access the Apps Script and as such that it actually is attached to the file, but the Apps Script does not seem to run for anyone else but me.
'
function onEdit(e){
if(SpreadsheetApp.getActiveSheet().getSheetName() == "Cooldown")
{
if (e.range.columnStart != 2 || e.range.rowStart != 5) return;
else if(e.value != "TRUE")
{
SpreadsheetApp.getActiveSheet().hideRows(e.range.rowStart + 1);
SpreadsheetApp.getActiveSheet().getRange('B6').setValue(false);
}
else SpreadsheetApp.getActiveSheet().showRows(e.range.rowStart + 1);
}
else if(SpreadsheetApp.getActiveSheet().getSheetName() == "Benodigde Priesters")
{
if (e.range.columnStart != 2 || e.range.rowStart != 2) return;
else if(e.value != "TRUE")
{
SpreadsheetApp.getActiveSheet().hideRows(e.range.rowStart + 1);
SpreadsheetApp.getActiveSheet().hideRows(e.range.rowStart + 3);
SpreadsheetApp.getActiveSheet().getRange('B3').setValue(false);
SpreadsheetApp.getActiveSheet().getRange('B5').setValue(false);
}
else
{
SpreadsheetApp.getActiveSheet().showRows(e.range.rowStart + 1);
SpreadsheetApp.getActiveSheet().showRows(e.range.rowStart + 3);
}
}
}
As you might have noticed from the Apps Script, its intended purpose is to hide certain rows if a certain checkbox is unchecked and show the rows if it is checked. Rows 3 and 5 are hidden and B3 and B5 are reset to false if B2 is unchecked. Similarly, rows 3 and 5 are shown if B2 is checked.
Picture of the sheet
You are saying that users are "allowed to edit certain cells". That implies that the sheets are protected.
The onEdit(e) function is a simple trigger that runs under the account of the user at the keyboard. If that user does not have the right to edit the columns that you are trying to hide, the function will throw an error when it tries to hide the columns. You can inspect the errors at My Executions.
To make it work, rename the onEdit(e) function to something like hideColumns(e) and use an installable "on edit" trigger to run it. Installable triggers run under the account of the user who set up the trigger.

Date stamp script not working with arrayformula

I'm trying to use a simple date stamp script in Google Sheets that will input today's date upon edit of another column but then will not change thereafter. I also have an array formula set on the column the script is looking at for the edits and it appears the array formula is preventing the script from working properly. Here is the formula:
={"Triggered";arrayformula(IFS(E2:E="","",C2:C>=E2:E,"✅",TRUE,""))}
And this is the script:
function onEdit(e) {
var sh = e.source.getActiveSheet();
if(sh.getName() !== "Watchlist" || e.range.columnStart !== 8) return;// 1 is A, 2 is B, 3 is C, etc
var o = e.range.offset(0, 1)
if(!o.getValue()) o.setValue(new Date())
}
Any help with what I'm doing wrong is appreciated. Thanks.
Unfortunately, according to the official documentation :
An installable edit trigger runs when a user modifies a value in a
spreadsheet.
Even when the output of the arrayformula is updated, the cell still contains the same formula. Therefore, the onEdit trigger won't fire since there wasn't any edit action by the user.
Read also the discussion here.

Google Apps Script: Capture timestamp/email of logged in user who has updated a field in a specific column

I have created a Google Sheet that is shared with multiple people within my organization. It will not be shared with anyone outside the company. On said spreadsheet, when a user checks the box in column 1, I would like to put a timestamp in column 2, and the logged in user's email in column 3.
The timestamp works; and the email works when I do it; but it only works for me. I have tried, deploying as a webapp (executing as the user accessing the app), deploying as a API Executable, all to no avail.
I suspect it's due to trying to trigger this from onEdit, since they may think I'm trying to harvest something that the user isn't releasing to me intentionally. Since we're all in the same company, and it's not ill intended; I'm thinking there must be a solution. A function which stores the logged in user, and another function that gets this value onEdit?
in the code I've pasted, I have it checking for values greater than 5, as I was unclear how to check for checkbox=TRUE.
Any advice?
function onEdit() {
var s = SpreadsheetApp.getActiveSheet();
var email = Session.getActiveUser().getEmail();
Logger.log(email);
var r = s.getActiveCell();
if( r.getColumn() == 1) {
if(r.getValue()>5){
var nextCell = r.offset(0, 2);
nextCell.setValue(new Date());
var emailCell = r.offset(0, 3);
emailCell.setValue(email);}}
}
I expect any user within my organization, to check the box in column 1, and the time they checked it appears in column 2; and their email address shows up in column 3.
Try using an installable onEdit trigger.

delete entire row if any cell is empty

Just like the title says. I found a solution if one column is blank, but not if any are blank.
I crafted this with the help of another post, though I don't have a clue re: google scripts.
function onEdit(e) {
//Logger.log(JSON.stringify(e));
//{"source":{},"range":{"rowStart":1,"rowEnd":1,"columnEnd":1,"columnStart":1},"value":"1","user":{"email":"","nickname":""},"authMode":{}}
try {
var ss = e.source; // Just pull the spreadsheet object from the one already being passed to onEdit
var s = ss.getActiveSheet();
// Conditions are by sheet and a single cell in a certain column
if (s.getName() == 'Sheet1' && // change to your own
e.range.columnStart == 1 && e.range.columnEnd == 99 && // only look at edits happening in col C which is 3
e.range.rowStart == e.range.rowEnd ) { // only look at single row edits which will equal a single cell
checkCellValue(e);
}
} catch (error) { Logger.log(error); }
};
function checkCellValue(e) {
if ( !e.value || e.value == 0) { // Delete if value is zero or empty
e.source.getActiveSheet().deleteRow(e.range.rowStart);
}
}
problem is, I have no idea how to actually "use" it
Demo of the setup.
e.range.columnStart and e.range.columnEnd need to be equal to each other in this case
In the spreadsheet that you'd like to use this in, click on Script Editor in the Tools menu. Select Blank Project in the dialog that comes up, and then replace the code in the window with the code you've posted above. Save and name your project, then click Current Project's Triggers in the Resources menu. Click the link to add a new trigger. You'll see a series of drop down boxes, select the function (onEdit()), From Spreadsheet (the event source), and "On Edit" (the event). You have the option to set failure notifications. Click save to save the trigger. You'll be prompted to provide authorization, once you do, the script should run as expected.