Automatically stamp username who made changes to Google Sheet - google-sheets

I have a Google Sheet that I would like to automatically stamp the username of the person who last made a change to a specific row. I currently have this code to work as I like to do the same function with the time:
function onEdit() {
var s = SpreadsheetApp.getActiveSheet();
var r = s.getActiveCell();
if( r.getColumn() != 2 ) { //checks the column
var row = r.getRow();
var time = new Date();
time = Utilities.formatDate(time, "GMT-07:00", "yyyy-MM-dd, hh:mm:ss");
SpreadsheetApp.getActiveSheet().getRange('G' + row.toString()).setValue(time);
};
};
Assuming this is somewhat close to what I require for the username, I tried using this:
function onEdit() {
var s = SpreadsheetApp.getActiveSheet();
var r = s.getActiveCell();
if( r.getColumn() != 2 ) { //checks the column
var row = r.getRow();
var time = new Date();
time = Utilities.formatDate(time, "GMT-07:00", "yyyy-MM-dd, hh:mm:ss");
SpreadsheetApp.getActiveSheet().getRange('H' + row.toString()).setValue(Session.getActiveUser);
};
};
But that spits out some weird command that is clearly broken.
How can I do this?
This is the sheet I am working on: https://docs.google.com/spreadsheets/d/1VifU8AJWuPn53-_JCQKbPTjHxKDArkyG0G7zt1wzmPg/edit?usp=sharing

Is this what you are trying to do?
function onEdit(e) {
var r = e.range;
if( r.getColumn() != 2 ) { //checks the column
var time = new Date();
time = Utilities.formatDate(time, "GMT-07:00", "yyyy-MM-dd, hh:mm:ss");
SpreadsheetApp.getActiveSheet().getRange(r.getRow(),8).setValue(Session.getActiveUser().getEmail());
}
}

Related

Revise the Google Script, It is not working after update

I'm using the script below as a Time Stamp and save the changes, so i can check how much changes has been done. The problem is now the script is not working after update v8?
Can anyone help with this, what is the issue with my script?
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = e.source.getActiveSheet();
var sheet = s.getName();
var rowIndex = e.range.getRowIndex();
var colIndex = e.range.getColumnIndex();
var actionCol1 = 14;
var tSheet = e.source.getSheetByName("History bg pending");
if(sheet=="Hard Live tracker"){
if(e.value != null && colIndex == actionCol1){
e.range.offset(0,9).setValue(new Date ()).setNumberFormat("MM/dd/yyyy hh:mm:ss");
var tRange = tSheet.getRange(tSheet.getLastRow()+1, 1, 1, colIndex+9);
var sRange = s.getRange(rowIndex, 1, 1, colIndex+10);
sRange.copyTo(tRange);
}
}}

How do i get the URL of a editable form response in spreadsheets

Im trying to get the url of a editable google form response to show up in google sheets,but it does not seem to be working.
I have seen Awesome Table and Ruben's example. Based of these 2 links and some others, they seem to be working for single form response sheets,but not multiple.
I tried this code 1st:
var formURL = 'https://docs.google.com/forms/d/__Your ID__/viewform';
var sheetName = '__Response sheet__';
var columnIndex = __column where it appears__;
function getEditResponseUrls() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
var data = sheet.getDataRange().getValues();
var form = FormApp.openByUrl(formURL);
for(var i = 2; i < data.length; i++) {
if (data[i][0] != '' && data[i][columnIndex-1] == '') {
var timestamp = data[i][0];
var formSubmitted = form.getResponses(timestamp);
if (formSubmitted.length < 1) continue;
var editResponseUrl = formSubmitted[0].getEditResponseUrl();
sheet.getRange(i+1, columnIndex).setValue(editResponseUrl);
}
}
}
2nd is:
// Form URL
var formID = '__Your ID__';
// Sheet name used as destination of the form responses
var sheetName = '__Response sheet__'';
/*
* Name of the column to be used to hold the response edit URLs
* It should match exactly the header of the related column,
* otherwise it will do nothing.
*/
var columnName = '__name of column where it appears__' ;
// Responses starting row
var startRow = 2;
function getEditResponseUrls(){
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues();
var columnIndex = headers[0].indexOf(columnName);
var data = sheet.getDataRange().getValues();
var form = FormApp.openById(formId);
for(var i = startRow-1; i < data.length; i++) {
if(data[i][0] && !data[i][columnIndex]) {
var timestamp = data[i][0];
var formSubmitted = form.getResponses(timestamp);
if(formSubmitted.length < 1) continue;
var editResponseUrl = formSubmitted[0].getEditResponseUrl();
sheet.getRange(i+1, columnIndex+1).setValue(editResponseUrl);
}
}
}
Nothing is showing up, and when i check the logs for triggers, it is all working fine, no failures.I have tried putting the global variables within the function, but no changes.
The following points are taken from the latest version from #Rubén latest version on github. This code is a thing of beauty and a joy to behold. Combined with Rubén's detailed instructions, this answer can be setup and running in less than 5 minutes.
change
var formID = '__Your ID__';
to
var formURL = 'https://docs.google.com/forms/d/ -insert id - /edit';
you get the URL from the Forms Editor page.
change
var columnName = 'Form URL';
to
var sheetName = 'URL'; // Column U
replace getEditResponseUrls entirely
function getEditResponseUrls(){
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues();
var columnIndex = headers[0].indexOf(columnName);
var data = sheet.getDataRange().getValues();
var form = FormApp.openByUrl(formURL);
for(var i = startRow-1; i < data.length; i++) {
if(data[i][0] != '' && data[i][columnIndex] == '') {
var timestamp = data[i][0];
var formSubmitted = form.getResponses(timestamp);
if(formSubmitted.length < 1) continue;
var editResponseUrl = formSubmitted[0].getEditResponseUrl();
sheet.getRange(i+1, columnIndex+1).setValue(editResponseUrl);
}
}
}
Remember to set the installable trigger.
In the Google Sheet that you have linked from the question above, you have declared two functions with the same name and this could be a reason why the first one may never be executing. I tested this code and it seemed to work.
You may want to replace everything in the file with just this code.
var id = '1SdSPhOwi1dWQzRsNpA9zFL-ODorgohST3TMRJLqz16I';
var sheetName = 'Order Information';
var columnIndex = 21;
function getEditResponseUrls() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
var data = sheet.getDataRange().getValues();
var form = FormApp.openById(id);
for(var i = 2; i < data.length; i++) {
if (data[i][0] != '' && data[i][columnIndex-1] == '') {
var timestamp = data[i][0];
var formSubmitted = form.getResponses(timestamp);
if (formSubmitted.length < 1) continue;
var editResponseUrl = formSubmitted[0].getEditResponseUrl();
sheet.getRange(i+1, columnIndex).setValue(editResponseUrl);
}
}
}

How do I make my script work only in specific rows?

I have an automated time stamp script that works when clicking a checkbox, a time stamp is populated in the cell next to it. How do I make my script work on certain rows?
Example: Column C has check boxes, Column D is populated with dates when Check boxes are marked.
What I want my TimeStamp script to do:
Work only on Row 11, all the way down.
var COLUMNTOCHECK = 3;
var DATETIMELOCATION = [0, 1];
var SHEETNAME = 'Training Dash'
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
if( sheet.getSheetName() == SHEETNAME ) {
var selectedCell = ss.getActiveCell();
if (selectedCell.getColumn() >= COLUMNTOCHECK && selectedCell.getColumn() % 2 == 1) {
var dateTimeCell = selectedCell.offset(DATETIMELOCATION[0],DATETIMELOCATION[1]);
dateTimeCell.setValue(new Date());
}
}
}
if I understood correctly, this should help.
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
if( sheet.getSheetName() == SHEETNAME ) {
var selectedCell = ss.getActiveCell();
if (selectedCell.getColumn() >= COLUMNTOCHECK && selectedCell.getColumn() %
2 == 1 && selectedCell.getRow() > 10) {
var dateTimeCell =
selectedCell.offset(DATETIMELOCATION[0],DATETIMELOCATION[1]);
dateTimeCell.setValue(new Date());
}
}
}

Wanting auto sort on 3 sheets, when one is locked

Please see the previous post on this question;
Auto Sort not working on Multiple Sheets within one Google Sheet
Here's the good script from that last session;
function onEdit(event){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = event.source.getActiveSheet().getName()
var editedCell = event.range.getSheet().getActiveCell();
if(sheet=="Loan Inquiries"){
var columnToSortBy = 2;
var tableRange = "A3:G99"; //range to be sorted
if(editedCell.getColumn() == columnToSortBy){
var range = ss.getActiveSheet().getRange(tableRange);
range.sort( { column : columnToSortBy, ascending: true } );
}}
else if(sheet=="Deals in Escrow"){
var columnToSortBy = 7;
var tableRange = "A3:I99"; //range to be sorted
if(editedCell.getColumn() == columnToSortBy){
var tableRange = "A3:I99"; //range to be sorted
var range = ss.getActiveSheet().getRange(tableRange);
range.sort( { column : columnToSortBy, ascending: true } );
}
else{return}
}}
function test_onEdit() {
onEdit({
user : Session.getActiveUser().getEmail(),
source : SpreadsheetApp.getActiveSpreadsheet(),
range : SpreadsheetApp.getActiveSpreadsheet().getActiveCell(),
value : SpreadsheetApp.getActiveSpreadsheet().getActiveCell().getValue(),
authMode : "LIMITED"
});
}
This thread successfully resolved my question, however, now what I want to do is to Auto Sort a 3rd Sheet, which is locked to others, but not to myself. The 3rd Sheet will be titled "Karlan Production for 2017". I also want this 3rd sheet to pull all new data from the 2nd Sheet "Deals in Escrow" and in the same formatting as the 2nd Sheet and to auto sort as the data is imported to the 3rd Sheet, but also be able for me to input new deals manually as well in the 3rd Sheet and still be able to auto update.
I believe this will do what you want:
function onEdit(event){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = event.source.getActiveSheet().getName()
var editedCell = event.range.getSheet().getActiveCell();
if(sheet=="Loan Inquiries"){
var columnToSortBy = 2;
var tableRange = "A3:G99"; //range to be sorted
if(editedCell.getColumn() == columnToSortBy){
var range = ss.getActiveSheet().getRange(tableRange);
range.sort( { column : columnToSortBy, ascending: true } );
}}
else if(sheet=="Deals in Escrow"){
var columnToSortBy = 7;
var tableRange = "A3:I99"; //range to be sorted
if(editedCell.getColumn() == columnToSortBy){
var range = ss.getActiveSheet().getRange(tableRange);
range.sort( { column : columnToSortBy, ascending: true } );
combineData()
}}
else if(sheet=="Karlan Production for 2017"){
var columnToSortBy = 7;
if(editedCell.getColumn() == columnToSortBy){
combineData()
}}
else{return}
}
function combineData(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s=ss.getSheets()[1]
var lr = s.getLastRow()
var s1=ss.getSheets()[2]
var lr1 = s1.getLastRow()
var lc1=s1.getLastColumn() //get the last column of 'Karlan Production for 2017'
var rng=s.getRange(3, 1, lr,lc1).getValues() //get 'Deals in Escrow' values
var rng1=s1.getRange(3, 1, lr1,lc1).getValues() //get 'Karlan Production for 2017' values
var rng2=[]
var rng2=rng.concat(rng1) //combine 'Deals in Escrow' and 'Karlan Production for 2017' values (all rows)
removeDuplicates(rng2) // call remove duplicates sending combined array
}
function removeDuplicates(data) {
var ss = SpreadsheetApp.getActiveSpreadsheet()
var s1=ss.getSheets()[2]
var newData = new Array();
for(i in data){
var row = data[i];
var duplicate = false;
for(j in newData){
if(row.join() == newData[j].join()){
duplicate = true;
}
}
if(!duplicate){
newData.push(row);//create array of non duplicate rows
}
}
s1.clearContents(); //clear 'Karlan Production for 2017'
var sor=s1.getRange(3, 1, newData.length, newData[0].length).setValues(newData); //set new array
sor.sort( { column : 7, ascending: true } );//sort new data
}
After adding the new sheet, click the arrow on the sheet tab.
Click Protect Sheet. In the popup, enter a description and click
the Sheet button. Click the Set permissions button. In the Range
editing permissions popup click the arrow by 'Only you'. Select
'Custom' and add the email address of the other person you want
to be able to edit the sheet. Click done.

Google Script send email from a sheet in a specific date

follow script is used to get a date from a google sheet and if this date is equal to today or tomorrow generate an automatic email to my address in order to remind me.
function getVal() {
var ss = SpreadsheetApp.getActiveSpreadsheet(),
sheet = ss.getActiveSheet();
sheet.setActiveRange(sheet.getRange("A1"));
var range = sheet.getDataRange(),
formulas = range.getValues();
var toDay = new Date();
for (var r=0; r<formulas.length; r++) {
for (var c=0; c<formulas[r].length; c++) {
//var value = sheet.getRange(r,c).getValue();
var value = range.getCell(r, c).getValue();
Logger.log(value);
if (value == "AAAA")
{
var index = r+2;
value = sheet.getRange(index,c).getValue();
while (value != "" || index >= formulas.length)
{
if (DateDiff.inDays(value,toDay)==1 || DateDiff.inDays(value,toDay)==0)
{
MailApp.sendEmail(myAdress,subject, text);
}
index = index + 3;
value = sheet.getRange(index,c).getValue();
}
}
}
}
}
var DateDiff = {
inDays: function(d1, d2) {
var t2 = d2.getTime();
var t1 = d1.getTime();
return parseInt((t2-t1)/(24*3600*1000));
},
inWeeks: function(d1, d2) {
var t2 = d2.getTime();
var t1 = d1.getTime();
return parseInt((t2-t1)/(24*3600*1000*7));
},
inMonths: function(d1, d2) {
var d1Y = d1.getFullYear();
var d2Y = d2.getFullYear();
var d1M = d1.getMonth();
var d2M = d2.getMonth();
return (d2M+12*d2Y)-(d1M+12*d1Y);
},
inYears: function(d1, d2) {
return d2.getFullYear()-d1.getFullYear();
}
}
when i run the script it fail in the line :
var value = range.getCell(r, c).getValue();
have you any suggestion in order to fix this bug?
thanks
Mario
try to change the line with:
var value = formulas[r][c]
it should also do less request to google spreadsheet and run faster.

Resources