Scope of variable in TI process

Post Reply
iesak
Posts: 20
Joined: Mon Feb 23, 2009 4:49 pm
Version: 9.4
Excel Version: 2003

Scope of variable in TI process

Post by iesak »

when running the following code in TI process, I found that value of variable summaryProductName become null within the while loop.
got any idea, or is it a bug ?



detailCount=1;
summaryCount=1;
summaryProductName='';
detailProductName='';
preVerson = ATTRS('Verson',Version,'Pre_Verson');

while (summaryCount <= DIMSIZ('Summary_Product'));

summaryProductName=DIMNM('Summary_Product', summaryCount);

if(ellev('Summary_Product',summaryProductName)=0);

while (detailCount <= DIMSIZ('Detail_Product'));
detailProductName=DIMNM('Detail_Product', detailCount);
if(ellev('Detail_Product',detailProductName)=0);
ratioValue=CellGetN ('SummaryToDetailRatio',detailProductName ,summaryProductName, 'rate');
if(ratioValue >0);
value=CellGetN ('SummaryForecastInput', Year1, Month1,preVerson,Customer,summaryProductName, 'Forecast_Qty');
value = value * ratioValue;
CellPutN (value, 'DetailForecastInput',Year1, Month1,Version,Customer,detailProductName, 'Forecast_Qty');
endif;
endif;
detailCount=detailCount+1;
end;
endif;
summaryCount=summaryCount +1;
end;
User avatar
Alan Kirk
Site Admin
Posts: 6606
Joined: Sun May 11, 2008 2:30 am
OLAP Product: TM1
Version: PA2.0.9.18 Classic NO PAW!
Excel Version: 2013 and Office 365
Location: Sydney, Australia
Contact:

Re: Scope of variable in TI process

Post by Alan Kirk »

iesak wrote:when running the following code in TI process, I found that value of variable summaryProductName become null within the while loop.
got any idea, or is it a bug ?

detailCount=1;
summaryCount=1;
summaryProductName='';
detailProductName='';
preVerson = ATTRS('Verson',Version,'Pre_Verson');

while (summaryCount <= DIMSIZ('Summary_Product'));

summaryProductName=DIMNM('Summary_Product', summaryCount);

if(ellev('Summary_Product',summaryProductName)=0);

while (detailCount <= DIMSIZ('Detail_Product'));
detailProductName=DIMNM('Detail_Product', detailCount);
if(ellev('Detail_Product',detailProductName)=0);
ratioValue=CellGetN ('SummaryToDetailRatio',detailProductName ,summaryProductName, 'rate');
if(ratioValue >0);
value=CellGetN ('SummaryForecastInput', Year1, Month1,preVerson,Customer,summaryProductName, 'Forecast_Qty');
value = value * ratioValue;
CellPutN (value, 'DetailForecastInput',Year1, Month1,Version,Customer,detailProductName, 'Forecast_Qty');
endif;
endif;
detailCount=detailCount+1;
end;
endif;
summaryCount=summaryCount +1;
end;
I doubt that that's really the problem; there seems to be a bug in your code. You initialise detailCount right at the head of the code, outside any of the loops, but don't re-initialise it thereafter.

What that means is that the first time you execute the loop

while (detailCount <= DIMSIZ('Detail_Product'));

detailCount will reach the value DIMSIZ('Detail_Product').

However because you haven't reinitialised that value, the NEXT time you try to execute that loop then it won't execute at all because detailCount will already have a value of DIMSIZ('Detail_Product')+1.

You'd therefore need to put
detailCount=1;
between the lines
if(ellev('Summary_Product',summaryProductName)=0);
and
while (detailCount <= DIMSIZ('Detail_Product'));

My bet is that that will fix your problem.
"To them, equipment failure is terrifying. To me, it’s 'Tuesday.' "
-----------
Before posting, please check the documentation, the FAQ, the Search function and FOR THE LOVE OF GLUB the Request Guidelines.
User avatar
Steve Vincent
Site Admin
Posts: 1054
Joined: Mon May 12, 2008 8:33 am
OLAP Product: TM1
Version: 10.2.2 FP1
Excel Version: 2010
Location: UK

Re: Scope of variable in TI process

Post by Steve Vincent »

I'm making an assumption that the code is in the data tab, but if so Alan is right there is a bug in the code rather than a TM1 problem.

As you have one while loop nested in a 2nd, you need to ensure the internal one has its counter reset once its finished otherwise it'll only loop correctly once.

Code: Select all

1
    1
    2
    3
2
   1
   2
   3
3
   1
   2
   3
Thats a basic example, the internal loop needs to reset back to 1 before it clicks on to the next value in the external loop. In your code its actually doing;

Code: Select all

1
    1
    2
    3
2
3
and thats because the internal while always = 3 (the DIMSIZ value) because you've not reset it.

Its one of those kind of issues i've had myself in the past, really easy to fix but sometimes a real pain to find, mainly due to the lack of any kind of step through abilty in TI. If you put asciioutput lines at various places you'd be able to pick out where the issues are, but it can take ages to do depending on how complicated the code is :?
If this were a dictatorship, it would be a heck of a lot easier, just so long as I'm the dictator.
Production: Planning Analytics 64 bit 2.0.5, Windows 2016 Server. Excel 2016, IE11 for t'internet
User avatar
Alan Kirk
Site Admin
Posts: 6606
Joined: Sun May 11, 2008 2:30 am
OLAP Product: TM1
Version: PA2.0.9.18 Classic NO PAW!
Excel Version: 2013 and Office 365
Location: Sydney, Australia
Contact:

Re: Scope of variable in TI process

Post by Alan Kirk »

Steve Vincent wrote:I'm making an assumption that the code is in the data tab,
Sorry, yes, I should have made it clear that I was making the same assumption. This was based on the fact that had it been in the Prolog or Epilog tab then variables like Year1, Month1, Version and so on (which I assume to be from the process' Variables tab rather than ones which are defined in the code) would have no context and therefore no values.

(It's interesting that (in version 9.0 at least, but I don't think that this is different in other versions) if you use variable names from the Variables tab in either the Prolog or the Epilog then the compiler doesn't throw a "Variable is undefined" tizzy the way it does with a code variable that hasn't been initialised. This is even though for practical purposes the effect is the same. In the Prolog / Epilog tabs Variables tab variables will have a value of an empty string or 0 (as the case may be), but IMHO the compiler should still spit an error since the use of them in either of those tabs is naught but a bug in the user's coding. I don't think it's a big enough issue to raise a change request over, though.)
Steve Vincent wrote: In your code its actually doing;

Code: Select all

1
    1
    2
    3
2
3
and thats because the internal while always = 3 (the DIMSIZ value) because you've not reset it.
And now on The Yummy Channel boys and girls, it's time for Pedantry Corner, with Mr. T!

It would actually be 4 (the DIMSIZ value + 1) in this case because the test condition is <= rather than <. That allows me to clarify something that I could probably have worded better in my original post:
Alan Kirk wrote: detailCount will reach the value DIMSIZ('Detail_Product').

However because you haven't reinitialised that value, the NEXT time you try to execute that loop then it won't execute at all because detailCount will already have a value of DIMSIZ('Detail_Product')+1.
I should have put this as:
Alan Kirk wrote: detailCount will reach the value DIMSIZ('Detail_Product') at the top of its final loop. It will then execute the code one last time, incrementing detailCount by 1 and giving it a value of DIMSIZ('Detail_Product')+1.

However because you haven't reinitialised that value, the NEXT time you try to execute that loop then it won't execute at all because detailCount will have retained the value of DIMSIZ('Detail_Product')+1 from the previous loop, and will fail the While test.
One other thing that I should have mentioned is that I'm not a fan of using a function which returns what is effectively a constant value as part of a loop test; in this case, the DimSiz function.

I'm not sure to what extent (if any) running code on the data tab will lock the metadata of the server, so I suppose that if the planets were aligned in just the right way then DimSiz could, maybe, possibly, perhaps, change during the course of running the code if someone else was making changes to the dimension structure at the same time. (Though for obvious reasons I PITY DA FOOL who tries to change my dimensions while I'm running a T.I., I PITY DA FOOL!)

However in practice, that number's not ever likely to change in the life of the code in the data tab. That means that calling the function each time burns up processor cycles unnecessarily. A single call is trivial, but even in a tool which is as fast as TI (and let's face it, TI is amazingly fast), all of those function calls are going to add up especially if you have a data set running into hundreds of thousands of records. I'd much rather therefore get the DimSiz value just the once (on the Prolog tab) and assign it to a variable, then test against the value of that variable in my While loop.
"To them, equipment failure is terrifying. To me, it’s 'Tuesday.' "
-----------
Before posting, please check the documentation, the FAQ, the Search function and FOR THE LOVE OF GLUB the Request Guidelines.
Post Reply