I am trying to run a script that auto-populates the date in column F whenever data is entered or changed in column E in a spreadsheet with multiple sheets.
I currently have a script which was written for me based on what I described but I was getting an error code. I went back to my original question and explained that this script was needed to run on a single sheet within a spreadsheet with multiple sheets. He gave me some additional information but this was his last answer "yes, you will need to replace event.source.getActiveSheet() with something like "getsheetbyname". I have tried everything that is within my limited knowledge to work with what he gave me but I am still getting an error code no matter what I try.
Here is the area that is giving me the error.
var sheet = event.source.getsheetbyname();
Here is the error code I am receiving
TypeError: Cannot read property "source" from undefined. (line 2, file "Code")
I am aware that there needs to be the name of the sheet I am wanting the script to run on but I do not know how to code it to do so. The name of the sheet is "Juvenile weights"
The expected results should be when I add or change the data in column E it should auto-populate the current date into the adjacent cell in the adjacent column.
When I save the script and then run the script to make sure it's working, of course, it gives me the error code I described above. Then when I go back to that sheet after saving the script instead of auto-populating the date, now when I highlight a string of cells in a row it changes all the following cells to the same information I have in the first cell I started highlighting. Very odd!
The script + error code:
The code:
function onEdit(event) {
var sheet = event.source.getActiveSheet();
// note: actRng = the cell being updated
var actRng = event.source.getActiveRange();
var index = actRng.getRowIndex();
var cindex = actRng.getColumnIndex();
if (cindex == 5) { // 1 == Column A, 2 == Column B, 3 == Column C, etc.
var dateCol = sheet.getLastColumn();
var lastCell = sheet.getRange(index,dateCol);
var date = Utilities.formatDate(new Date(), "EST", "MMM-dd-yyyy");
lastCell.setValue("'" + date);
}
}
I believe this does the same thing:
function onEdit(e) {
var sheet = e.range.getSheet();
if (e.range.columnStart == 5) {
sheet.getRange(e.range.rowStart,sheet.getLastColumn()).setValue("'" + Utilities.formatDate(new Date(), "EST", "MMM-dd-yyyy HH:mm:ss"));
}
}
Is there a reason you aren't using SpreadsheetApp.getActiveSheet().getSheetByName("Juvenile weights");
Related
I am trying to move a row of data from one sheet to another, when a specific value is recorded in a specific column.
I have found and adapted the following code to use in the Apps Script:
function onEdit(event) {
// assumes source data in sheet named Responses
// target sheet of move to named Completed
// test column with yes/no is col Y or 25
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "Responses" && r.getColumn() == 25 && r.getValue() == "yes") {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("Completed");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
}
}
I have tested this on a copy of this data and it has worked fine. However, when using the original, nothing happens, when yes is entered in column Y. I have listed below some reasons why I think this may be occurring:
This is a shared sheet, I am not the owner. The owner has granted permissions
The responses sheet is connected with a Google Form
P.S. The following error appears when the script is executed from the editor, I don't believe this is an issue based on the type of trigger, it also appeared on my test and had no impact
TypeError: Cannot read property 'source' of undefined
onEdit # Code.gs:6
I would appreciate any suggestions on workarounds!
In order to help you to debug your script, just after function onEdit(event) { add a the following line:
console.log(JSON.stringify(event,null,' '));
The above will print the event object "printable" properties on the execution logs. This will allow you to validate, first, that the function is actually triggered when the spreadsheet is edited by using the Google Sheets UI, second, the coordinates of the edited cell as well the value entered into edited cell.
The coordinates will be shown as properties rowStart, columnStart, rowEnd, columnEnd.
Also you might find helpful to add the following line before the if statement.
console.log(s.getName());
NOTE: The error "Cannot read property 'source' of undefined" occurs when the onEdit function is run from the script editor as the event object is undefined.
Related
How can I test a trigger function in GAS?
How to run a function when specific range is edited
I would like to automatically protect columns where a header row contains a date based on whether the date in the google sheet app script
Here is a screenshot of the sheet:.
I have tried and created a script that can work but it showing an error in getting last column please suggest if any edit needs to be done I am also attaching the screen shot of the error please check it out also
Script -
function Lock_Cells() {
var ss= SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Sheet 1');
var lastcolum = sheet.getLastColumn();
for (var i = 3; i <= lastcolum; i++){
var today = sheet.getRange(0,3).getValue();
var Check_date = sheet.getRange(5,i).getValue();
if (Check_date < today){
var Lock_Range = sheet.getRange(5,i,50);
var protection = sheet.getRange(Lock_Range).protect();
var description = "colum " + i;
protection.setDescription(description);
var eds = protection.getEditors();
protection.removeEditors(eds);
}}}
Screenshot of error -
Thanks to you that problem is solved and now the sheet is showing the last column but now when I run the function it is showing an error and is not completing the script I have attached the screenshot of the error and the error showing is -
Error Exception: The starting row of the range is too small. Lock_Cells # Code.gs:11
Screenshot https://i.stack.imgur.com/fDK9g.png
The error showed in the screenshot (Cannot read property 'getLastColumn' from null) occurs because the spreadsheet hasn't a sheet named Sheet 1 (var sheet = ss.getSheetByName('Sheet 1');). To fix this error replace 'Sheet 1' by the correct sheet name.
The code has other errors too:
var today = sheet.getRange(0,3).getValue();
getRange requires values equal or greater than 1
var Lock_Range = sheet.getRange(5,i,50);
var protection = sheet.getRange(Lock_Range).protect();
getRange can't use a Class Range object as argument. Please checkout https://developers.google.com/apps-script/reference/spreadsheet/sheet for the valid arguments for getRange.
This code works fine when data is edited in Column 3 or being copy-pasted but if the cursor remains at column 1 at the time of the whole row being copy/pasted, it won't update and secondly, if salesforce sends data to column 3, it doesn't work that time too, please help me here.
function onEdit() {
var s = SpreadsheetApp.getActiveSheet();
var sName = s.getName();
var r = s.getActiveCell();
var row = r.getRow();
var ar = s.getActiveRange();
var arRows = ar.getNumRows()
// Logger.log("DEBUG: the active range = "+ar.getA1Notation()+", the number of rows = "+ar.getNumRows());
if( r.getColumn() == 3 && sName == 'Sheet1') { //which column to watch on which sheet
// loop through the number of rows
for (var i = 0;i<arRows;i++){
var rowstamp = row+i;
SpreadsheetApp.getActiveSheet().getRange('F' + rowstamp.toString()).setValue(new Date()).setNumberFormat("MM/dd/yyyy hh:mm"); //which column to put timestamp in
}
}
}//setValue(new Date()).setNumberFormat("MM/dd/yyyy hh:mm:ss");
Explanation:
Three important things to know:
As it is also stated in the official documentation, the onEdit triggers are triggered upon user edits. This function won't be triggered by formula nor another script. If salesforce or any other service except for the user, edits column C the onEdit trigger is not going to be activated. Workarounds exist, but these workarounds depend on the context of your specific problem. I would advice you to search or ask a specific question about it.
Regarding the other issue you have, you should get rid of active ranges and take advantage of the event object. This object contains information regarding the edit/edits user made.
As it is recommended by the Best Practices you should not set values in the sheet iteratively but you can to that in one go by selecting a range of cells and set the values. In your case, you want to set the same value in all of the cells in the desired range, hence setValue is used instead of setValues. But the idea is to get rid of the for loop.
Solution:
function onEdit(e) {
var s = e.source.getActiveSheet();
var sName = s.getName();
var ar = e.range;
var row = ar.getRow();
var arRows = ar.getNumRows()
if( ar.getColumn() == 3 && sName == 'Sheet1') {
s.getRange(row,6,arRows).setValue(new Date()).setNumberFormat("MM/dd/yyyy hh:mm");
}
}
Note:
Again, onEdit is a trigger function. You are not supposed to execute it manually and if you do so you will actually get errors (because of the use of the event object). All you have to do is to save this code snippet to the script editor and then it will be triggered automatically upon edits.
I'll start this off by saying I have no clue what I'm doing. I'm surviving off copying and pasting code off the internet for a spreadsheet me and my friends use for watching films together.
I've run into an issue where I'm updating a cell with the current date when another cell in that row is updated if its blank with a script.
This issue is I then use a function in the cell next to it to give the difference in days for another date marked down in a cell (like a normal spreadsheet as that easier for me to do). But every time the script runs the function breaks and is replaced with the text "#NUM!" (Actually has that text as the function disappears from inside it).
I tried changing it to =U2 and that breaks also. Is this something that can't be done? The great almighty google god has not provided me with an answer so I've made an account here in hope of salvation.
tl;dr Scrips look like they are breaking my cell references for any sheet function that looks at cells they edit. How stop?
In cell V2 I have the function =DATEDIF(S2,U2,"D")
Script bellow (I know not how to format)
function onEdit(event) {
var eventRange = event.range;
var sheetName = SpreadsheetApp.getActiveSheet().getSheetName();
if (sheetName == "Scores") {
if (eventRange.getColumn() == 10) { //Check which is updated
var columnXRange = SpreadsheetApp.getActive().getSheetByName("Scores").getRange(eventRange.getRow(), 21, eventRange.getNumRows(), 21);//where to write
var values = columnXRange.getValues();
for (var i = 0; i < values.length; i++) {
if (!values[i][0]) { // If cell isn't empty
values[i][0] = new Date();
}
}
columnXRange.setValues(values);
}
}
}
Ok, I see the problem. You are looking at a way bigger range than you want with
var columnXRange = SpreadsheetApp.getActive().getSheetByName("Scores").getRange(eventRange.getRow(), 21, eventRange.getNumRows(), 21);
You only really need the value of one cell to check if it is empty. Try replacing your function with :
function onEdit(event) {
var eventRange = event.range;//makes shit happen?
var sheetName = SpreadsheetApp.getActiveSheet().getSheetName();//checks current shit
if (sheetName == "Scores") {//name of sheet want shit to happen
if (eventRange.getColumn() == 10) { // 1 is column A, 2 is B ect
// getRange(row, column, numRows, numColumns) sheet name to make not everywhere
var columnXRange = SpreadsheetApp.getActive().getSheetByName("Scores").getRange(eventRange.getRow(), 21, 1, 1);//num is where will write 1 is a ect
var values = columnXRange.getValues();//takes all shit from above to use as range
if (!values[0][0]) { // If cell isn't empty
values[0][0] = new Date();//set date to the vaules in the range
}
columnXRange.setValues(values); //use the values set above and write them in
}
}
}
..and that should fix your problem. The problem with your current script is that the script is copying the "value" of your column v cells and replacing it with just a text value. This limits the range you are grabbing to just the cell you need, eliminates the for() loop, and steps over the problem entirely.
I am brand new to writing code and I am fumbling through this trying to come up with a spreadsheet that is fed info from a form. I have searched and searched for the answer to this problem for days but I cannot figure it out on my own without some help..so HELP! :)
What my script does it creates a copy of a sheet based on a trigger every night so that I have a record of form responses for each day. I want to to delete (not clear) all rows except the top 6 rows each time a new sheet is created so the form will add lines each time a response is given. I keep getting the Those rows are out of bounds. (line 17, file "DailyClear") when I try to run the script.
Here is what I've got
function dailyclear(e)
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Today');
sheet.copyTo(ss)
var nusheet = ss.getSheetByName('Copy of Today')
var value = nusheet.getRange("B2").getCell(1,1).getValue()
SpreadsheetApp.setActiveSheet(nusheet)
Logger.log("Current index of sheet: %s", nusheet.getIndex())
ss.moveActiveSheet(2);
nusheet.setName(value);
//Clear "Today"
var lastrow = sheet.getLastRow()
sheet.deleteRows(7, lastrow-6)
//Set Date Value for "Today"
var dd = Utilities.formatDate(new Date(), "GMT-5", "MM/dd/yy");
sheet.getRange("B2").getCell(1,1).setValue(dd);
}
It will not allow me to delete the 7th row and retain rows 1-6 without throwing that error if the 7th row is blank and the only row that exists. If I start adding information from form responses in the cells and it starts creating rows and I run the script it throws up the error Sorry, it is not possible to delete all non-frozen rows. (line 17, file "DailyClear"). And on top of all that when a new sheet is created I have the 7th row clear ready for the first response from the form to fill and the form puts the first response of the day on row 8 and leaves 7 blank! This is driving me crazy...anyone recommend a good book for beginners before I go crazy? :( Thanks for any help I can get, here is a link to my sheet..
https://docs.google.com/spreadsheets/d/1NZxXjMptx6ldzL2CKk6OwJcq_heIv995ZGVeIE59xNc/edit?usp=sharing
Thank you to anyone who can help
As noted already, you cannot delete all non-frozen rows, so Row 7 will have to stay. Perhaps shrink it down and add a fill or some formatting so it just doesn't look like an empty row, and then since data is entered on row 8 anyway, change your script slightly to accomodate:
function dailyclear(e)
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Today');
sheet.copyTo(ss)
var nusheet = ss.getSheetByName('Copy of Today')
var value = nusheet.getRange("B2").getCell(1,1).getValue()
SpreadsheetApp.setActiveSheet(nusheet)
Logger.log("Current index of sheet: %s", nusheet.getIndex())
ss.moveActiveSheet(2);
nusheet.setName(value);
//Clear "Today"
var lastrow = sheet.getLastRow()
sheet.deleteRows(8, lastrow-7);
//Set Date Value for "Today"
var dd = Utilities.formatDate(new Date(), "GMT-5", "MM/dd/yy");
sheet.getRange("B2").getCell(1,1).setValue(dd);
}