tracylee
23rd October 2018, 07:23
Hi,

I have issue on my calculation program. When i run a session, then prompt the message "Fatal error: Number of Function calls exceeds maximum of 500 stack entriesries. Please refer my attached file for more details. Please advise.

mark_h
23rd October 2018, 14:24
I would debug the code and see what is causing it to continually call a function.

günther
24th October 2018, 09:15
I would write a log file, run the session and see later what happens.

tracylee
26th October 2018, 04:54
I would debug the code and see what is causing it to continually call a function.

Hi, thanks for your reply. Below is my code.



function calculate.long.bar()
{
countlongbar = 0
longbarlength = 0
longbarsection.f = long.sect.f
longbarsection.t = long.sect.t


select count(tccus024.lgth):count.lgth, tccus024.sect
from tccus024
where tccus024.sect inrange {:longbarsection.f} and {:longbarsection.t} and tccus024.tqty > 0
group by tccus024.sect
selectdo
sect.no = tccus024.sect
countlongbar = countlongbar + 1
longbarsection.f = long.sect.f
longbarsection.t = long.sect.t
longbarlength = long.lgth - 15 |add -15 (6.9.18)

|******* Update Cut List Table (Wastage) **************
select tccus025.*
from tccus025 for updatea
where tccus025.sect = :ssection and tccus025.pono = :position
selectdo
ret = dal.change.object("tccus025")
dal.set.field("tccus025.wstg", mmbalance)
ret = dal.save.object("tccus025")
commit.transaction()
endselect

reloop()

selectempty
message("Successful!")
update.planned.order()
check.balance.short.bar()
generate.wh.order.lines()
start.session(MODAL_OVERVIEW, "tccus0125m000", "", "")
stop()
endselect
}


function reloop()
{
sect.no.1 = sect.no

select tccus024.*
from tccus024
where tccus024.tqty > 0 and tccus024.sect = :sect.no.1 and tccus024.lgth <= :longbarlength
order by tccus024.lgth desc as set with 1 rows
selectdo
selectempty
select count(tccus024.lgth):count.lgth
from tccus024
where tccus024.sect = :sect.no.1 and tccus024.tqty > 0
group by tccus024.sect
selectdo

if (count.lgth > 0) then
select tccus024.*
from tccus024
where tccus024.sect = :sect.no.1 and tccus024.tqty > 0
selectdo
endselect

if long.lgth < tccus024.lgth then
message("Order length is shorter than short length.")
stop()
else
countlongbar = countlongbar + 1
longbarsection.f = long.sect.f
longbarsection.t = long.sect.t
longbarlength = long.lgth - 15 |add -15 (6.9.18)

|******* Update Cut List Table (Wastage) **************
select tccus025.*
from tccus025 for update
where tccus025.sect = :ssection and tccus025.pono = :position
selectdo
ret = dal.change.object("tccus025")
dal.set.field("tccus025.wstg", mmbalance)
ret = dal.save.object("tccus025")
commit.transaction()
endselect

reloop()
endif
else
message("Successful!")
update.planned.order()
check.balance.short.bar()
generate.wh.order.lines()
start.session(MODAL_OVERVIEW, "tccus0125m000", "", "")
stop()
endif

selectempty

|******* Update Cut List Table (Wastage) **************
select tccus025.*
from tccus025 for update
where tccus025.sect = :ssection and tccus025.pono = :position
selectdo
ret = dal.change.object("tccus025")
dal.set.field("tccus025.wstg", mmbalance)
ret = dal.save.object("tccus025")
commit.transaction()
endselect

if use.off.cut = tcyesno.yes then
update.planned.order()
check.balance.short.bar()
calculate.off.cut()
else
update.planned.order()
check.balance.short.bar()
calculate.long.bar()
endif
endselect

endselect

get.code()

ssection = tccus024.sect

|***** Include Cut Loss (14.9.18) *****
|**20mm
if formwork.code = "LE" or formwork.code = "BHH" or formwork.code = "BHV" or formwork.code = "BHX" or
formwork.code = "BHA" or formwork.code = "BHB" or formwork.code = "BHC" or formwork.code = "BHD" or
formwork.code = "BHE" or formwork.code = "BHF" or formwork.code = "BHG" or formwork.code = "BHH" or
formwork.code = "BXC" or formwork.code = "LA" or formwork.code = "SP" or formwork.code = "BHC" then
slength = tccus024.lgth + 20

|**70mm
else if formwork.code = "LAE" then
slength = tccus024.lgth + 70

|**150mm
else if formwork.code = "LM" then
slength = tccus024.lgth + 150

|**4mm
else
slength = tccus024.lgth + 4 | add +4 (6.9.18)
endif
endif
endif




slength.1 = tccus024.lgth
squty = tccus024.tqty
allocatedqty = tccus024.gqty |tccus024.oqty

longs = longbarlength | assign long bar balance to a new variable longs

iw = longs / slength | use long bar balance to divide then we will get how many qty can produce

if round(iw,0,0) = 0 then
countlongbar = countlongbar + 1
longbarsection.f = long.sect.f
longbarsection.t = long.sect.t
longbarlength = long.lgth

|******* Update Cut List Table (Wastage) **************
select tccus025.*
from tccus025 for update
where tccus025.sect = :ssection and tccus025.pono = :position
selectdo
ret = dal.change.object("tccus025")
dal.set.field("tccus025.wstg", mmbalance)
ret = dal.save.object("tccus025")
commit.transaction()
endselect

select tccus024.*
from tccus024
where tccus024.tqty > 0 and tccus024.sect = :sect.no.1 and tccus024.lgth <= :longbarlength
order by tccus024.lgth desc as set with 1 rows
selectdo
reloop()
selectempty
sect.no.1 = sect.no.1
countlongbar = countlongbar + 1
longbarsection.f = long.sect.f
longbarsection.t = long.sect.t
longbarlength = long.lgth
reloop()
endselect
endif


select max(tccus025.pono):posi
from tccus025
where tccus025.sect <> ""
selectdo
position = posi + 10
selectempty
position = 10
endselect


mmbalance = 0 | use to store long bar balance

temp = 0 | use to store the actual length of produce qty times short length

balance = 0 | use to store if the short lgth still have balance qty after produce

if (iw > squty) then
balance = 0 | set to zero
newquty = squty | set new qty = short lgth balance qty
temp = slength * round(newquty,0,0) | short lgth * new qty
mmbalance = longs - temp | current long bar balance - temp
iw = newquty | new short bar lgth able produce qty to new qty
else
balance = squty - round(iw,0,0) | new short lgth balance qty
temp = slength * round(iw,0,0) | total produce short lgth
mmbalance = longs - temp | update long bar balance = current long bar balance - temp
endif

|******* Update balance qty and temp total back to table **************
select tccus024.*
from tccus024 for update
where tccus024.sect = :ssection and tccus024.lgth = :slength.1
selectdo
ret = dal.change.object("tccus024")
dal.set.field("tccus024.sect", ssection)
dal.set.field("tccus024.lgth", str$(slength.1))
dal.set.field("tccus024.tqty", str$(balance))
ret = dal.save.object("tccus024")
commit.transaction()
endselect

if balance = 0 then
select tccus024.*
from tccus024 for update
where tccus024.sect = :ssection and tccus024.lgth = :slength.1
selectdo
ret = dal.change.object("tccus024")
dal.set.field("tccus024.nqty", str$(balance))
ret = dal.save.object("tccus024")
commit.transaction()
endselect
endif

|******* Insert Cut List Table **************
select tccus025.*
from tccus025 for update
where tccus025.sect = :ssection and tccus025.pono = :position
selectdo

ret = dal.change.object("tccus025")

dal.set.field("tccus025.sect", ssection)
dal.set.field("tccus025.slen", str$(slength.1))
dal.set.field("tccus025.csle", str$(round(iw,0,0)))
dal.set.field("tccus025.clle", str$(countlongbar))
dal.set.field("tccus025.lbal", str$(mmbalance))
dal.set.field("tccus025.olen", str$(long.lgth))
dal.set.field("tccus025.ocut", tcyesno.no)
dal.set.field("tccus025.wstg", 0)

ret = dal.save.object("tccus025")
commit.transaction()

selectempty
ret = dal.new.object("tccus025")

dal.set.field("tccus025.pono", position)
dal.set.field("tccus025.sect", ssection)
dal.set.field("tccus025.slen", str$(slength.1))
dal.set.field("tccus025.csle", str$(round(iw,0,0)))
dal.set.field("tccus025.clle", str$(countlongbar))
dal.set.field("tccus025.lbal", str$(mmbalance))
dal.set.field("tccus025.olen", str$(long.lgth))
dal.set.field("tccus025.ocut", tcyesno.no)
dal.set.field("tccus025.wstg", 0)

ret = dal.save.object("tccus025")
commit.transaction()
endselect

if (mmbalance = 0) then
countlongbar = countlongbar + 1
longbarsection.f = long.sect.f
longbarsection.t = long.sect.t
longbarlength = long.lgth

select tccus024.*
from tccus024
where tccus024.tqty > 0 and tccus024.sect = :sect.no.1 and tccus024.lgth <= :longbarlength
order by tccus024.lgth desc as set with 1 rows
selectdo
reloop()
selectempty
sect.no.1 = sect.no.1
countlongbar = countlongbar + 1
longbarsection.f = long.sect.f
longbarsection.t = long.sect.t
longbarlength = long.lgth

|******* Update Cut List Table (Wastage) **************
select tccus025.*
from tccus025 for update
where tccus025.sect = :ssection and tccus025.pono = :position
selectdo
ret = dal.change.object("tccus025")
dal.set.field("tccus025.wstg", mmbalance)
ret = dal.save.object("tccus025")
commit.transaction()
endselect

reloop()
endselect

else
longbarsection.f = long.sect.f
longbarsection.t = long.sect.t
longbarlength = mmbalance
prcm.notify("tccus024.refresh")

reloop()
endif
}

tracylee
26th October 2018, 04:55
I would write a log file, run the session and see later what happens.

Hi, thanks for your reply. Below is my code.


function calculate.long.bar()
{
countlongbar = 0
longbarlength = 0
longbarsection.f = long.sect.f
longbarsection.t = long.sect.t


select count(tccus024.lgth):count.lgth, tccus024.sect
from tccus024
where tccus024.sect inrange {:longbarsection.f} and {:longbarsection.t} and tccus024.tqty > 0
group by tccus024.sect
selectdo
sect.no = tccus024.sect
countlongbar = countlongbar + 1
longbarsection.f = long.sect.f
longbarsection.t = long.sect.t
longbarlength = long.lgth - 15 |add -15 (6.9.18)

|******* Update Cut List Table (Wastage) **************
select tccus025.*
from tccus025 for updatea
where tccus025.sect = :ssection and tccus025.pono = :position
selectdo
ret = dal.change.object("tccus025")
dal.set.field("tccus025.wstg", mmbalance)
ret = dal.save.object("tccus025")
commit.transaction()
endselect

reloop()

selectempty
message("Successful!")
update.planned.order()
check.balance.short.bar()
generate.wh.order.lines()
start.session(MODAL_OVERVIEW, "tccus0125m000", "", "")
stop()
endselect
}


function reloop()
{
sect.no.1 = sect.no

select tccus024.*
from tccus024
where tccus024.tqty > 0 and tccus024.sect = :sect.no.1 and tccus024.lgth <= :longbarlength
order by tccus024.lgth desc as set with 1 rows
selectdo
selectempty
select count(tccus024.lgth):count.lgth
from tccus024
where tccus024.sect = :sect.no.1 and tccus024.tqty > 0
group by tccus024.sect
selectdo

if (count.lgth > 0) then
select tccus024.*
from tccus024
where tccus024.sect = :sect.no.1 and tccus024.tqty > 0
selectdo
endselect

if long.lgth < tccus024.lgth then
message("Order length is shorter than short length.")
stop()
else
countlongbar = countlongbar + 1
longbarsection.f = long.sect.f
longbarsection.t = long.sect.t
longbarlength = long.lgth - 15 |add -15 (6.9.18)

|******* Update Cut List Table (Wastage) **************
select tccus025.*
from tccus025 for update
where tccus025.sect = :ssection and tccus025.pono = :position
selectdo
ret = dal.change.object("tccus025")
dal.set.field("tccus025.wstg", mmbalance)
ret = dal.save.object("tccus025")
commit.transaction()
endselect

reloop()
endif
else
message("Successful!")
update.planned.order()
check.balance.short.bar()
generate.wh.order.lines()
start.session(MODAL_OVERVIEW, "tccus0125m000", "", "")
stop()
endif

selectempty

|******* Update Cut List Table (Wastage) **************
select tccus025.*
from tccus025 for update
where tccus025.sect = :ssection and tccus025.pono = :position
selectdo
ret = dal.change.object("tccus025")
dal.set.field("tccus025.wstg", mmbalance)
ret = dal.save.object("tccus025")
commit.transaction()
endselect

if use.off.cut = tcyesno.yes then
update.planned.order()
check.balance.short.bar()
calculate.off.cut()
else
update.planned.order()
check.balance.short.bar()
calculate.long.bar()
endif
endselect

endselect

get.code()

ssection = tccus024.sect

|***** Include Cut Loss (14.9.18) *****
|**20mm
if formwork.code = "LE" or formwork.code = "BHH" or formwork.code = "BHV" or formwork.code = "BHX" or
formwork.code = "BHA" or formwork.code = "BHB" or formwork.code = "BHC" or formwork.code = "BHD" or
formwork.code = "BHE" or formwork.code = "BHF" or formwork.code = "BHG" or formwork.code = "BHH" or
formwork.code = "BXC" or formwork.code = "LA" or formwork.code = "SP" or formwork.code = "BHC" then
slength = tccus024.lgth + 20

|**70mm
else if formwork.code = "LAE" then
slength = tccus024.lgth + 70

|**150mm
else if formwork.code = "LM" then
slength = tccus024.lgth + 150

|**4mm
else
slength = tccus024.lgth + 4 | add +4 (6.9.18)
endif
endif
endif




slength.1 = tccus024.lgth
squty = tccus024.tqty
allocatedqty = tccus024.gqty |tccus024.oqty

longs = longbarlength | assign long bar balance to a new variable longs

iw = longs / slength | use long bar balance to divide then we will get how many qty can produce

if round(iw,0,0) = 0 then
countlongbar = countlongbar + 1
longbarsection.f = long.sect.f
longbarsection.t = long.sect.t
longbarlength = long.lgth

|******* Update Cut List Table (Wastage) **************
select tccus025.*
from tccus025 for update
where tccus025.sect = :ssection and tccus025.pono = :position
selectdo
ret = dal.change.object("tccus025")
dal.set.field("tccus025.wstg", mmbalance)
ret = dal.save.object("tccus025")
commit.transaction()
endselect

select tccus024.*
from tccus024
where tccus024.tqty > 0 and tccus024.sect = :sect.no.1 and tccus024.lgth <= :longbarlength
order by tccus024.lgth desc as set with 1 rows
selectdo
reloop()
selectempty
sect.no.1 = sect.no.1
countlongbar = countlongbar + 1
longbarsection.f = long.sect.f
longbarsection.t = long.sect.t
longbarlength = long.lgth
reloop()
endselect
endif


select max(tccus025.pono):posi
from tccus025
where tccus025.sect <> ""
selectdo
position = posi + 10
selectempty
position = 10
endselect


mmbalance = 0 | use to store long bar balance

temp = 0 | use to store the actual length of produce qty times short length

balance = 0 | use to store if the short lgth still have balance qty after produce

if (iw > squty) then
balance = 0 | set to zero
newquty = squty | set new qty = short lgth balance qty
temp = slength * round(newquty,0,0) | short lgth * new qty
mmbalance = longs - temp | current long bar balance - temp
iw = newquty | new short bar lgth able produce qty to new qty
else
balance = squty - round(iw,0,0) | new short lgth balance qty
temp = slength * round(iw,0,0) | total produce short lgth
mmbalance = longs - temp | update long bar balance = current long bar balance - temp
endif

|******* Update balance qty and temp total back to table **************
select tccus024.*
from tccus024 for update
where tccus024.sect = :ssection and tccus024.lgth = :slength.1
selectdo
ret = dal.change.object("tccus024")
dal.set.field("tccus024.sect", ssection)
dal.set.field("tccus024.lgth", str$(slength.1))
dal.set.field("tccus024.tqty", str$(balance))
ret = dal.save.object("tccus024")
commit.transaction()
endselect

if balance = 0 then
select tccus024.*
from tccus024 for update
where tccus024.sect = :ssection and tccus024.lgth = :slength.1
selectdo
ret = dal.change.object("tccus024")
dal.set.field("tccus024.nqty", str$(balance))
ret = dal.save.object("tccus024")
commit.transaction()
endselect
endif

|******* Insert Cut List Table **************
select tccus025.*
from tccus025 for update
where tccus025.sect = :ssection and tccus025.pono = :position
selectdo

ret = dal.change.object("tccus025")

dal.set.field("tccus025.sect", ssection)
dal.set.field("tccus025.slen", str$(slength.1))
dal.set.field("tccus025.csle", str$(round(iw,0,0)))
dal.set.field("tccus025.clle", str$(countlongbar))
dal.set.field("tccus025.lbal", str$(mmbalance))
dal.set.field("tccus025.olen", str$(long.lgth))
dal.set.field("tccus025.ocut", tcyesno.no)
dal.set.field("tccus025.wstg", 0)

ret = dal.save.object("tccus025")
commit.transaction()

selectempty
ret = dal.new.object("tccus025")

dal.set.field("tccus025.pono", position)
dal.set.field("tccus025.sect", ssection)
dal.set.field("tccus025.slen", str$(slength.1))
dal.set.field("tccus025.csle", str$(round(iw,0,0)))
dal.set.field("tccus025.clle", str$(countlongbar))
dal.set.field("tccus025.lbal", str$(mmbalance))
dal.set.field("tccus025.olen", str$(long.lgth))
dal.set.field("tccus025.ocut", tcyesno.no)
dal.set.field("tccus025.wstg", 0)

ret = dal.save.object("tccus025")
commit.transaction()
endselect

if (mmbalance = 0) then
countlongbar = countlongbar + 1
longbarsection.f = long.sect.f
longbarsection.t = long.sect.t
longbarlength = long.lgth

select tccus024.*
from tccus024
where tccus024.tqty > 0 and tccus024.sect = :sect.no.1 and tccus024.lgth <= :longbarlength
order by tccus024.lgth desc as set with 1 rows
selectdo
reloop()
selectempty
sect.no.1 = sect.no.1
countlongbar = countlongbar + 1
longbarsection.f = long.sect.f
longbarsection.t = long.sect.t
longbarlength = long.lgth

|******* Update Cut List Table (Wastage) **************
select tccus025.*
from tccus025 for update
where tccus025.sect = :ssection and tccus025.pono = :position
selectdo
ret = dal.change.object("tccus025")
dal.set.field("tccus025.wstg", mmbalance)
ret = dal.save.object("tccus025")
commit.transaction()
endselect

reloop()
endselect

else
longbarsection.f = long.sect.f
longbarsection.t = long.sect.t
longbarlength = mmbalance
prcm.notify("tccus024.refresh")

reloop()
endif
}

NPRao
26th October 2018, 08:49
When i run a session, then prompt the message "Fatal error: Number of Function calls exceeds maximum of 500 stack entries.

Refer to - Known limits (http://www.baanboard.com/programmers_manual_baanerp_help_misc_known_limits)
Bshell
maximum string buffer size is 4K – be careful when concatenating strings with '&' sign
maximum function stack depth is 75
The online version here is old and from the latest programmer's manual -
Known limits
Reports
sorting doubles correct to 6 decimal places
Report TIV < 1101: maximum of 255 fields on a report (including array elements)
Report TIV >= 1101: maximum of 512 fields on a report (including array elements)
Bshell
maximum function stack depth is 500
Bic
maximum 255 arguments per function
maximum 32K variables per compilation
maximum BRANCH of 32K (BRANCH refers to the amount of generated code per function, including macros etc.)
You can also use the Debug Bshell to figure out the issue -

Bshell resources
debug_level DEBUG_LEVEL
SHOW_TRACE 040000000 dbgstack Show stack traces.

Bshell command line options
dbgstack -dbgstack Set the SHOW_TRACE flag in the debug_level resource.

So basically you have to change your code.

tracylee
27th October 2018, 06:55
Refer to - Known limits (http://www.baanboard.com/programmers_manual_baanerp_help_misc_known_limits)

The online version here is old and from the latest programmer's manual -

You can also use the Debug Bshell to figure out the issue -

So basically you have to change your code.

Hi, thanks for your advise. May i know which part coding i need to change? Thanks.

NPRao
27th October 2018, 20:20
TracyLee,

I'm not a Functional developer to understand and fix your code.
Some parts of your code did not make sense to me -
start.session(MODAL_OVERVIEW, "tccus0125m000", "", "")
stop()

Why you need to start a session in the selectempty and stop it or why do you need so many reloop() calls.

I suggested ways to debug and figure out the root cause of the issue and you know your Functional/business requirements, unless you can explain better others cannot help you out to rewrite your code efficiently.

andreas.toepper
29th October 2018, 08:23
Hi, thanks for your advise. May i know which part coding i need to change? Thanks.
You're using a recursion in function reloop().
Bshell maximum function stack depth is 500
I think this points to a problem with too many nested loops. Maybe you do have an endless loop condition in your data. (So your function reloop() is recursively called again and again. The stack is flooded, till the error is being raised,)

mark_h
29th October 2018, 13:27
Andreas is correct - looks like no matter what you are always hitting reloop continuously.

Ajesh
30th October 2018, 22:54
You are hitting recursion.. So basically till 500 levels it can handle recursion, it seems

tracylee
31st October 2018, 02:33
You are hitting recursion.. So basically till 500 levels it can handle recursion, it seems

Thanks for your reply. If more than 500 level, then how to solve it? Please advise. Thanks.

mark_h
31st October 2018, 13:49
I am not exactly sure what you are doing but you will need to figure out away to get a return in the code somewhere. It the BOM program we basically track the make item, position and level we are on when we go to the next level. This allows us to return to find the position in the bom we where at when we increased the level. We use arrays and a level counter to track where it is. Not sure if you have that kind of source code you can go look at.

Ajesh
31st October 2018, 15:04
Thanks for your reply. If more than 500 level, then how to solve it? Please advise. Thanks.

Whats the Requirement? There is no easy fixes, i have to say..

bhushanchanda
8th November 2018, 09:33
Thanks for your reply. If more than 500 level, then how to solve it? Please advise. Thanks.


Dynamic SQL is the solution here.