In this blog post, I would like to discuss the options that we now have for PAW action button parameters of TI processes. The IBM documentation can be found here. Some additional explanations can be useful, though. The information has been updated as of PAW version 2.0.106/2.1.13 (August 2025 SC release).
We first create the TI process in the usual way. Any parameter in the process will be of type String (for texts) or Numeric (for numbers). Once the process is exposed behind a PAW action button in a book, this choice of parameter type determines what kind of actions can be chosen: do you expect the user to pick an existing element or subset? Do you want a number between 1 and 5 as the input? etc. The goal is to not only pass information from the user or PAW to a process and its parameters, at least as important will be avoiding errors/typos/elements with no read access/enforcing validation, a.s.o.
Please have a look at my other recent article on the LogOutput function to have the chosen parameter values end up in the TM1 server log in a convenient and quick way.
For String parameters (the vast majority of cases) we have:
- Text input
- List
- Member list
- Set list
- Cell
- Synchronize member
- Synchronize set
- File
For Numeric parameters we have:
- Text input (what a weird name to supply a number!)
- List
- Boolean
- Number range
- Calendar
- Cell
Note that some types are possible with both text and numbers, whereas others are text-only or number-only. In the remainder of the blog post, we will discuss the different options and some typical use cases. Turbo Integrator code is provided where non-trivial.
· Text input (text and number)
The user can freely enter a text or a number (it depends on the parameter type in the process). For numbers, decimal values are allowed when the decimal separator is the dot. The PAW default parameter value can be different from the TI process default value.
When the Text input parameter is deactivated for prompting the user, then PAW default value enters the TI process. This means that the default TI parameter value will never be utilized.
· List (text and number)
Enter the list of possible values under "Control Detail" in PAW. It should be comma-separated values with no spaces in between (spaces will be part of the value that enters TI). The first value in the list is shown, so when no choice is made, the first value is used in TI. It is possible to advance without selecting an option (a blank option) if you allow the blank option in the list: ,A,B,C. Like this, the first option and which is shown, is the blank option.
When the List parameter is deactivated for prompting the user, then the first option enters the TI process. This means that the default TI parameter value will never be utilized.
Numbers in a list are allowed too. You should have the parameter in TI as type Numeric in that case. A mix of texts and numbers is possible as well: your parameter type should be String and you probably need additional code to work with the value that is chosen. There is no function in TI that can return the type of a variable. You need to loop over the characters and test as such - which is far from ideal. [The JsonType() function in TM1 V12 also does not help here.]
· Member list (text only)
(in earlier versions, it was called 'Dimension list')
The user can pick an element from any hierarchy in any dimension. Element security (and dimension/hierarchy security) will first be applied to potentially reduce the list of elements. Instead of choosing from the entire hierarchy, we can also offer to the user a subset within the hierarchy. The subset can be static or dynamic (MDX-driven), using a certain alias or using principal names.
The output, or what enters the TI process, will be:
- if the "Pass name" checkbox is activated: in case a subset is used with an alias, the element name under that alias. In all other cases, the principal name of the chosen element.
- if the "Pass member unique name" checkbox is activated: in other cases it will be [dimension_name].[hierarchy_name].[principal_element_name].
Since any dimension/hierarchy in the TM1 model can be sourced from, it means that not only dimensions in a certain cube are candidates for element selections. You could have an action button asking a selection of element(s) from the user, store it in some cube or subset, and have other MDX queries act upon the selection. This is just 1 use case out of the many new opportunities that arise.
When the user is prompted, he/she has an option to select no element in case the PAW default value is not set. In that case, a blank value enters the TI process for this parameter. When the Member list parameter is deactivated for prompting the user, then the PAW default value will enter the TI process. In case the latter is not set, then the TI process parameter default value is used in the TI process for that parameter.
The behaviour of the PAW default value when combined with a dynamic subset seems to have changed compared to the past. Now, when the PAW default value is set, it is shown to the user. However, when the default value is not part of the (dynamic) subset, then the first element of the dynamic subset becomes the default value for the user. This means that we can create a dynamic subset for the current fiscal period or year, or even a dynamic subset for "the current period followed by all 12 periods". The default value will be the first item in the subset. In the past a dynamic subset could be used, but the default value would not be updated. This means that the subset would contain an element '2025' whereby the PAW default value was still '2024' - in case no one updated (many) buttons in the PAW interface. Luckily, this situation is resolved now and we should not update potentially many PAW assets.
As a matter of fact, we can now change a system parameter cube for the 'Current fiscal period'. This value is picked up in a dynamic MDX subset. All process parameters that are type 'Member list' and point to this subset, will automatically show the current fiscal period, also when TI or a user updates the period in the system cube. However, the parameter type 'Cell' is probably easier in this example. See below. Needless to say, there are still many examples to give for the utility of 'Member list' as a parameter type.
· Set list (text only)
With this option we can ask the user to select a public or private subset in a given dimension/hierarchy combination. We have to be careful as to what will be output in the parameter value: it is not the name of the chosen subset, neither a concatenated list of elements in the subset. Rather, it is the TM1SubsetToSet() function syntax towards the chosen subset in the dimension/hierarchy: {TM1SubsetToSet([Year].[Year], "chosen subset name", "public or private")}
It follows that with such a piece of text, we can write TI code to create a new, temporary or permanent, subset. In that way, we can loop over the elements in the original subset, for instance. But yes, we might need additional code in the TI process to loop through the subset elements. Or, we might want to extract the dimension/hierarchy/subset names and use the given public subset in a zero out or view source process. All this is now possible, whereas in the past (TM1 Architect/Perspectives) we would have been clueless or we would be busy designing terrible workarounds.
Within the loop, we could also retrieve the element names following the alias that was applied to the chosen subset name.
Private subsets are possible too. To accommodate, the TI process parameter value will be something along these lines: {TM1SubsetToSet([Year].[Year], "chosen private subset name", "private")}
Example code for public/private subsets with/without an alias can be found near the end of this blog post. It can be used for "Synchronize set" too, with minor edits. The code does not use TM1 V12-specific code so it will also work in TM1 V11.
The checkbox "Show set editor in parameters prompt" allows the user to still access the Set editor for the dimension/hierarchy combination and save a subset, for instance, to subsequently pick that new subset. It would be a selection of elements ("Apply" is done, as opposed to a Save as) or a real subset ("Save as" is done). If such a choice is made rather often by multiple user, it could lead to a number of private subsets. When the user does 'Apply' rather than save and/or use an existing set, then an alias that is applied to the selection of elements cannot be picked up, unfortunately, and the principal names will be returned. As the end product is passing a parameter value to a process, the alias value might or might not be important - in some cases it will be important, in the majority of cases this will not be important information. In case it is important information, you will need to either have users working with predefined or saved subsets, either you add a Member type parameter to select a certain alias name in the relevant }ElementAttributes dimension.
In other words, this is the easiest way to ask from the user a selection of multiple existing hierarchy elements (thereby respecting security settings for a user). The users and developers do not need to know upfront all the possible combinations. Nor do we need to create a view on an }ElementAttributes or regular cube where write access allows the user to clear and select/deselect elements with a 'Y' or 'N' (like a caveman). In what follows we will see a different option to reach the same goal, whereby a selector in PAW is used rather than the Set editor. Up to you to decide what works best in a certain model/PAW UI. However, that option revolves around synchronizing elements with a PAW asset, so there is still a difference in user experience - users will decide what is easier/better.
· Cell (text and number)
The value of a parameter at run-time can be sourced from a cell in a given cube slice. Most of the time it will be used for system settings or configuration settings, but likewise any cube cell is fine. The value is retrieved and shown and it acts like a visual clue to the user who is about to execute the TI process: he/she can verify or validate or check the cell value, and if needed, abort the process execution. The cell value can be a number or a text.
Note that the user cannot change the cell value. This is not the purpose of this parameter type. The database cannot be altered for that cube cell value. However, one might consider the following case. The user is shown the cell value, for instance a folder or file location, but the user wants to deviate and go with a different value - even if it does not change the underlying cube cell value. This 'suggestion' kind of solution is not possible. Then, what is the use case for this cell type parameter? Just showing the user a value from a completely static cell (not picked up from the sheet so not dynamic at all, not changeable by user, etc.)? In the end, it could be shown in PAW too and even in an exploration that is dynamic and not necessarily complete static. Because let's not forget that, in case the cube or intersection changes, the developer needs to change 1 or more button parameters in scattered PAW books. Let's hope that the introduction of a PAW API can alleviate things in this respect.
· Synchronize member (text only)
The process automatically picks up parameter values from other synchronized items in a book. You can select the dimension and hierarchy to be synchronized under the Control Details column, as well as the synchronization group. In case of a selection of multiple elements, then only the first element makes it to the parameter value in the process. The output value can be configured as 'element name' or '[dimension_name].[hierarchy_name].[principal_element_name]' (if the "Pass member unique name" checkbox is activated).
· Synchronize set (text only)
This type is very similar to 'Synchronize member' but in this case the selection of the user is a set and this one is passed to the parameter. Just like we have seen with 'Set list', the TI process parameter value is not simply the chosen subset name, but rather an MDX expression: {TM1SubsetToSet([dim name].[hier name], "subset name", "public or private")}. Please refer to the discussion above to understand what is possible or not. Since the purpose of this control type is to use the selection(s) in asset(s) of the current PAW sheet/book, it follows that access to the Set editor is not possible. Likewise, dimension/hierarchy combinations to use are only use from the current sheet/book (with a suitable synchronization scope). When the user has a selection of elements in the synchronized hierarchy, rather than an existing subset, when an alias is applied to the selected element it cannot be picked up.
· File (text only)
This control type passes the file name of the uploaded file to the process parameter. This parameter displays only when the 'Allow file upload' property is selected in the configuration of the action button. By default, the Prompt user is disabled for this parameter.
At run-time, a canvas will appear and allow the user to upload a file from his/her computer. The file will need to match the columns/variables that the process expects it to have, if not, errors can pop up and/or unexpected behavior might be observed.
What this control type does is picking up the filename of the uploaded file, after that the file was indeed stored in a certain folder (typically, 'upload_model' in the TM1 data directory for TM1 V11 and the root folder for TM1 V12). From there, the TI process can locally access the file and read its contents. In case the filename already exists, a choice is presented: Overwrite the existing file or Create a copy.
Since we know the folder name and file name, we can also intervene and add more logic: for instance, we might want to cut or copy the file at the end of the process run (the Epilog tab) to a 'Processed OK' folder or to a 'Processed Not OK' folder. Conditionally upon there being errors or not, the uploaded file is redirected to a different location. A timestamp could be added too, to ensure file name uniqueness.
In the Prolog tab of the process, you should set DatasourceNameForServer = pFileName; to pick up the uploaded file and read its contents. If the parameter name is different then change it in the code oneliner. Note that when the checkbox 'Allow file upload' is activated but none of the parameters is of control type 'File', the user will still be asked to upload a file BUT the uploaded file is not taken into consideration. Hence the user is processing the wrong file (meaning, the file that was used by the process developer at design time). This is dangerous!
Lastly, it is not something we would do, but what if 2 process parameters are of control type 'File'? Let's say pFileName_1 and pFileName_2. The user will be able to upload 1 file, and that filename is passed to the process via both pFileName_1 and pFileName_2.
· Boolean (number only)
Binary values such as True and False (the default choices here) are offered to the user. A label can be specified in the Control detail column: Yes and No, 1 and 0, ... Irrespective of the 2 labels, the outcome will always be the number 1 (whatever is used for True) or 0 (whatever is used for False).
· Number range (number only)
Rather than specifying any number, this control type imposes a minimal value (From value) and maximal value (to value) for the parameter. A +/- kind of control is used to increase or decrease the value, but you can of course manually overwrite the value. Decimal values are still possible.
· Calendar (number only)
When using this parameter type, you will get a serial number: the number of days since Jan. 1, 1900. This is irrespective of the configuration setting "UseExcelSerialDate" (which is a static parameter). The output value always matches the Excel way of calculating days since a certain day 1. Consequently, if the TM1 model at hand has UseExcelSerialDate=F, then we need to subtract the well-known value of 21,916 days to start counting as of Jan. 1, 1960.
You can definitely use additional date functions in TI to manipulate the chosen value. For example, you can compute the chosen year, month, day, etc.
TI code example when the calendar value is today, August 16, 2025:
# 45885
ASCIIOutput( 'test.txt', NumberToString( pCalendar ));
# 2025-08-16
vYearMonthDay = Timst( pCalendar - 21916, '\Y-\m-\d' );
ASCIIOutput( 'test.txt', vYearMonthDay );
TI code example to work with parameters with a subset control type (it is lengthy but quite complete):
vFile = 'output.txt';
AsciiOutput( vFile, p_Set_List );
vPos_Opening_Bracket_1 = Scan( '[', p_Set_List );
vPos_Closing_Bracket_1 = Scan( ']', p_Set_List );
vDim_From_Parameter = Subst( p_Set_List, vPos_Opening_Bracket_1 + 1, vPos_Closing_Bracket_1 - vPos_Opening_Bracket_1 - 1 );
vPos_Opening_Bracket_2 = Scan( '].[', p_Set_List ) + 2;
vPos_Closing_Bracket_2 = Scan( '],', p_Set_List );
vHier_From_Parameter = Subst( p_Set_List, vPos_Opening_Bracket_2 + 1, vPos_Closing_Bracket_2 - vPos_Opening_Bracket_2 - 1 );
vPos_Opening_Quotes = Scan( ', "', p_Set_List ) + 2;
vPos_Closing_Quotes = Scan( '",', p_Set_List );
vSub_From_Parameter = Subst( p_Set_List, vPos_Opening_Quotes + 1, vPos_Closing_Quotes - vPos_Opening_Quotes - 1 );
If( DimensionExists( vDim_From_Parameter ) = 0 );
LogOutput( 'ERROR', 'The dimension ''' | vDim_From_Parameter | ''' does not exist. Please investigate.' );
ProcessError;
EndIf;
If( HierarchyExists( vDim_From_Parameter, vHier_From_Parameter ) = 0 );
LogOutput( 'ERROR', 'The hierarchy ''' | vHier_From_Parameter | ''' in the dimension ''' | vDim_From_Parameter | ''' does not exist. Please investigate.' );
ProcessError;
EndIf;
vSub_Public_or_Private = '';
If( Scan( '"public"', Lower( p_Set_List )) > 0 );
vSub_Public_or_Private = 'public';
If( HierarchySubsetExists( vDim_From_Parameter, vHier_From_Parameter, vSub_From_Parameter ) = 0 );
LogOutput( 'ERROR', 'The public subset ''' | vSub_From_Parameter | ''' in the hierarchy ''' | vHier_From_Parameter | ''' in the dimension ''' | vDim_From_Parameter | ''' does not exist. Please investigate.' );
ProcessError;
EndIf;
vAlias = HierarchySubsetAliasGet( vDim_From_Parameter, vHier_From_Parameter, vSub_From_Parameter );
ElseIf( Scan( '"private"', Lower( p_Set_List )) > 0 );
vSub_Public_or_Private = 'private';
EndIf;
vTemporary_Subset = 'temp';
SubsetCreateByMDX( vTemporary_Subset, p_Set_List, 1 );
# Loop over the elements of the chosen subset, retrieve principal names or alias values
index = 1;
While( index <= HierarchySubsetGetSize( vDim_From_Parameter, vHier_From_Parameter, vTemporary_Subset ));
vElement = HierarchySubsetGetElementName( vDim_From_Parameter, vHier_From_Parameter, vTemporary_Subset, index );
If( vAlias @= '' );
AsciiOutput( vFile, vElement );
Else;
vAlias_Value = ElementAttrS( vDim_From_Parameter, vHier_From_Parameter, vElement, vAlias );
If( vAlias_Value @= '' );
vAlias_Value = vElement;
EndIf;
AsciiOutput( vFile, vAlias_Value );
EndIf;
index = index + 1;
End;
#IBMChampion