Steve Vincent wrote:Ever since i started using TM1 i was always under the impression that TI code worked in any tab, it just did the job differently depending on which one. Today i have found out that is not the case for at least one function, and probably more.
I had a process where i wanted to list the names of cubes and dimensions that met certain criteria in 2 temporary dimensions. The plan was to then use this list in another process to destroy those cubes / dims. A simple piece of code went in to prolog to list the cubes, and an identical piece in epilog to list the dims. i only did this to keep things tidy and easy to read, i could do it all in prolog but this is where i found the limitation.
DimensionElementInsert does not work in epilog. Even using SaveDataAll at the end makes no difference, it never does the task. Even an asciioutput confirmed the code was being run and the parameters were correct, but TI refuses to do the task. I then made a simple check using this code;
PROLOG
Code: Select all
DimensionCreate( '_TempKillCubes' );
DimensionElementInsert ( '_TempKillCubes' , '' , 'test1' , 'N' );
EPILOG
Code: Select all
DimensionCreate( '_TempKillDims' );
DimensionElementInsert ( '_TempKillDims' , '' , 'test2' , 'N' );
The epilog will not add test2 as an element. If all the code is in prolog it will run fine.
I have tested this in 9.0 and 9.5.1 with the same results. At the very least nuances like this should be mentioned in the documentation for the function, and who knows what other functions are limited this way. Does anyone have any other examples of functions where this happens, or a version of TM1 where it doesn't?
To be honest this doesn't surprise me. It's always been part of TM1 folklore (i.e., generally believed by many longer-term admins but not found explicitly in the documentation) that the Metadata tab does "something" that refreshes the metadata structures when it completes, but that this something isn't done on any of the other tabs. If this is indeed the case, it would make sense that any metadata changes that were done up to and prior to that tab (i.e. in the Prolog as well) would be implemented, though the same change won't work on the Data / Epilog tabs. Indeed I recall a few questions like this over the years and the usual advice given is to move the code back a tab or two.
Without breaking into Iboglix headquarters and stealing the code for TI (in which case I'd hack it to include search and replace features in the editor; oh, wait, I just gave away the plot for the next Mission Impossible movie) there's no way to be sure what the "something" is, but it's possible to speculate.
When you make metadata changes to a dimension (for example) using the API, you do the following (page 46 of the 9.5.1 API manua)l:
1. Call TM1ObjectDuplicateto make a copy of the dimension you want to update. The copy is an unregistered dimension.
2. Use the calls TM1DimensionElementInsertand TM1DimensionElementComponentAdd to add new elements and components to the duplicated, unregistered dimension.
3. Use the calls TM1DimensionElementDeleteand TM1DimensionElementComponentDeleteto delete unneeded elements and components.
4. Call TM1DimensionCheck to verify the integrity of the new dimension.
5. Call TM1DimensionUpdate to overwrite the old dimension with the new one.
If I had to bet, it would be that TI is only calling the TM1DimensionUpdate function at the end of the Metadata tab and that that function call is the "something" that TI is doing to update the metadata. If I'm correct about that, it would indeed explain why metadata changes need to be done on the Metadata tab or earlier.
And yes, you're correct, the limitation that this imposes on DimensionElementInsert should indeed be documented, as should a bunch of other things.
In relation to your general question of function limitations, aside from the above one of limiting metadata functions to the Metadata tab or earlier I've seen a bunch of instances where people have attempted to use functions that access variables in the Prolog / Epilog tabs where the variables, by definition, have no context. (Notwithstanding that if the variables are populated in the Metadata or Data tabs, they'll still hold the last value populated when the code hits the Epilog tab). Obviously that doesn't work. On the other hand functions like ItemReject
will work when you may believe (as I do) that they shouldn't. There's sometimes an element of "suck it and see" to TI coding but I'd regard this particular instance as an exception rather than a rule;
most of the functions, as long as they have a valid context, should work equally in any tab.