I´m geting Cannot read property "0" from undefined. Error on line 16. ( while (colunaDias[emptyCell][0] <= dias) )
It should be a very simple function for google SpreadSheets. I can´t see what I´m doing wrong...
The bizarre thing is that if I don´t use the variable "dias" and use a integer instead. The while function works....
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var leadsSheet = ss.getSheetByName("Leads Todas as Categorias, menos outros - Days (5days)");
var targetSheet = ss.getSheetByName("feticaria");
var cellLeads = leadsSheet.getRange(1,1).getValue();
//var cellTarget = targetSheet.getRange(1,1).setValue(valor);
var colunaDias = leadsSheet.getRange('B:B').getValues();
var sourceMedium = leadsSheet.getRange('A:A').getValues();
var emptyCell = 16;
var dias = 1;
while (colunaDias[emptyCell][0] != ""){
while (colunaDias[emptyCell][0] <= dias){
dias++;
emptyCell++;
}
emptyCell++;
}
Logger.log(emptyCell);
}
I think the only thing that could cause that error is if emptyCell is bigger than the colunaDias array, i.e. if your sheet is smaller than 16 rows (if the value you show here is correct).
Add this line right before the first while :
Logger.log('emptyCell = '+emptyCell+' and colunaDias.length = '+colunaDias.length);
I tested a copy of your script and it runs without error except if I define emptyCell > 1000 on a 1000 rows Sheet.
I'm guessing that colunaDias[emptyCell] is undefined. It passes the first while condition, because "undefined" is not equal to "". If colunaDias[emptyCell] is undefined, then either there is something wrong with this line:
var colunaDias = leadsSheet.getRange('B:B').getValues();
or
colunaDias[emptyCell][0]
Where "emptyCell" is 16 is the problem. getValues() returns an object of rectangular grid of values. I would test to see if there is anything in the rectangular grid, by checking [0][0].
Logger.log('is there any data? ' + colunaDias[0][0])
If there is no data, then the something failed on line:
var colunaDias = leadsSheet.getRange('B:B').getValues();
If that line is working, then something higher up is wrong.
You should be checking the return type of getSheetByName for null.
// The code below will log the index of a sheet named "YourSheetName"
var leadsSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("YourSheetName");
if (leadsSheet != null) {
Logger.log(leadsSheet.getIndex());
}
I know this post in from a few years ago, but this was the closest to a problem I am having. I just want to post my answer in case someone else ends up here one day.
For some reason the check variable "dias" is being passed as a string.
That's why replacing it with a number allows the script to run.
dias = parseInt(dias); //use this before the variable needs to be read
I cant say why it is passing a string after being ++ but this will fix it
Related
I have two problems.
1) My function noDateAlert(); is SLOW. Any suggestions to make it take less than 5 seconds? Currently takes 17-30 depending on how many lines it has to check.
2) The error message will not pop up when I run noDateAlert(); in another function from my custom menu. It works fine when I run it by itself from the script page. It also works fine when run within the other program from the script page.
I'm using this program to warn me if the 3 cells are empty.
When it is enclosed in the other function it is the first thing listed.
Here's the function:
function noDateAlert() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh0 = ss.getSheetByName("Loads");
// get data from Loads sheet
var data = sh0.getRange(8,29,53,31).getValues();
var data2 = sh0.getRange(8,3,53,3).getValues();
for(var i=0; i < 45; i++) { //Controls how many rows it goes through for posting // len = data.length; i < len
//Only work on loads currently wanting to post
if(data2[i][0] == "P-Post"){
//Warn me if all 3 cells in one row are empty/blank
if(data[i][0] == "" && data[i][1] == "" && data[i][2] == ""){
Browser.msgBox("Some of the loads you want to post are missing dates. Please check dates and run 'Post Loads' again.");
return false;
break;
};
};
};
};
Try this for your msgbox. And I'll keep on looking at the other problem.
SpreadsheetApp.getUi().alert('Some of the loads you want to post are missing dates. Please check dates and run \'Post Loads\' again.');
I'm not privy to your data but I doubt that I do things this way. But since you have access to and knowledge of your data I'll assume that breaking this up in two ranges makes sense. However, I hope you realize that data2[i][0] is actually column 3 and data[i][0] is actually column 29. I left the limit for i at 53 since you specified 53 rows in both ranges. But again. I don't know the detail nor do I have access to the data. So if this doesn't help, you can change it back.
function noDateAlert()
{
var ss=SpreadsheetApp.getActiveSpreadsheet();
var sh0=ss.getSheetByName("Loads");
var data = sh0.getRange(8,29,53,31).getValues();
var data2 = sh0.getRange(8,3,53,3).getValues();
for(var i=0;i<53;i++)
{
if(data2[i][0]=="P-Post")
{
if(!data[i][0] && !data[i][1] && !data[i][2])
{
SpreadsheetApp.getUi().alert('Some of the loads you want to post are missing dates. Please check dates and run \'Post Loads\' again.');
return false;
}
}
}
}
So I have been having erratically getting an error: "Internal Error Executing the Custom Function" when running my custom function on a decently sized range of cells.
Google specifies "A custom function call must return within 30 seconds. If it does not, the cell will display an error: Internal error executing the custom function."
My custom function is this:
function ConcatLoop(rangeString, concatString, isPrefix, isOneColumn) {
//var rangeString = "A1:A10,B1:B10,C1:C10";
//var concatString = "1x ";
//var isPrefix = "true";
//var isOneColumn = "true";
var rangeStringArray = rangeString.split(',');
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var rangeValues=[];
//GRABBING THE VALUES FROM EACH RANGE
for(i=0;i<rangeStringArray.length;i++)
{
var range = sheet.getRange(rangeStringArray[i]);
rangeValues.push(range.getValues());
}
if(isOneColumn){var newRangeValues = [[]]};
//REMOVES EMPTY STRINGS AND ARRAYS OR CONCATENATES THE STRINGS
for (i = 0; i < rangeValues.length; i++) {
for (j = 0; j < rangeValues[i].length; j++){
if (rangeValues[i][j] == "")
{
rangeValues[i].splice(j, 1);
j--;
}
else if(isPrefix == "true")
{
rangeValues[i][j] = concatString + rangeValues[i][j];
if(isOneColumn){newRangeValues[0].push(rangeValues[i][j])};
}
else
{
rangeValues[i][j] = rangeValues[i][j] + concatString;
if(isOneColumn){newRangeValues[0].push(rangeValues[i][j])};
}
}
if (rangeValues[i] ==""){
rangeValues.splice(i,1);
i--;
}
}
//LOG WHILE TESTING
//if(isOneColumn){Logger.log(JSON.stringify(newRangeValues))}
//else{Logger.log("range values after concat: " + rangeValues)}
//RETURN WHILE RUNNING
if(isOneColumn){return newRangeValues}
else{return rangeValues};
}
When I have 1000 values plugged into the function, it takes quite a while to pull all the values. It runs fine when I test it in GOogle Scripts, because there isn't a time constraint there.
If there is anything I can do to work around this or make this more efficient, could someone let me know? Thank you so much!
Thanks to the incredible individuals who commented, I did find an answer earlier, so I'm going to post it for anyone who might need it.
Google sets a limitation of 30 seconds for the execution time of any custom function on a spreadsheet. Anything above that will give you an internal error. Although there is a limitation of 5 minutes for the execution time in the Script Editor, there is probably an issue if your script takes over 30 seconds to execute. In my case, I had too many separate ranges I needed to pull data out of. So I was calling "getValues(range)" quite a few times within a for-loop.
The solution was to pull each entire sheet in the spreadsheet as one range. So rather than having 7 ranges for each of my 27 sheets, I had 1 range for each of my 27 sheets. This caused me to have an excess amount of unnecessary information in memory, but also caused the execution time to go from around 45 seconds to 10 seconds. Solved my problem entirely.
Thank you!
parseFloat is not working in our function
There are so many answers abouth this issue but any of them are not satisfying for me.
Please see code:
var kasatoplam = $('.kasatoplam');
function fiyatTopla() {
var eklenen = $('.adisyon .adisyontable .adsiyonTableUrunler').length;
var urunfiyatlari = [];
$('.adisyon .adisyontable .adsiyonTableUrunler').each(function () {
var urunfiyat = $(this).find('.urunFiyati').text()
urunfiyatlari.push(parseFloat(urunfiyat))
});
console.log(urunfiyatlari);
var toplamfiyat = 0;
for(i=0; i<=urunfiyatlari.length; i++){
toplamfiyat += urunfiyatlari[i]<<0;
}
kasatoplam.html(toplamfiyat);
}
`var urunfiyat = $(this).find('.urunFiyati').text()
urunfiyatlari.push(parseFloat(urunfiyat))`
What is the failure mode for parseFloat? Is it throwing an exception or just not yielding the values you expected? It would help to know.
In any case, it seems that the contents of urunfiyat must be the problem. Have you stepped through the code with the debugger and seen what kind of text values you are getting from
` $(this).find('.urunFiyati').text()' ?
Perhaps you are getting nothing undefined or empty string or perhaps the string needs a little processing before it is passed to parseFloat
I having trouble with this problem for hours ago.
I wrote these in my Jquery function to check Value in Variable if it's exist or not.
console.log("in tr");
console.log(tmpRoomlistArray[c].room_name);
let roomName = tmpRoomlistArray[c].room_name;
When I ran and looked at Google Chrome Console. It shows results like this.
Rome <<< In console.log It shows valid value
in tr
Uncaught TypeError: Cannot read property 'room_name' of undefined <<
This is what happen when I assign in to a variable and this is what I need
What happen ?? I'm blind right now..
edit : edit question content
I already solved it. It just a silly problem that I overlooked. It's about array index.
I just put
tmpRoomlistArray[c-1]
into my function and it worked. I think the solution is just rest more, So you could see the problem more clearly.
For those who want to know what happen just read it below.
I got a function that insert row in table, and this function have 2 parameters, which is an array. So this function will insert row continuously into the table. It won't stop until it reach the end of the array.
var day = ["1","2","3"];
var room = ["room1","room2","room3",....,"room16"] // 16 Elements;
var timeForHeader = ["08:00","09:00",....."20:00"] // 25 Elements;
function addRow(paramDay,paramRoom){
// this function will create many rows depends on paramRoom length and columns depends on length of time header.
var dayLength = day.length;
var roomLength = room.length;
var timeForHeaderLength = timeForHeader.length;
for(var i = 0; i < dayLength; i++)
{
// this is for rows
for(var c = 0; c < timeForHeaderLength+1; c++)
{
// I made c +1 timeForHeaderLength because I want a header
//this is for column
if(c == 0)
{
// if c == 0 mean I will insert a header row element in my table
var tr = $("<tr/>");
var td = $("<td/>",{text:timeForHeader[0]+" - "+timeForHeader[1]}).appendTo(tr);
...
...
var td23 = $("<td/>",{text:timeForHeader[23]+" - "+timeForHeader[24]}).appendTo(tr);
$("#mytableId").append(tr);
}else{
// this row that contain room's name and content
// and this is the part that cause me a problem.
// in this else condition c must be 1-17 so when I access to tmpRoomlistArray that contains 16 Element
// So right now You guys should know right. The tmpRoomlistArray's index must be 0 - 16
// it worked when c is between 1 - 16, But it didn't work on the last c cause c is equal to 17
console.log(tmpRoomlistArray[c].room_name);
let roomName = tmpRoomlistArray[c].room_name;
//It should be
let roomName = tmpRoomlistArray[c-1].room_name;
// Hahahahahahahahahahahahahahahahahhaha
}
}
}
}
tmpRoomlistArray[c] is coming as undefined.
Try to print:
console.log(tmpRoomlistArray[c]);
or
console.log(tmpRoomlistArray);
instead of
console.log(tmpRoomlistArray[c].room_name);
You can also use
debugger
in javascript code to watch value of array.
Use var instead of let?
Could let be looking for something more strongly typed?
I have a currently fairly dysfunctional Javascript program that's been causing me problems. However, it throws one error that I just don't understand:
TypeError: 'undefined' is not an object (evaluating 'sub.from.length')
What I'm trying to do, as you can probably guess, is check the length of a certain "from" array in the sub dict. Here's the source code for the entire function, and here's the code of the loop that I think is causing the error:
console.log(afcHelper_ffuSubmissions.length); // just for debugging, returns the correct number
for (var i = 0; i < afcHelper_ffuSubmissions.length; i++) { // this whole section works fine
var sub = afcHelper_ffuSubmissions[i];
//console.log("THIS IS BROKEN DOWN BY LINK",afcHelper_Submissions[i]);
if (pagetext.indexOf(afcHelper_ffuSections[sub.section]) == -1) {
// Someone has modified the section in the mean time. Skip.
document.getElementById('afcHelper_status').innerHTML += '<li>Skipping ' + sub.title + ': Cannot find section. Perhaps it was modified in the mean time?</li>';
continue;
}
var text = afcHelper_ffuSections[sub.section];
var startindex = pagetext.indexOf(afcHelper_ffuSections[sub.section]);
var endindex = startindex + text.length;
console.log(sub);
if (typeof(sub.from) != 'undefined' && sub.from.length > 0) { // ** problem spot?? this is the code i recently added.
for (var i = 0; i < sub.from.length; i++) {
mainid = sub.from[i]['id'];
var sub = afcHelper_Submissions[mainid]; // and then it goes on from here...
Any ideas would be great. Frankly, I just can't see why I'm getting a TypeError about something that I've already explicitly checked the type of (typeof(sub.from))...
I'm not sure how you could just check if something isn't undefined and at the same time get an error that it is undefined. What browser are you using?
You could check in the following way (extra = and making length a truthy evaluation)
if (typeof sub !== 'undefined' && sub.from && sub.from.length) {
[update]
I see that you reset sub and thereby reset sub.from but fail to re check if sub.from exist:
for (var i = 0; i < sub.from.length; i++) {//<== assuming sub.from.exist
mainid = sub.from[i]['id'];
var sub = afcHelper_Submissions[mainid]; // <== re setting sub
My guess is that the error is not on the if statement but on the for(i... statement. In Firebug you can break automatically on an error and I guess it'll break on that line (not on the if statement).
try out this if you want to assign value to object and it is showing this error in angular..
crate object in construtor
this.modelObj = new Model(); //<---------- after declaring object above