Product:
Planning Analytics 2.0.9.19
Microsoft Windows 2019 server

Issue:
How export a cube to file?

Suggested solution:

If you have a cube that looks like this, in planning sample, you can export it with a TM1 TI process.

You can write a process to export it that should look like this:

#Section Prolog

# -- get the time --
LastProcessStart = TIMST(NOW, '\Y-\m-\D \h:\i:\s');

# -- set the process as a subset name --
sName = GetProcessName();
ViewName = sName ;
SubName = sName ;

# -- check the folder to save the environment file 
DimName1='SYS_ServerParameters';
Element1 = 'ServerName' ;
Element2 = 'LastUpdated' ;

# -- find the data folder from the path of the logs folders---
sLogDirName1 = LOWER ('Logfiles\' ) ;
sLogDirName2 = LOWER ('Logs\' ) ;
sDataDirName = LOWER ( 'Data\' ) ;
sBackupDirName = LOWER ( 'Config\' );
sENvFileName = 'environment.txt' ;
sLogDirPath = LOWER( GetProcessErrorFileDirectory );

nLyckadScan1 = SCAN (sLogDirName1, sLogDirPath) ;
nLyckadScan2 = SCAN (sLogDirName2, sLogDirPath) ;
IF ( nLyckadScan1 <> 0 );
sDataDirPath = DELET (sLogDirPath, nLyckadScan1, LONG (sLogDirName1)) | sDataDirName;
sEnvDirPath = DELET (sLogDirPath, nLyckadScan1, LONG (sLogDirName1)) | sENvFileName;
ELSEIF ( nLyckadScan2 <> 0 );
sDataDirPath = DELET (sLogDirPath, nLyckadScan2, LONG (sLogDirName2)) | sDataDirName;
sEnvDirPath = DELET (sLogDirPath, nLyckadScan2, LONG (sLogDirName2)) | sENvFileName;
ELSE;
# the log folder does not have this name use this then --
sEnvDirPath = 'D:\Program Files\ibm\cognos\tm1_64\samples\tm1\PlanSamp\' | sEnvFileName ;
ENDIF;

# -- check that the cube exist
cube = 'Systemparameters';
DimName3 = 'Sysparameters' ;
DimName4 = 'Measure Parameter';
DimName5= 'Text' ;

IF ( CubeExists( Cube ) = 0 ) ;
# -- if cube does not exist - stop the process --
ProcessQuit ;
ENDIF;

# build the view - but first destroy it
ViewDestroy ( Cube, ViewName );
SubsetDestroy ( DimName3, SubName );
SubsetDestroy ( DimName4, SubName );

#-- create a view --
ViewCreate ( Cube, ViewName );

#-- create the subsets --
SubsetCreateByMDX ( SubName, '{TM1FILTERBYLEVEL( {TM1SUBSETALL( [' | DimName3 | '] )}, 0)}' );
SubsetCreateByMDX ( SubName, '{TM1FILTERBYLEVEL( {TM1SUBSETALL( [' | DimName4 | '] )}, 0)}' );

ViewSubsetAssign ( Cube, ViewName, DimName3, SubName );
ViewSubsetAssign ( Cube, ViewName, DimName4, SubName );

# -- set the source to skip calculated values --
ViewExtractSkipCalcsSet ( Cube, ViewName, 1);
ViewExtractSkipRuleValuesSet ( Cube, ViewName, 0 );
ViewExtractSkipZeroesSet ( Cube, ViewName, 1 );

# -- Set source --
DataSourceType='VIEW';
DataSourceNameForServer=Cube;
DataSourceCubeview=ViewName;

# -- Change to get comma in the text file
DatasourceASCIIQuoteCharacter='"';
DatasourceASCIIDelimiter = ',';

#Section Metadata

# -- get the servername from dimension --
aServerName = ATTRS( DimName1, Element1 , 'value') ;
vApplication = aServerName | ':' | DimName3 ;

# -- export the values to file --
ASCIIOutput( sEnvDirPath, vApplication ,v1,v2,v3 );


#Section Data



#Section Epilog

ViewDestroy ( Cube, ViewName );
SubsetDestroy ( DimName3, SubName );
SubsetDestroy ( DimName4, SubName );

 

The TI process need to have a data source like this:

The file will look like below;

 

You can write a process to import the csv file that can look like this (you have to adjust the code to your environment) :

#Section Prolog

# -- get the time --
LastProcessStart = TIMST(NOW, '\Y-\m-\D \h:\i:\s');

# -- check the folder to load the environment file from
DimName1='SYS_ServerParameters';
Element1 = 'ServerName' ;
Element2 = 'LastUpdated' ;

# -- try to find the data folder from the logs folder ---
sLogDirName1 = LOWER ('Logfiles\' ) ;
sLogDirName2 = LOWER ('Logs\' ) ;
sDataDirName = LOWER ( 'Data\' ) ;
sBackupDirName = LOWER ( 'Config\' );
sEnvFileName = 'environment.txt' ;
sLogDirPath = LOWER( GetProcessErrorFileDirectory );

nLyckadScan1 = SCAN (sLogDirName1, sLogDirPath) ;
nLyckadScan2 = SCAN (sLogDirName2, sLogDirPath) ;
IF ( nLyckadScan1 <> 0 );
sDataDirPath = DELET (sLogDirPath, nLyckadScan1, LONG (sLogDirName1)) | sDataDirName;
sEnvDirPath = DELET (sLogDirPath, nLyckadScan1, LONG (sLogDirName1)) | sEnvFileName;
ELSEIF ( nLyckadScan2 <> 0 );
sDataDirPath = DELET (sLogDirPath, nLyckadScan2, LONG (sLogDirName2)) | sDataDirName;
sEnvDirPath = DELET (sLogDirPath, nLyckadScan2, LONG (sLogDirName2)) | sEnvFileName;
ELSE;
# we chance that the log and data folder are the same
sEnvDirPath = 'D:\Program Files\ibm\cognos\tm1_64\samples\tm1\PlanSamp\' | sEnvFileName ;
ENDIF;


# -- setup the parameter cube --
cube2 = 'Systemparameters';
DimName3 = 'Sysparameters' ;
DimName4 = 'Measure Parameter';
Element5= 'Text' ;

# -- check that that the cube exist
IF ( CubeExists( Cube2 ) = 0 ) ;
IF (DimensionExists( DimName3 ) = 0 ) ;
DimensionCreate (DimName3 ) ;
ENDIF;
IF (DimensionExists( DimName4 ) = 0 ) ;
DimensionCreate (DimName4 ) ;
ENDIF;
# -- create a cube
CubeCreate(Cube2, DimName3 , DimName4 );
ENDIF;

DimensionElementInsertDirect (DimName4, '', Element5 ,'S') ;


# -- set the source to be the file
DatasourceNameForServer = sEnvDirPath ;
DatasourceNameForClient = sEnvDirPath ;

#Section Metadata

#-- check that the application is correct from the file
# SCAN(substring, string)
vLocation = SCAN(':',vApplication ) ;
vServerName = SUBST( vApplication, 1, vlocation - 1 ) ;
aServerName = ATTRS( DimName1, Element1 , 'value') ;
IF (aServerName @<> vServerName);
ProcessQuit;
ENDIF;

# -- add the dimension element from vParameter
# DimensionElementInsertDirect(DimName, InsertionPoint, ElName,ElType);
DimensionElementInsertDirect (DimName3, '', vParameter ,'S') ;

# -- add the lastupdated parameter
DimensionElementInsertDirect (DimName3, '', Element2 ,'S') ;

#Section Data

# -- load the data to the cube 
CellPutS( vValue, cube2, vParameter, vColumn );


#Section Epilog

# -- write the time to cube
CellPutS( LastProcessStart, cube2, Element2, vColumn );

The import TI process need to have a file as data source, similar to this:

Both process demand that you have a dimension (SYS_ServerParameters) that have the name of the application.

This can be done with the process SYS.GET_ServerParameters.

More Information:

https://www.ibm.com/docs/ru/planning-analytics/2.0.0?topic=data-exporting-from-cube

https://www.ibm.com/docs/en/cognos-tm1/10.2.2?topic=file-parameters-in-tm1scfg 

https://exploringtm1.com/how-to-create-a-tm1-model-a-best-practice-guide/

https://cubewise.com/blog/adjusting-server-configuration-planning-analytics/

https://bihints.com/book/export/html/100

https://exploringtm1.com/text-file-export-tm1-asciioutput-functions/

Product:
Planning Analytics 2.0.9.19
Microsoft Windows 2019 server

Issue:
I would like to turn of the DEV Tm1 servers during the weekend, can i do it with a chore?

Solution:

Create a parameter cube, something like below, add the tm1 instance name in the application column. Set a Y in Stop column if you would like the chore to stop the service. In the last two columns, we update the time when it was stopped or started.

# -- setup the parameter cube --

Cube = 'ScheduleCube' ;
DimName1 = 'sApplication' ;
DimName2 = 'ScheduleMeasures' ;
sLoadtestdata = 'NO' ;
# sLoadtestdata = 'YES' ;

DimensionDestroy (DimName1 ) ;
DimensionCreate (DimName1 ) ;

# -- add elements
nNum = 1;
While( nNum <= 15 );
sNum = numbertostring (nNum) ;
DimensionElementInsertDirect(DimName1 ,'', sNum , 'N' ) ;
nNum = nNum + 1;
End;



DimensionDestroy (DimName2);
DimensionCreate (DimName2 );

# -- add elements
DimensionElementInsertDirect (DimName2 ,'', 'Application' , 'S' ) ;
DimensionElementInsertDirect (DimName2 ,'', 'Text' , 'S' ) ;
DimensionElementInsertDirect (DimName2 ,'', 'StartRun' , 'S' ) ;
DimensionElementInsertDirect (DimName2 ,'', 'StopRun' , 'S' ) ;
DimensionElementInsertDirect (DimName2 ,'', 'Stop' , 'S' ) ;
DimensionElementInsertDirect (DimName2 ,'', 'Start' , 'S' ) ;
DimensionElementInsertDirect (DimName2 ,'', 'Last Stopped' , 'S' ) ;
DimensionElementInsertDirect (DimName2 ,'', 'Last Started' , 'S' ) ;


# -- create a cube
CubeCreate(Cube, DimName1 , DimName2 );

# -- add data to cube --

IF ( sLoadtestdata @= 'YES' ) ;
cellputs ( 'planning sample' , Cube , '1' , 'application' ) ;
cellputs ( 'Y' , Cube , '1' , 'Start' ) ;
cellputs ( 'Y' , Cube , '1' , 'Stop' ) ;
cellputs ( 'proven_techniques' , Cube , '2' , 'application' ) ;

# -- add your default test data here -- 
ENDIF;

Create then a TM1 TI process to stop services:

# --- stop a service --

Cube = 'ScheduleCube' ;
DimName1 = 'sApplication' ;
DimName2 = 'ScheduleMeasures' ;

# -- check number of elements --
nLong = DIMSIZ (DimName1) ;
nNum = 1 ;
WHILE ( nNum <= nLong ) ;
sNum = numbertostring (nNum) ;
# -- get the application name --
sApp = CELLGETS ( cube , sNum, 'Application' ) ;
# -- check that it is not empty --
IF (LONG (sApp) <> 0 );
# -- check that it is suppose to be stopped --
IF ('Y' @= CELLGETS ( cube, sNum, 'Stop' ) ) ;

# -- get the time and put in the cube --
sTime = TIMST(now, '\Y-\m-\d \h:\i:\s');
CELLPUTS ( sTime, cube, sNum, 'Last Stopped' ) ;
# -- make the call to stop --

sBatchFile = 'NET STOP "' | sApp |'"' ;
ExecuteCommand('cmd /c ' | sBatchFile, 0);

ENDIF;
ENDIF;
nNum = nNum +1 ;
END;


Create a TM1 TI process to start services:

# -- start a service --

Cube = 'ScheduleCube' ;
DimName1 = 'sApplication' ;
DimName2 = 'ScheduleMeasures' ;

# -- check number of elements --
nLong = DIMSIZ (DimName1) ;
nNum = 1 ;
WHILE ( nNum <= nLong ) ;
sNum = numbertostring (nNum) ;
# -- get the application name --
sApp = CELLGETS ( cube , sNum, 'Application' ) ;
# -- check that it is not empty
IF (LONG (sApp) <> 0 );
# check that it is suppose to be started --
IF ('Y' @= CELLGETS ( cube, sNum, 'Start' ) ) ;

# -- get the time and put in the cube --
sTime = TIMST(now, '\Y-\m-\d \h:\i:\s');
CELLPUTS ( sTime, cube, sNum, 'Last Started' ) ;
# -- make the call to start --

sBatchFile = 'NET START "' | sApp |'"' ;

ExecuteCommand('cmd /c ' | sBatchFile, 0);

ENDIF;
ENDIF;
nNum = nNum +1 ;
END;

 

Schedule them in cores, to run on Friday at 2300 and on Monday at 0300 – to get it to stop and start the service.

I recommend that you have a “savedataall” in the TM1 applications that run every Friday before above.

Set the chore to start on the weekday it should stop the service, and set it to run the chore every 7 days.

More Information about other things:

https://www.ibm.com/docs/en/planning-analytics/2.0.0?topic=smtf-savedataall

https://www.mci.co.za/business-performance-management/learning-mdx-views-in-ibm-planning-analytics/

Primary sales forecasting using PA, SPSS Modeler and python

https://www.wimgielis.com/tm1_createatestcube_EN.htm

Product:

Planning Analytics 2.0.9.19
Microsoft Windows 2019 server

Issue:

TI Process take longer to run – and TM1 Architect is non responsive. If you check the tm1server.log file, you find text like this:

TM1.Server sf_Rename: Failed to rename (d:\tm1data\products}subs\nameoftheprocesshaveingissus.sub) to (d:\tm1data\products}subs\nameoftheprocesshaveingissus.sub$$$). Error: error code:5 reason:”Access is denied.” file..
….could not rename file to intermediate file, “nameoftheprocesshaveingissus.sub” to “nameoftheprocesshaveingissus.sub$$$” after 10 retrys in 20 seconds…

 

Solution:

Go into Windows service and change the user that run the Cognos TM1 server instance to be Local System instead of a specific user or service account.

Maybe security demands on the server NTFS have change by use of any new Windows Policy.

Make certain you are logged into Windows with a user account that has permission to access the location (the folder where the tm1 application is). In the case of running any process that create subset or views, you will need to make sure your user account (that run the TM1 service) has permission to save files to the software’s data and subfolders.

 

Product:

Planning Analytics 2.0.9.19
Microsoft Windows 2019 Server

Issue:
How start or stop a TM1 instance from command line?

Solution:

There is a bat file in the TM1 installation you can take help from – check the folder : C:\Program Files\ibm\cognos\tm1_64\bin64

startup_tm1s.bat <path to tm1s.cfg file> { <TM1 Server Name> }

Above will start the TM1 if it is installed, otherwise it will install the TM1 instance and start it. Service_tm1s.bat file will both start and stop a TM1 instance.

Write a CMD file that have command of this character to use it;

Here we start TM1 instance FAP, in folder c:\tm1data\FAP\config.

>service_tm1s.bat stop TM1ServerConfigFolder TM1Servername

>service_tm1s.bat start TM1ServerConfigFolder TM1Servername

The downsize is that you need to inform of the path to the TM1 config file.

A bat file with the NET START command is better.

REM Stop the services
NET STOP "FAP" /Y

REM Start the services again
NET START "FAP"

More Information:

https://www.wimgielis.com/tm1_backup_EN.htm 

https://exploringtm1.com/how-to-do-a-daily-or-weekly-restart-a-tm1-model/

https://ecapitaladvisors.com/blog/how-to-set-up-turbo-integrator-chores-to-run-advanced-scheduling/ 

https://www.coretechnologies.com/products/ServiceScheduler/ 

https://support.pelco.com/s/article/Configure-a-Windows-service-to-restart-on-a-schedule-using-Task-Scheduler-1538586706677?language=en_US 

Product:

Planning Analytics 2.0.9.19

Issue:

Want the user name, running the TM1 TI process to be in the filename – how?

Solution:

There are many ways to do this, check internet and tm1py.

But this is a suggestion, when you use CAMID with Cognos Analytics:

# -- get the user
sUserRAW = TM1User() ;

IF ( SCAN ('R*S' ,sUserRAW ) <> 0 ) ;
sUser = 'Scheduled' ;
ELSE;
# -- get the alias 
sUserALIAS = ATTRS( '}Clients' , sUserRaw , '}TM1_DefaultDisplayValue') ;
# -- find the name part of the domain/name 
sUserBREAK = SCAN ( '/' , sUserALIAS ) ;
# -- SUBST(string, beginning, length) 
sUser = SUBST( sUserALIAS, sUserBREAK +1, LONG (sUserALIAS) - ( sUserBREAK ) ) ;
ENDIF;

sFileName = 'Data.' | sUser | '.' | TIMST( NOW(), '\Y\m\d.\h\i', 1) | '.zip';

 

 

More Information:

https://everanalytics.wordpress.com/2017/08/10/tm1_alias_attributes/ 

https://www.ibm.com/docs/en/planning-analytics/2.1.0?topic=mtf-tm1user

Product:

Planning Analytics 2.0.9.19

Issue:

When we copy the production TM1 instance to the development server, we have to turn off all the chores – is there a simpler way?

Solution:

Create a TM1 TI process that check a environment cube value, that is stored in a separate data folder, that tell if it is TEST or PROD server you run in.

Then add this TI process first in all the chores, so when a chore is run, it first checks if it is in TEST, and then quits the chore.

In the log file you will have a text like this: TM1.Process Process “SYS. Turn off this chore if in TEST”: : Execution was aborted by ChoreQuit() Function. : ChoreQuit() function called

To be able to temporary run the chore, we have a prompt in the TI process, that you can set to YES in the schedule, to make it run in your development environment.

Prompt can look like this:

Code should be like this in PROLOG:

sEnvironment = CellGetS( 'systemparameters', 'Environment' , 'Text');
IF ( sEnvironment @= 'Test') ;
IF ( pRun @<> 'YES' );
ChoreQuit ;
ENDIF; 
ENDIF;

 

More Information:

How to set up Turbo Integrator Chores to run Advanced Scheduling

https://bihints.com/closer-look-chores

https://www.ibm.com/docs/en/planning-analytics/2.1.0?topic=functions-chorequit

Product:

Planning Analytics 2.0.9.19

Planning Analytics Workspace version 96

Microsoft Windows 2019

Issue:

The csv files amount have changed from period to comma for decimals when we run the TM1 TI process?

Possible Solution:

Depending from where you start your TM1 TI process, the local region settings will affect the decimal separator in the file.

If you run a TM1 TI process from PAW in EDGE set to Swedish for language and spelling, then the value will have a comma (,) as a decimal separator.

If you run a TM1 TI process from PAW in EDGE or CHROME set to English for language and spelling, then the value will have a period (.) as a decimal separator.

Check the web browser options – language and ensure that you have English as first choice to get a period as decimal separator like 100.99

TM1 Architect will use the region settings of the users value in Windows control panel.

 

You can set values in the TM1 TI process, to make conversion of value work, but the ASCIIOUTPUT may not be affected.

DatasourceASCIIDecimalSeparator TurboIntegrator local variable sets the decimal separator to be used in any conversion of a string to a number or a number to a string. If you set this variable you must also set the DatasourceASCIIThousandSeparator variable. This will affect NumberToString (value) but not ASCIIOUTPUT (value).

The character specified must be a standard ASCII printable character, with a decimal value between 33 and 127 inclusive.

Either of the following examples sets the comma character (,) as the separator.

DatasourceASCIIDecimalSeparator=',';
DatasourceASCIIDecimalSeparator=Char(44);

More Information:

https://cubewise.com/functions-library/tm1-function-for-ti-numbertostringex/ 

https://cubewise.com/functions-library/tm1-function-for-ti-datasourceasciidecimalseparator/

https://www.ibm.com/docs/en/planning-analytics/2.0.0?topic=variables-datasourceasciithousandseparator 

What is the syntax for NumberToStringEx?

NumberToStringEx(Value, NumericFormat, DecimalSep, ThousandsSep)

  • Value = any real number​
  • NumericFormat = TM1 numeric format string e.g. #,0.## ​
  • DecimalSep = Decimal separator to be used in the output​
  • ThousandsSep = Thousands separator to be used in the output

https://www.ibm.com/docs/en/planning-analytics/2.0.0?topic=trf-numbr-1

https://www.ibm.com/docs/en/planning-analytics/2.0.0?topic=functions-asciioutput 

Product:

Planning Analytics 2.0.9.19
Microsoft Windows 2019 server

Issue:

How can i find data path to TM1 session?

Solution:

Search the internet and use the code to build something like this, it will check if the TM1S.CFG file is in the data or a \config\ folder, and then load the data from TM1S.CFG file to a dimensions, that you later can ask in your code for information from.

 

#Section Prolog
#****Begin: Generated Statements***
#****End: Generated Statements****

# -- get the data folder if the logs folder is logs or logfiles ---
sLogDirName1 = LOWER ('Logfiles\' ) ;
sLogDirName2 = LOWER ('Logs\' ) ;
sConfigDirName = LOWER ('Config\') ;
sDataDirName = LOWER ( 'Data\' ) ;
sBackupDirName = LOWER ( 'Backup\' );
sLogDirPath = LOWER( GetProcessErrorFileDirectory );

nLScan1 = SCAN (sLogDirName1, sLogDirPath) ;
nLScan2 = SCAN (sLogDirName2, sLogDirPath) ;
IF ( nLyckadScan1 <> 0 );
# sDataDirPath = DELET (sLogDirPath, nLScan1, LONG (sLogDirName1)) | sDataDirName;
# sBackupDirPath = DELET (sLogDirPath, nLScan1, LONG (sLogDirName1)) | sBackupDirName;
sConfigDirPath = DELET (sLogDirPath, nLScan1, LONG (sLogDirName1)) ;
ELSEIF ( nLyckadScan2 <> 0 );
# sDataDirPath = DELET (sLogDirPath, nLScan2, LONG (sLogDirName2)) | sDataDirName;
# sBackupDirPath = DELET (sLogDirPath, nLScan2, LONG (sLogDirName2)) | sBackupDirName;
sConfigDirPath = DELET (sLogDirPath, nLScan2, LONG (sLogDirName2)) ;
ELSE;
# the log folder can be the same as the datafolder 
sConfigDirPath = sLogDirPath ;
ENDIF;

CFGpath = sConfigDirPath ;

pParamsList=UPPER(':adminhost:ServerName:DataBaseDirectory:PortNumber:ClientMessagePortNumber:ServerCAMURI:LoggingDirectory:MTQ:HTTPPortNumber:IntegratedSecurityMode');
Dlmtr=';';
LenDtr=LONG(Dlmtr);
DataSourceType='CHARACTERDELIMITED';
# -- change the folder options to match your setup ---
sAfolder = 'config\' ;
ConfigFile = 'Tm1s.cfg';

IF (FileExists(CFGpath | sAfolder | ConfigFile ) = 1 ) ;
DatasourceNameForClient= CFGpath | sAfolder | ConfigFile;
DatasourceNameForServer= CFGpath | sAfolder | ConfigFile;

ELSEIF (FileExists(CFGpath | ConfigFile ) = 1 ) ;
DatasourceNameForClient= CFGpath | ConfigFile;
DatasourceNameForServer= CFGpath | ConfigFile;
ELSE;
# -- will use tm1s.cfg in the data folder --
DatasourceNameForClient= 'Tm1s.cfg';
DatasourceNameForServer= 'Tm1s.cfg';
ENDIF;


DatasourceASCIIDelimiter='=';
DatasourceASCIIHeaderRecords=1;

DimName='SYS_ServerParameters';
IF( DimensionExists(DimName) = 0 );
DimensionCreate( DimName );
ENDIF;

IF( CubeExists( '}ElementAttributes_'|DimName )=0 );
AttrInsert( DimName , '' , 'Value' , 'S' );
ENDIF;

IF( CubeExists( '}ElementAttributes_'|DimName )=1 );
IF(DIMIX( '}ElementAttributes_'|DimName , 'Value' )=0 );
AttrInsert( DimName , '' , 'Value' , 'S' );
ENDIF;
ENDIF;

#Section Metadata

#****Begin: Generated Statements***
#****End: Generated Statements****
#Section Data

#****Begin: Generated Statements***
#****End: Generated Statements****


IF( SUBST( Param , 1 , 1)@<>'#' & Param @<>'' & SCAN(UPPER(Param) , pParamsList)>0 );

IF( SCAN( ';' , Value )>0 );
CurPos=1;
ValueList=Value|Dlmtr;
ParamNum='';
i=0;
WHILE(CurPos>0&LONG( ValueList )>0);
CurPos=SCAN( Dlmtr , ValueList );
Value=SUBST( ValueList , 1, CurPos-1);
ValueList=DELET( ValueList, 1, CurPos+LenDtr-1);
#LOGOUTPUT( 'INFO' , Param | ParamNum |' = '| Value );
DimensionElementInsertDirect(DimName, '', Param | ParamNum ,'N');
AttrPutS(Value, DimName, Param | ParamNum , 'Value' );
i=i+1;
ParamNum=NUMBERTOSTRING(i);
END;
ELSE;

#LOGOUTPUT( 'INFO' , Param |'='| Value ); 
DimensionElementInsertDirect(DimName, '', Param ,'N');
AttrPutS(Value, DimName, Param , 'Value' );
ENDIF;

ENDIF;
#Section Epilog

#****Begin: Generated Statements***
#****End: Generated Statements****

More Information:
https://www.ibm.com/docs/en/planning-analytics/2.0.0?topic=trf-delet-1

https://www.ibm.com/docs/en/planning-analytics/2.1.0?topic=pctf-getprocesserrorfiledirectory 

https://www.ibm.com/docs/en/cognos-tm1/10.2.2?topic=chores-running-chore-server-startup 

Product:
Planning Analytics 2.0.19
Microsoft Windows 2019 server

Issue:
How get the parent and child of a dimension to a text file?

 

Solution:

Create a new TM1 TI process with the data source to the dimension.

And a parameter where you enter the dimension:

And the TM1 code as below:

#Section Prolog


# -- check the enter value to not be blank --
IF (LONG(pDimension) = 0 ) ;
sDim = 'account' ;
ELSE;
sDim = pDimension ;
ENDIF;
sOutputFile = 'D:\temp\' | sDim | '.csv';

# -- set the dimension as source --
DatasourceNameForServer = sDim ;
DatasourceNameForClient = sDim ;
DATASOURCEDIMENSIONSUBSET = 'all';

#Section Metadata

#Section Data

# ----- export the dimension ---

sElementType = DTYPE ( sDim, v1 );
# always output the element and its type
AsciiOutput ( sOutputFile, sElementType , v1 );
# cycle through children if it is a consolidated element
IF ( sElementType @= 'C' );
iCount = 1;
iMax = ElCompN ( sDim, v1 );
While ( iCount <= iMax );
sChild = ElComp ( sDim, v1, iCount );
sWeight = NumberToString ( ElWeight ( sDim, v1, sChild ) );
AsciiOutput ( sOutputFile, '', sChild , sWeight );
iCount = iCount + 1;
End;
EndIf;

#Section Epilog


This need to be adjusted to meet your needs.

 

More Information:

https://exploringtm1.com/how-to-use-a-dynamic-path-in-a-ti-for-a-data-source/ 

https://www.ibm.com/docs/en/cognos-tm1/10.2.2?topic=variables-datasourcedimensionsubset

https://lodestarsolutions.com/tag/tm1-dimension-subsets/

https://www.wimgielis.com/tm1_mdxstatements_EN.htm

Product:
Planning Analytics 2.0.9.19

Microsoft Windows 2019 server

Issue:
How send mail with powershell from Tm1?

Solution:

Create a folder on your tm1 server called d:\script\ , and in there create a file SENDMAIL.PS1 in Notepad++ with this content:

# Define the paths to your text files
$messageFilePath = "d:\script\message.txt"
$recipientFilePath = "d:\script\recipient.txt"

# Read the content of the text files
$messageBody = Get-Content -Path $messageFilePath -Raw
$recipient = Get-Content -Path $recipientFilePath -Raw

# Define the email parameters
$smtpServer = "smtp.yourserver.com"
$from = "your-email@domain.com"
$subject = "Your Subject Here"

# Send the email
Send-MailMessage -From $from -To $recipient -Subject $subject -Body $messageBody -SmtpServer $smtpServer

Update the $messageFilePath and $recipientFilePath variables with the paths to your text files.
Make sure to replace “smtp.yourserver.com” and “your-email@domain.com” with your actual SMTP server and email address.

Create a file “message.txt” with the text you want to send as body.
Create a file “recipient.txt” with the email person with the receiver of the mail.

 

Then create a TM1 TI process with above prompt, and below code:

#Section Prolog

#--- set variables ----
vFileMessage = 'd:\script\message.txt' ;
vFileRecipient = 'd:\script\recipient.txt' ;
toPerson = 'tm1@company.com' ;
toMessage = 'This is a test - something went wrong' ;

#--- check the prompts -----------
isMail = scan ( '@' , pReciver) ;
IF ( isMail <> 0 ) ;
toPerson = pReciver ;
ENDIF ;

IF ( LONG (pMessage) <> 0 ) ;
toMessage = pMessage ;
ENDIF ;

# --- Change to get clean text in the text file
DatasourceASCIIQuoteCharacter='';
DatasourceASCIIDelimiter = ',';
#--- try change this value to support other characters than english ------
setOutputCharacterSet (vFileMessage, 'TM1CS_ISO_8859_1');

#-------write the files-------------
TextOutput( vFileRecipient, toPerson ) ;
TextOutput( vFileMessage, toMessage ) ;

#Section Metadata

#Section Data

#Section Epilog

# call the powershell file to send the mail
ExecuteCommand( 'Powershell -ExecutionPolicy ByPass -file "D:\script\sendmail.ps1" ', 1 );

 

Run the process, to test it.

More Information:

https://www.ibm.com/docs/en/planning-analytics/2.0.0?topic=attf-setinputcharacterset-1

https://edu.cubewise.com/functions-library/tm1-function-for-ti-setoutputcharacterset

https://www.ibm.com/docs/it/cognos-tm1/10.2.2?topic=SS9RXT_10.2.2/com.ibm.swg.ba.cognos.tm1_ref.10.2.2.doc/r_tm1_ref_tifun_asciioutput.htm

https://www.ibm.com/docs/en/planning-analytics/2.0.0?topic=tf-ascii-text-turbointegrator-functions 

https://lazyadmin.nl/powershell/send-email-powershell/ 

https://mailtrap.io/blog/powershell-send-email/