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.
Related
Trying to get an Appscript to run but I can't seem to figure out the last few steps.
Background: I have a Google Sheet with two tabs, #1 is called "Data Form" which hosts a fillable form to capture Transaction information to then be input onto tab #2 called "Posted Transactions". This is a personal budget spreadsheet..
Anyways, The script below is intended to take the information input on the "Data Form", verify what the last row with data is on the "Posted Transactions" tab based on whether or not Column A has any data. (To further clarify, the "Posted Transactions" tab has formulas in columns G-I which prohibits me from using a simple "Find last Row" script.)
As it is written now, I receive an error "Exception: The number of columns in the data does not match the number of columns in the range. The data has 6 but the range has 1.
RecordNewTransaction # Code.gs:24"
Any suggestions to make this work properly?
UPDATE:
var dataRange = datasheet.getRange(lastRow+1,1,1,datasheet.getLastColumn()-3);
After many attempts at trial and error, I needed to edit the line shown above. Current & full script is performing as expected now and is shown below. Image snips of what I was trying to accomplish are also shown for reference.
function RecordNewTransaction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var formSS = ss.getSheetByName("Data Form"); //Form Sheet
var datasheet = ss.getSheetByName("Posted Transactions"); //Data
//Input Values
var values = [[formSS.getRange("B4").getValue(),
formSS.getRange("B6").getValue(),
formSS.getRange("B8").getValue(),
formSS.getRange("B10").getValue(),
formSS.getRange("B12").getValue(),
formSS.getRange("B14").getValue()]];
var columnToCheck = datasheet.getRange("A:A").getValues();
var lastRow = getLastRowSpecial(columnToCheck);
Logger.log(lastRow);
var dataRange = datasheet.getRange(lastRow+1,1,1,datasheet.getLastColumn()-3);
Logger.log(dataRange);
var dataValues = dataRange.getValues();
Logger.log(dataValues);
dataRange.setValues(values);
Logger.log(dataRange.setValues(values))
formSS.getRange('B4:B14').clearContent();
};
function getLastRowSpecial(range){
var rowNum = 0;
var blank = false;
for(var row = 0; row < range.length; row++){
if(range[row][0] === "" && !blank){
rowNum = row;
blank = true;
}else if(range[row][0] !== ""){
blank = false;
};
};
return rowNum;
};
Try
var dataRange = datasheet.getRange(lastRow,1,values.length,values[0].length)
replace 1 as necessary (this is the firts column where the data will be stored
Reference:
getRange(row, column, numRows, numColumns)
See edited question above which contains the revised script needed.
The problem here was that columns G-I of my results sheet contain formulas (shown in grey) which required this line below to be modified to grab the last column -3, otherwise the script was looking at too many columns that it didn't need to. Also had to modify "lastRow" to "lastRow+1" because this kept overriding the very last line of data I already had input and the +1 will make new data go to the next available row.
var dataRange = datasheet.getRange(lastRow+1,1,1,datasheet.getLastColumn()-3);
I have a Google Sheet that links to a Google Form and on each response the information is directed to the relevant team by email.
Recently, a VLookup was added to the sheet (in the end column) which has thrown off the script as it currently displays a "N/A" error (which will remain until the linked sheet has information added to it).
I am trying to limit the number of columns that the script looks at, in the hopes that this error will no longer affect the running of my script - however I'm not sure of the best way to enter the range...nothing seems to be working. This is what I currently have, where EM is the last column that my form data is in before the vlookup...
var sheet = SpreadsheetApp.getActive().getSheetByName("Form responses 1");
var range = sheet.getDataRange("A:EM");
var values = range.getValues();
var lastRow = range.getLastRow();
var lastRowValues = values[lastRow-1];
Logger.log(lastRowValues);
I have tried adding A1:EM but that doesn't seem to work either so I assume I am using the wrong "get"?
Solution:
var sheet = SpreadsheetApp.getActive().getSheetByName("Form responses 1");
var range = sheet.getDataRange();
var values = range.getValues();
var lastRow = range.getLastRow();
var lastRowValues = values[lastRow-1];
Logger.log(lastRowValues);
Explanation:
You have two options:
Use getDataRange() with no parameters:
sheet.getDataRange();
Or use getRange("A:EM") to specify the exact range:
sheet.getRange("A:EM");
References:
getRange
getDataRange
getDataRange() does not require parameters
Try this instead:
function myfun() {
var sheet = SpreadsheetApp.getActive().getSheetByName("Sheet0");
var range = sheet.getRange("A:EM");
var values = range.getValues();
var lastRow = range.getLastRow();
var lastRowValues = values[lastRow-1];
Logger.log(lastRowValues);
}
Does anyone have an idea of why my code is throwing the "Service Spreadsheets failed while accessing" error? I've read that this is usually caused by a large dataset, but all the datasets involved here are tiny. For whatever reason, the error is being thrown on line 6. I'm new to both Apps Script and Javascript, but I don't think this code should take very long to run at all. The function simply aims to take values from one sheet and drop them into their corresponding place on another sheet -- I've used formulas in the sheet to find the column number (that is the column_nums var) although ideally I would find an all-script solution. The reason I'm doing this through script and not a simple index match is because I want the values from sheet A to be updated over time and use sheet B to periodically (on a trigger) paste in sheet A's values to track them over time. Apologies if this is a basic question, thanks so much!
function export_maxes() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var source = ss.getSheets()[0];
var destination = ss.getSheets()[1];
var new_maxes = source.getRange("E1").getDataRegion(SpreadsheetApp.Dimension.ROWS).getValues();
var column_nums = source.getRange("A1").getDataRegion(SpreadsheetApp.Dimension.ROWS).getValues();
// find row
var row_num = destination.getRange("B1").getDataRegion(SpreadsheetApp.Dimension.ROWS).getHeight();
var row_num = row_num + 1;
// find columns and input maxes. start at 1 bc data has headers
for (var i = 1; i < new_maxes.length; i++) {
destination.getRange(row_num, column_nums[i]).setValue(new_maxes[i])
}
};
There is ongoing issue tracker for "getDataRegion failed when it faces hidden rows or columns". Alternative solution is to show the hidden column groups by using method:expandAllColumnGroups() and hide the column after you fetched the data by using method:collapseAllColumnGroups()
Your code should look like this.
function export_maxes() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var source = ss.getSheets()[0];
var destination = ss.getSheets()[1];
source.expandAllColumnGroups();
var new_maxes = source.getRange("E1").getDataRegion(SpreadsheetApp.Dimension.ROWS).getValues();
var column_nums = source.getRange("A1").getDataRegion(SpreadsheetApp.Dimension.ROWS).getValues();
// find row
var row_num = destination.getRange("B1").getDataRegion(SpreadsheetApp.Dimension.ROWS).getHeight();
source.collapseAllColumnGroups();
var row_num = row_num + 1;
// find columns and input maxes. start at 1 bc data has headers
for (var i = 1; i < new_maxes.length; i++) {
destination.getRange(row_num, column_nums[i]).setValue(new_maxes[i])
}
};
References:
expandAllColumnGroups
collapseAllColumnGroups
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");
I have been searching for a way to copy certain cells from a row and paste them into another spreadsheet, but all I can seem to find are ways to do that just from sheet to sheet within one spreadsheet or questions that deal with code way above my head. I'm just now learning to code in Google Spreadsheets and I can't seem to get it right. Here is my code for now, I'm working on just copying one cell first and after I can do that I'll get a loop to iterate through the row and pick the cells I want to copy.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var master = SpreadsheetApp.openById('0AgcCWQn-aoI1dFpLVE4tSENwcThrYnlMUzhuRmdWU2c');
var target = SpreadsheetApp.openById('0AgcCWQn-aoI1dF96X2dBT2dVVFZ2SU1NRWdYTDJhT2c');
var master_sheet = master.getSheetByName("Steve2");
var target_sheet = target.getSheetByName("Corbin1");
var master_range = master_sheet.getRange("A1");
var target_range = target_sheet.getRange("A1");
master_range.copyTo(target_range);
Right now it is giving me an error saying that it cannot call the getRange method of null. I'm not sure if I'm using OpenById correctly or if I can even use that in this situation.
OK I've got it working now. It copies the row perfectly and it copies only the cells I want. Now I need help with the pasting part. It copies everything fine and puts it into the other sheet great, but I need it to copy into the next available row and into the first available columns. So if row 5 is the last column of data, I need it to paste into row 6 and take up the first 6 or so columns.
This is what I have so far.
function menuItem1() {
var sss = SpreadsheetApp.openById('0AgcCWQn-aoI1dFpLVE4tSENwcThrYnlMUzhuRmdWU2c'); // sss = source spreadsheet Steve2
var ss = sss.getSheetByName('Sheet1'); // ss = source sheet
//Message box asking user to specify the row to be copied
var answer = Browser.inputBox('What row would you like to copy?');
var range = parseInt(answer);
var array = [1,2,3,9,12,30];
//Runs a loop to iterate through array, using array elements as column numbers
for(var i = 0; i < array.length; i++){
var SRange = ss.getRange(answer,1,1,array[i]);
//get A1 notation identifying the range
var A1Range = SRange.getA1Notation();
//get the data values in range
var SData = SRange.getValues();
}
var tss = SpreadsheetApp.openById('0AgcCWQn-aoI1dF96X2dBT2dVVFZ2SU1NRWdYTDJhT2c'); // tss = target spreadsheet Corbin1
var ts = tss.getSheetByName('Sheet1'); // ts = target sheet
//set the target range to the values of the source data
ts.getRange(A1Range).setValues(SData);
//Confirmation message that the row was copied
Browser.msgBox('You have successfully copied Row: ' + answer);
}
You are getting this error maybe because your spreadsheet does not have a sheet called Steve2 or Cobin1. Try using the method master.getSheets()[0], this way you will get the first sheet without using their name.
You can algo use this piece of code to check the sheets names:
for(var x in master.getSheets()) {
Logger.log(master.getSheets()[x].getSheetName());
}
best,