I am getting this error: TypeError: Cannot call method "getName" of null. I have used a script to replace the formulas of the active sheet with the cell values. However, I don't want to accidentally run this on a few sheets, so I want to be able to exclude or include only specific sheets. I have been following another post and came up with this, and now I have the error:
function freezeValues() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
//loop through all sheets and get name to see if it includes specific string
for (i = 0; i < sheets.length; i++) {
var sheet = ss.getSheetByName(sheets[i]);
var name = sheet.getName();
if (name.includes("String_00")) {
//get active sheet and replace range with values
var sheetActive = ss.getActiveSheet();
var range = sheetActive.getRange("A1:Z50");
range.copyTo(range, {contentsOnly: true});
} else {
continue;
//skip over all those that don't meet the condition
}
}
}
UPDATE:
Trying this:
function freezeValues() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
//loop through all sheets and get name to see if it includes specific string
for (i = 0; i < sheets.length; i++) {
//var sheet = ss.getSheetByName(sheets[i]);
var name = sheets[i].getName().toString();
if (name.indexOf("String_00") > -1) {
//get active sheet and replace range with values
//var sheetActive = ss.getActiveSheet();
var range = sheets.getRange("A1:Z50");
range.copyTo(range, {contentsOnly: true});
} else {
continue;
//skip over all those that don't meet the condition
}
}
}
But now it doesn't do anything. using .include was giving me an error, so I moved over to .indexOf() > -1. Does not freeze data as expected for any sheet, regardless of name.
I came up with 2 solutions for this, sort of started from the drawing board. One creates an array, a sort of blacklist, and then if the sheet name contains any item in the blacklist, then it returns and doesn't execute the replacement. The second solution searches for a pattern in the sheet name and only then continues on to the replacement. Both accomplish what I was trying to do. I think the code I found was a bit buggy and was a bit complicated for what I was doing. I didn't need to loop through all sheet names, just check the sheet name against given variables. Anyway, here they are:
This one creates the array blacklist of pages not to edit:
function freezeValues() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ['Sheet1', 'Sheet2', 'Sheet3', 'Sheet4'];
var sheetActive = ss.getActiveSheet();
if (sheets.indexOf(sheetActive.getName()) > -1) return;
var range = sheetActive.getRange("A1:Z50");
range.copyTo(range, {contentsOnly: true});
}
This one only searches for specific text in the sheet name before proceeding with the replacement.
function freezeValues() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheetActive = ss.getActiveSheet();
var name = sheetActive.getName()
if (name.indexOf("String_00") > -1) {
var range = sheetActive.getRange("A1:Z50");
range.copyTo(range, {contentsOnly: true});
}
}
I'm sure there is a method to use sheet index value so if you want to skip the first 4 sheets, you can probably do that as well, so it doesn't call on names at all.
UPDATE
function freezeValues2() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheetActive = ss.getActiveSheet();
if (sheetActive.getIndex() > 4) {
var range = sheetActive.getRange("A1:Z50");
range.copyTo(range, {contentsOnly: true});
}
}
Related
I'm trying to get this code to work but keep getting a "TypeError: offset.copyTo is not a function". The script is supposed to take one value from sheet "Budget" and copy it into the next available row in column F on sheet "Projected".
I have tried playing around with syntax and other ways to copy but to now avail, any help would be greatly appreciated
function OffsetRecord() {
var sheet = SpreadsheetApp.openById("xx").getSheetByName("Budget");
var offset = sheet.getRange('I5').getValue();
var destSheet = SpreadsheetApp.openById("xx").getSheetByName("Projected");
var colF = destSheet.getRange('F:F').getValues();
var fcolF = colF.filter(function (e) {return e[0];});
var firstEmptyRowIncolF = fcolF.indexOf('')+1;
offset.copyTo(firstEmptyRowIncolF, {contentsOnly: true});
copyTo expects ranges as parameters, not values or column numbers, see here
Modify your code as following:
function OffsetRecord() {
var spreadsheet = SpreadsheetApp.openById("XX");
var sheet = spreadsheet.getSheetByName("Budget");
var offset = sheet.getRange('I5');//without ".getValue();"!
var destSheet = spreadsheet.getSheetByName("Projected");
...
firstEmptyRowIncolF = ...;
var destinationColumn = 1;
var range = destSheet.getRange(firstEmptyRowIncolF, destinationColumn);
offset.copyTo(range, {contentsOnly: true});
}
I have this script here, but I want it to only run on ONE specific sheet named "Nes Smart Data" (SheetNo5). Currently it runs on all sheets and puts the data on cells where I don't want them to be. Can you help me correct the code? Thanks a lot!
function onEdit(e){
var sheet = SpreadsheetApp.getActiveSheet();
var range = e.range;
var column = range.getColumn();
var row = range.getRow();
var text;
if (column==11) { //Replace 2 with the column number of your comments cell//
var newRange = sheet.getRange(row,column-5); //If the date is in the next column
var today = Utilities.formatDate(new Date(),Session.getScriptTimeZone(),'dd.MM.yyyy');
newRange.setValue(today);
}
if (column == 11){
text = sheet.getRange(row, 23).getValue();
sheet.getRange(row, 23).setValue(text + e.value+".");
}
}
Replace the following variable and things should work as desired -
Current:
var sheet = SpreadsheetApp.getActiveSheet();
Modification proposed:
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Nes Smart Data');
Let me know if it doesn't!
Hi I'm trying to have my spreadsheet include multiple timestamps across different tabs in this spreadsheet. Whenever data is edited in Column J, I want a timestamp to immediately populate in Column K. I have 4 sheets within the 1 Google Sheet, and I need all of them to have this automated timestamp running independently. Thanks for any help. I've tried looking to other posts, but have a difficult time modifying code from other people's docs to work for my own.
I was using the following script function to get this timestamp. It worked fine when I only had one tab to the google sheet. But now that I have multiple tabs it only updates one sheet. Trying to figure out how to get it to do the same thing across the whole doc.
function onEdit(event)
{
var timezone = "EST";
var timestamp_format = "MM-dd-yyyy HH:mm:ss"; // Timestamp Format.
var updateColName = "PM Status ";
var timeStampColName = "Date Update";
var sheet = event.source.getSheetByName('Walt'); //Name of the sheet where you want to run this script.
var actRng = event.source.getActiveRange();
var editColumn = actRng.getColumn();
var index = actRng.getRowIndex();
var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues();
var dateCol = headers[0].indexOf(timeStampColName);
var updateCol = headers[0].indexOf(updateColName); updateCol = updateCol+1;
if (dateCol > -1 && index > 1 && editColumn == updateCol) { // only timestamp if 'Last Updated' header exists, but not in the header row itself!
var cell = sheet.getRange(index, dateCol + 1);
var date = Utilities.formatDate(new Date(), timezone, timestamp_format);
cell.setValue(date);
}
}
Here you go. Setup an onEdit() trigger. I tested it. It works. It currently works on all of the sheets in the spreadsheet but it's easy to limit it to specific sheets. You could put all the required sheets into an array like var wantedSheets=['Sheet1','Sheet2','Sheet3','Sheet4']; and do wantedSheets.indexOf() to find out if the current sheet is in or out.
function onTimeStampEdit(e)
{
var ss=e.source;
var sh=ss.getActiveSheet();
var rg=e.range;
var row=rg.getRow();
var col=rg.getColumn();
if(col==9 || col==10)
{
sh.getRange(row,11).setValue(Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "MM/dd/yyyy HH:mm:ss"));
}
}
You can use this to setup an installable trigger. Just add the SpreadsheetId.
function installOnEditTrigger()
{
setupTrigger('onTimeStampEdit','SpreadsheetId');
}
function setupTrigger(funcName,SpreadsheetId)
{
if(!isTrigger(funcName))
{
ScriptApp.newTrigger(funcName).forSpreadsheet(SpreadsheetId).onEdit().create();
}
}
function isTrigger(funcName)
{
var r=false;
if(funcName)
{
var allTriggers=ScriptApp.getProjectTriggers();
var allHandlers=[];
for(var i=0;i<allTriggers.length;i++)
{
allHandlers.push(allTriggers[i].getHandlerFunction());
}
if(allHandlers.indexOf(funcName)>-1)
{
r=true;
}
}
return r;
}
screenshot
Hi all, i need help and i am not a coder. I am trying to achieve the same thing on sheet number 2.
My datas are imported through "=Submission!$b2" from sheet 1
i need help removing rows automatically when a specific cell on column H does not contain the value "Bekreft", i tried both codes shown here with no success.
This is what i added for script:
function onEdit() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getSheetByName('DATA - Do Not Touch!!!'); // change to your own
var values = s.getDataRange().getValues();
for(var i=values.length;i>0;i-=1){
var lcVal=values[i-1][0].toLowerCase() //Change to all lower case
var index = lcVal.indexOf("vent"); //now you only have to check for contains "vent"
if (lcVal.indexOf("vent") > -1){
s.deleteRow(i)};
}}
Seeing as you state you are "not a coder", and the code you pasted will not help you if you are referencing data from another page, I would suggest using a filter function to achieve your goal. You would add the following formula to your second page:
=FILTER(Submission!B:B,ISNUMBER(SEARCH("Bekreft", Submission!H:H)))
If you are looking to have a script go through your static list and delete out values that do not contain "Bekreft" then you can use the following script.
function onEdit() {
var sheet = SpreadsheetApp.openById("Add Sheet ID").getSheetByName('Sheet1');
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
var values = rows.getValues();
var rowsDeleted = 0;
for (var i = 0; i <= numRows - 1; i++) {
var row = values[i];
//row for condition
if (row[7].indexOf("Bekreft")) {
sheet.deleteRow((parseInt(i)+1) - rowsDeleted);
rowsDeleted++;
}
}
};
I have a few scripts which, individually, all work. However I am unable to get them to all run on opening the sheet. At the moment, only the first script (hideColumn) runs on opening the sheet. The others all work when called directly from the menu I managed to create.
function onOpen() {
// get active spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
// create menu
var menu = [{name: "Hide Overview Columns", functionName: "hideColumn"},
{name: "Hide Rebalancing Columns", functionName: "hideColumn2"},
{name: "Add/Hide Dividend Data for Chart", functionName: "hideColumn3"}];
// add to menu
ss.addMenu("Check", menu);
// execute function
function hideColumn(){
function hideColumn(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Overview");
// get data
var data = sheet.getDataRange();
// get number of columns
var lastCol = data.getLastColumn()+1;
Logger.log(lastCol);
// itterate through columns
for(var i=1; i<lastCol; i++) {
if(data.getCell(1, i).getValue() == 'HIDE') {
sheet.hideColumns(i);
}
}
}
function hideColumn2() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Rebalancing");
// get data
var data = sheet.getDataRange();
// get number of columns
var lastCol = data.getLastColumn()+1;
Logger.log(lastCol);
// itterate through columns
for(var i=1; i<lastCol; i++) {
if(data.getCell(2, i).getValue() == 'HIDE') {
sheet.hideColumns(i);
}
}
}
function showColumn3() {
// get active spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Dividends - Calculations");
// get data
var data = sheet.getDataRange();
// get number of columns
var lastCol = data.getLastColumn();
// show all columns
sheet.showColumns(1, lastCol);
}
function hideColumn3() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Dividends - Calculations");
// get data
var data = sheet.getDataRange();
// get number of columns
var lastCol = data.getLastColumn()+1;
Logger.log(lastCol);
// itterate through columns
for(var i=1; i<lastCol; i++) {
if(data.getCell(1, i).getValue() == 'HIDE') {
sheet.hideColumns(i);
}
}
}}}
we can help but won't code for you unless you showed us you tried!
Your best option is to have a look at the Google Apps Script documentation.
Here are the pages you need to check to do your script (you'll see it's well explained)
Create a menu
Hide a column
Get the content of a range
Create a loop to check several cell one by one in JS (Mozilla Doc)