There is no breaking point (right click on the row-number will set/remove one) set and therefore it just runs into an error without giving you the possibility to monitor what's loaded within the include-file - you noticed that there is now another tab above the debugger-script-window?
Because of the fact that this tab/window is created and is called CreateCalendar I assume that the include-file is really loaded - in the most cases it's exactly the reason (an invalid path) why anything didn't work. Nevertheless you may to ensure that it worked like expected and if not to trace the issue - for this you should use must_include instead of include and TRACE $(File);.
Therefore I think that there is something wrong with your sub-routine probably any small syntax-issue, for example I noticed that there is a space between the routine-name and the parameter (I'm not sure if it lead to an error) ...
I just dived a bit deeper in the matter and think you are right that it's not working in this way - without that there are "obvious" logically or syntactically errors. Every part "seemed" to be loaded and executed in the right order.
But it's not completely true. The cause of the sub-error here is that the sub-routine was created within a control-statement.
Control-statements like sub … end sub, if … end if, for … next have special properties in regard to their validity. This means either the existence and execution-order of them as well as the objects (tables, variables, further control-statements) which are created within them. This means they aren't available from everywhere.
In your case it means the sub was created within the for-loop and is only within the loop available and each call from the outside called a non exists statement.
I don't know if it's anywhere sufficient documented how Qlik has implemented the control-statements and which requirements are following from it. I remember that I have seen already postings where the guru's discussed this topic - maybe Rob Wunderlich could shed some light on the matter.
In the end I doubt that there is a way to apply your mentioned approach and that the already made suggestion of applying multiple (nested) include-variables is probably the most suitable solution (I use this approach since many years and it's IMO quite practical).
Nevertheless I tried to develop a workaround with a logic which loads these include-files within a table, aggregated the records, creates multiple variables within a loop, called them outside from the loop, executed the routines and cleanes everything. It worked - but it's not really simpler and you will further need to specify each variable … but maybe somebody has further ideas to make this snippet more useful:
set pathDataOrigin = 'YourPath\';
for each File in filelist ('$(pathDataOrigin)CalendarIncludeT*.txt') t1: load [@1:n] as Statement, filebasename() as Filebasename, rowno() as RowNo from [$(File)] (fix, codepage is 1252); next File
t2: load Filebasename, concat(Statement, chr(10), RowNo) as Statement resident t1 group by Filebasename; drop tables t1;
for i = 0 to noofrows('t2') - 1 let s$(i) = peek('Statement', $(i), 't2'); $(s$(i));
for i = 0 to noofrows('t2') - 1 let s$(i) = null(); next
let i = null();
Just came another thought that the above mentioned control-statements are the most usual ones but there more available like do while loop, case switch, … and maybe there are any differences how their validity worked ... in the case you want a bit play with them ...
many thanks for your elaborate explanation. I wasn't aware of the fact, that control statements behave in this way. Now I understand why the workaround as suggested by @albertovarela is so extensively used, and I guess it is okay to use it, as it can be expected that functions are not changed very often. Understanding the reason behind this solution makes it even more acceptible. Thanks for shedding light on this topic.