This is not an issue but rather a solution, who some may need someday.
LO macro, and many other versions, dialects and similars, has a statement to declare variables and arrays called "STATIC". It can be used in a procedure level (subs and functions), but they cannot be declared outside them. When a variable is delcared as STATIC (instead of using DIM or REDIM) the value attributed to it in a call to the procedure is retained for as long as the envorinment is running.
However, if a procedure is invoked from a document, say a Calc document, as a user defined function and not by a running program, the static variable DIES after the procedure exits, returning to the calling document. A next call to the same procedure will not get the value saved to the static variable. For example:
Code: Select all
function testatic(x as double) as double
static stCount as long
stCount = stCount + 1
testatic = x * stCount
end functionIf the function is called for the first time from calc, passing a value say 8, as the sole argument...
(from a calc cell:) [ =testatic(8) ] (enter) ... (the [...] is just to simulate a cell, not to be typed in in...; the same to (enter)...)
... it is expected that the code will run, increment the static value to 1, multiply 8 by 1 and return the value (testatid=) 1*8.
If the the procedure is called again from calc, for example passing the argument 5, one expects that the static variable stCount will increment to 2, and the function will return 2*5 = 10. Surprisingly (or not so), it returns 5, that is the static variable lost the expected saved value "1" and returned to the value 0, which is incremented to 1, then multiplied by 5 returning 5 again, not 10.
I have a problem that requires to evaluate a computational costly function using path integral along a long trajectory starting in at x=0 (it doesn't matter...(*) ). The calc document will call the function many, many times at values of x that vary about (and eventually converge to) the solution which, and for every call, it has to start the integration from zero, so that the best strategy is it to keep the last values of x, and all internal values (the reason of make them STATIC) and use them as the starting point to calculate the function at the new x. Just to give an idea of the cost/time in a run, the calc process took 2 hours to conclude.
I searched around and could't find anything similar that could resolve the issue (except to code the whole problem as a macro, but I would loose all the control I have on the run, and for that I wouldn't need calc).
I realized that I needed to keep the environment runing between calls, so that the static variable would remain "alive". Then I coded a dumb subroutine to start a do-wait-loop process. Here a simplified version of the sub:
Code: Select all
sub foreverloop ()
do
wait 10000 ' 10 seconds
beep ' just to tell me it's running
loop
end subI was concerned about the overhead that an not-ending loop with a wait would put on the cpu, but I found some sources saying that the wait statement just use internal circuitry clock (that is always ticking) and the overhead is negligible (maybe infinitesimal) compared to all processes that are already running in the machine (which is far from few) even without any user load.
The subroutine is put to run before starting the process in calc, and after conclusion the dumb function is stopped.
Surprisingly (or not so), it workd prefectly! The same process above that took 2 hours to conclude finished in ... 120 seconds.
If somebody has a better or more efficient solution, please let me know. If no other solution exist, it would be interesting that adequate solution could be implemented by the the macro developed team.
Jorge
(*) for those interested, the process involve an adaptive 5th-order Runge-Kutta algorithm to path integrate 9 differential equations that define 9 generalized hypergeometric functions evaluated at (-x^3)/9 for values of x somewhere between 30 and 100+...)