From c97bfbb95420edd64cb4e57bd4e75982566dac95 Mon Sep 17 00:00:00 2001 From: Paul Niederbracht - OLAPLINE GmbH Date: Mon, 18 May 2026 14:26:26 +0200 Subject: [PATCH 1/2] =?UTF-8?q?}bedrock.hier.clone=20=E2=80=93=20N?= =?UTF-8?q?=E2=86=92C=20Element=20Conversion,=20Extended=20Attribute=20Han?= =?UTF-8?q?dling=20&=20Subset/MDX=20Filter=20Support?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + main/}bedrock.hier.clone (2).pro | 617 ++++++++++++++++++++++++ main_asJSON/}bedrock.hier.clone.json | 89 ++++ wiki_content/wiki_bedrock.hier.clone.md | 182 +++++++ 4 files changed, 889 insertions(+) create mode 100644 main/}bedrock.hier.clone (2).pro create mode 100644 main_asJSON/}bedrock.hier.clone.json create mode 100644 wiki_content/wiki_bedrock.hier.clone.md diff --git a/.gitignore b/.gitignore index b60bffe..af7b0ba 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,4 @@ *.log *.debug *.txt +/.vs diff --git a/main/}bedrock.hier.clone (2).pro b/main/}bedrock.hier.clone (2).pro new file mode 100644 index 0000000..0913a1c --- /dev/null +++ b/main/}bedrock.hier.clone (2).pro @@ -0,0 +1,617 @@ +601,100 +602,"}bedrock.hier.clone" +562,"SUBSET" +586,"}Cubes" +585,"}Cubes" +564, +565,"x1Wi2=X?2Gz6r3ZWh3[r28Zba@pwD]Aw^_WDtYcQ7F8bIRkrOsgwsNN[IFhTei[:IZBrxBNQ:yD4wM7Lfw6TAVT64EBoTF_MA``H;6z\6Uhvfzjdu6lBe>VbLXZEWbsbvB0@4yrot2oaGz6vhKE_dKClT>LMiJVyd:dV_S^?O1bcMcbpNRR>w;_3DndoRD==nP@wj;Pc" +559,1 +928,0 +593, +594, +595, +597, +598, +596, +800, +801, +566,0 +567,"," +588,"," +589,"." +568,"""" +570, +571,All +569,0 +592,0 +599,1000 +560,10 +pLogOutput +pStrictErrorHandling +pSrcDim +pSrcHier +pTgtDim +pTgtHier +pAttr +pUnwind +pIfNthanC +pSrcFilter +561,10 +1 +1 +2 +2 +2 +2 +1 +1 +1 +2 +590,10 +pLogOutput,0 +pStrictErrorHandling,0 +pSrcDim,"" +pSrcHier,"" +pTgtDim,"" +pTgtHier,"" +pAttr,0 +pUnwind,0 +pIfNthanC,0 +pSrcFilter,"" +637,10 +pLogOutput,"OPTIONAL: Write parameters and action summary to server message log (Boolean True = 1)" +pStrictErrorHandling,"OPTIONAL: On encountering any error, exit with major error status by ProcessQuit after writing to the server message log (Boolean True = 1)" +pSrcDim,"REQUIRED: Source Dimension" +pSrcHier,"REQUIRED: Source Hierarchy" +pTgtDim,"REQUIRED: Target Dimension (can be the same as source)" +pTgtHier,"OPTIONAL: Target Hierarchy (will default to SrcHier_Clone if the dimensions are the same)" +pAttr,"OPTIONAL: Include Attributes? (Boolean 1=True; 2 = only existing)" +pUnwind,"REQUIRED: Unwind? (0 = Delete all Elements, 1 = Unwind Existing Elements, 2 = Do not change Existing Elements (Only relevant if target hierarchy exists) )" +pIfNthanC,"OPTIONAL: if 1 than all N-elemens will be created as c-elements" +pSrcFilter,"OPTIONAL: Source filter. Use Subset: or MDX:" +577,1 +vEle +578,1 +2 +579,1 +1 +580,1 +0 +581,1 +0 +582,1 +VarType=32 ColType=827 +603,0 +572,292 +#Region CallThisProcess +# A snippet of code provided as an example how to call this process should the developer be working on a system without access to an editor with auto-complete. +If( 1 = 0 ); + ExecuteProcess( '}bedrock.hier.clone', 'pLogOutput', pLogOutput, + 'pStrictErrorHandling', pStrictErrorHandling, + 'pSrcDim', '', 'pSrcHier', '', + 'pTgtDim', '', 'pTgtHier', '', + 'pAttr', 0, 'pUnwind', 0, 'pIfNthanC', 0, 'pSrcFilter', '' + ); +EndIf; +#EndRegion CallThisProcess + +#****Begin: Generated Statements*** +#****End: Generated Statements**** + +################################################################################################# +##~~Join the bedrock TM1 community on GitHub https://github.com/cubewise-code/bedrock Ver 4.0~~## +################################################################################################# + +#Region @DOC +# Description: +# This process will clone the source dimension Hierarchy. + +# Use case: Mostly in Development. +# 1/ Create a duplicate of an existing hierarchy for testing. + +# Note: +# Valid source dimension name (pSrcDim) and target dimension (pTgtDim) names are mandatory otherwise the process will abort. +# Valid source hierarchy name (pSrcHier) is mandatory otherwise the process will abort. + +# Caution: +# - Target hierarchy cannot be `Leaves`. +# - If the target dimension Hierarchy exists then it will be overwritten. +#EndRegion @DOC + +### Global Varaibales ### +StringGlobalVariable ('sProcessReturnCode'); +NumericGlobalVariable('nProcessReturnCode'); +nProcessReturnCode = 0; + +### Constants ### +cThisProcName = GetProcessName(); +cUserName = TM1User(); +cTimeStamp = TimSt( Now, '\Y\m\d\h\i\s' ); +cRandomInt = NumberToString( INT( RAND( ) * 1000 )); +cTempSub = cThisProcName |'_'| cTimeStamp |'_'| cRandomInt; +cMsgErrorLevel = 'ERROR'; +cMsgErrorContent = '%cThisProcName% : %sMessage% : %cUserName%'; +cLogInfo = 'Process:%cThisProcName% run with parameters pSrcDim:%pSrcDim%, pSrcHier:%pSrcHier%, pTgtDim:%pTgtDim%, pTgtHier:%pTgtHier%, pAttr:%pAttr%, pUnwind:%pUnwind%, pIfNthanC:%pIfNthanC%, pSrcFilter:%pSrcFilter%.'; +cLangDim = '}Cultures'; +nNumLang = DimSiz( cLangDim ); + +nProcessSameNamedHier = 0; +sEpilogTgtHier = ''; +nTempSubsetCreated = 0; +sTempSubset = ''; +sFilterPrefix = ''; +sFilterValue = ''; + +## LogOutput parameters +IF ( pLogoutput = 1 ); + LogOutput('INFO', Expand( cLogInfo ) ); +ENDIF; + +### Validate Parameters ### +nErrors = 0; + +If( Scan( ':', pSrcDim ) > 0 & pSrcHier @= '' ); + # A hierarchy has been passed as dimension. Handle the input error by splitting dim:hier into dimension & hierarchy + pSrcHier = SubSt( pSrcDim, Scan( ':', pSrcDim ) + 1, Long( pSrcDim ) ); + pSrcDim = SubSt( pSrcDim, 1, Scan( ':', pSrcDim ) - 1 ); +EndIf; + +## Validate Source dimension +IF( Trim( pSrcDim ) @= '' ); + nErrors = 1; + sMessage = 'No source dimension specified.'; + LogOutput( cMsgErrorLevel, Expand( cMsgErrorContent ) ); +EndIf; + +IF( DimensionExists( pSrcDim ) = 0 ); + nErrors = 1; + sMessage = 'Invalid source dimension: ' | pSrcDim; + LogOutput( cMsgErrorLevel, Expand( cMsgErrorContent ) ); +EndIf; + +# Validate Source hierarchy +IF( Trim( pSrcHier ) @= '' ); + pSrcHier = pSrcDim; +ElseIF(HierarchyExists(pSrcDim,pSrcHier ) = 0 ); + nErrors = 1; + sMessage = 'Invalid source hierarchy: ' | pSrcHier; + LogOutput( cMsgErrorLevel, Expand( cMsgErrorContent ) ); +EndIf; + +# Validate Target dimension +IF( Trim( pTgtDim ) @= '' ); + nErrors = 1; + sMessage = 'No target dimension specified.'; + LogOutput( cMsgErrorLevel, Expand( cMsgErrorContent ) ); +ElseIf( Scan( ':', pTgtDim ) > 0 & pTgtHier @= '' ); + # A hierarchy has been passed as dimension. Handle the input error by splitting dim:hier into dimension & hierarchy + pTgtHier = SubSt( pTgtDim, Scan( ':', pTgtDim ) + 1, Long( pTgtDim ) ); + pTgtDim = SubSt( pTgtDim, 1, Scan( ':', pTgtDim ) - 1 ); +EndIf; + +If ( DimensionExists( pTgtDim ) = 0 ); + DimensionCreate( pTgtDim ); + ### In this case clone source hierarchy into same-named hierarchy of the new target dimension first. This will allow attributes to be processed in the data tab. + nProcessSameNamedHier = 1; +EndIf; + +# Validate target hierarchy +If( pSrcDim @= pTgtDim); + If( pTgtHier @= '' % pTgtHier @= pSrcHier ); + pTgtHier = pSrcHier | '_Clone'; + EndIf; +ElseIf(pTgtHier @= ''); + If( nProcessSameNamedHier = 1 ); + sEpilogTgtHier = pTgtHier; + pTgtHier = pTgtDim; + Else; + pTgtHier = pSrcHier; + EndIf; +ElseIf( nProcessSameNamedHier = 1 ); + sEpilogTgtHier = pTgtHier; + pTgtHier = pTgtDim; +Endif; + +pTgtHier = Trim(pTgtHier); + +IF(pTgtHier @= 'Leaves' ); + nErrors = 1; + sMessage = 'Leaves is an invalid selection for Target Hierarchy: ' | pTgtDim |':'|pTgtHier; + LogOutput( cMsgErrorLevel, Expand( cMsgErrorContent ) ); +EndIf; + +If( DimensionExists( pTgtDim ) = 0 ); + If( pUnwind >= 1 ); + pUnwind = 2; + EndIf; +ElseIf( HierarchyExists( pTgtDim, pTgtHier ) = 0 ); + If( pUnwind >= 1 ); + pUnwind = 2; + EndIf; +EndIf; + +### Check for errors before continuing +If( nErrors <> 0 ); + If( pStrictErrorHandling = 1 ); + ProcessQuit; + Else; + ProcessBreak; + EndIf; +EndIf; + +### Resolve pSrcFilter ### +If( Trim( pSrcFilter ) @<> '' ); + If( SubSt( pSrcFilter, 1, 7 ) @= 'Subset:' ); + sFilterPrefix = 'Subset'; + sFilterValue = Trim( SubSt( pSrcFilter, 8, Long( pSrcFilter ) ) ); + ElseIf( SubSt( pSrcFilter, 1, 4 ) @= 'MDX:' ); + sFilterPrefix = 'MDX'; + sFilterValue = Trim( SubSt( pSrcFilter, 5, Long( pSrcFilter ) ) ); + Else; + nErrors = 1; + sMessage = 'Invalid pSrcFilter prefix. Use \"Subset:\" or \"MDX:\".'; + LogOutput( cMsgErrorLevel, Expand( cMsgErrorContent ) ); + EndIf; +EndIf; + +If( sFilterPrefix @= 'Subset' ); + If( SubsetExists( pSrcDim, sFilterValue ) = 0 ); + nErrors = 1; + sMessage = 'Subset not found: ' | sFilterValue | ' on dimension ' | pSrcDim; + LogOutput( cMsgErrorLevel, Expand( cMsgErrorContent ) ); + Else; + sTempSubset = sFilterValue; + EndIf; +ElseIf( sFilterPrefix @= 'MDX' ); + sTempSubset = cTempSub; + nRet = ExecuteProcess( '}bedrock.hier.sub.create.bymdx', + 'pLogOutput', pLogOutput, + 'pStrictErrorHandling', pStrictErrorHandling, + 'pDim', pSrcDim, + 'pHier', pSrcHier, + 'pSub', sTempSubset, + 'pMDXExpr', sFilterValue, + 'pConvertToStatic', 1, + 'pTemp', 1 + ); + If( nRet = 0 ); + nTempSubsetCreated = 1; + Else; + nErrors = 1; + sMessage = 'Failed to create MDX subset. Check MDX expression: ' | sFilterValue; + LogOutput( cMsgErrorLevel, Expand( cMsgErrorContent ) ); + EndIf; +Else; + sTempSubset = 'ALL'; +EndIf; + +If( nErrors <> 0 ); + If( pStrictErrorHandling = 1 ); + ProcessQuit; + Else; + ProcessBreak; + EndIf; +EndIf; + +### Create target dimension Hierarchy ### +If( HierarchyExists( pTgtDim, pTgtHier) = 0 ); + HierarchyCreate( pTgtDim, pTgtHier ); +Else; + IF(pUnwind = 1 ); + nRet = ExecuteProcess('}bedrock.hier.unwind', + 'pLogOutput', pLogOutput, + 'pStrictErrorHandling', pStrictErrorHandling, + 'pDim', pTgtDim, + 'pHier', pTgtHier, + 'pConsol', '*', + 'pRecursive', 1 + ); + ELSEIF(pUnwind = 2 ); + #Do nothing + ELSEIF(pUnwind = 0 ); + HierarchyDeleteAllElements( pTgtDim, pTgtHier ); + EndIf; +EndIf; + +If(pSrcDim @=pSrcHier); + sDimHier = pSrcDim; + Else; + sDimHier =pSrcDim|':'|pSrcHier; + Endif; + +### Set the target Sort Order ### +sSortElementsType = CELLGETS( '}DimensionProperties', sDimHier, 'SORTELEMENTSTYPE'); +sSortElementsSense = CELLGETS( '}DimensionProperties', sDimHier, 'SORTELEMENTSSENSE'); +sSortComponentsType = CELLGETS( '}DimensionProperties', sDimHier, 'SORTCOMPONENTSTYPE'); +sSortComponentsSense = CELLGETS( '}DimensionProperties', sDimHier, 'SORTCOMPONENTSSENSE'); + +HierarchySortOrder(pTgtDim, pTgtHier, sSortComponentsType, sSortComponentsSense, sSortElementsType , sSortElementsSense); + +nSourceHierSize = SubsetGetSize( pSrcDim, sTempSubset ); + +nIndex = 1; +WHILE( nIndex <= nSourceHierSize ); + sElName = SubsetGetElementName( pSrcDim, sTempSubset, nIndex ); + sElType = ElementType( pSrcDim, pSrcHier, sElName ); + + if( sElType @<> 'S' & pIfNthanC = 1 ); + HierarchyElementInsert( pTgtDim, pTgtHier, '', sElName, 'C' ); + else; + HierarchyElementInsert( pTgtDim, pTgtHier, '', sElName, sElType ); + endif; + nIndex = nIndex + 1; +END; + +### Assign Data Source ### + +DatasourceNameForServer = pSrcDim|':'|pSrcHier; +DataSourceType = 'SUBSET'; +DatasourceDimensionSubset = sTempSubset; + +### Replicate Attributes ### + +# Note: DType on Attr dim returns "AS", "AN" or "AA" need to strip off leading "A" + +sAttrDim = '}ElementAttributes_' | pSrcDim; +sAttrLoc = '}LocalizedElementAttributes_' | pSrcDim; +sAttrTragetDim = '}ElementAttributes_' | pTgtDim; +sAttrLocTarget = '}LocalizedElementAttributes_' | pTgtDim; + +If( pAttr = 1 & DimensionExists( sAttrDim ) = 1 ); + nNumAttrs = DimSiz( sAttrDim ); + nCount = 1; + While( nCount <= nNumAttrs ); + sAttrName = DimNm( sAttrDim, nCount ); + sAttrType = SubSt(DType( sAttrDim, sAttrName ), 2, 1 ); + If ( DimensionExists( sAttrTragetDim ) = 0); + AttrInsert(pTgtDim,'',sAttrName,sAttrType ); + ElseIF(DimIx(sAttrTragetDim, sAttrName) = 0); + AttrInsert(pTgtDim,'',sAttrName,sAttrType ); + Endif; + nCount = nCount + 1; + End; +Elseif(pAttr > 1 & DimensionExists( sAttrDim ) = 1 ); + nNumAttrs = DimSiz( sAttrTragetDim ); +EndIf; + +### End Prolog ### +573,38 + +#****Begin: Generated Statements*** +#****End: Generated Statements**** + +################################################################################################# +##~~Join the bedrock TM1 community on GitHub https://github.com/cubewise-code/bedrock Ver 4.0.0~~## +################################################################################################# + + +### Check for errors in prolog ### + +If( nErrors <> 0 ); + If( pStrictErrorHandling = 1 ); + ProcessQuit; + Else; + ProcessBreak; + EndIf; +EndIf; + +### Add Elements to target dimension ### + +sElType = ElementType(pSrcDim, pSrcHier, vEle); + + +IF( sElType @= 'C' & ElementComponentCount( pSrcDim, pSrcHier, vEle ) > 0 ); + nChildren = ElementComponentCount( pSrcDim, pSrcHier, vEle ); + nCount = 1; + While( nCount <= nChildren ); + sChildElement = ElementComponent( pSrcDim, pSrcHier, vEle, nCount ); + sChildWeight = ElementWeight( pSrcDim, pSrcHier, vEle, sChildElement ); + If( HierarchyElementExists( pTgtDim, pTgtHier, sChildElement ) = 1 ); + HierarchyElementComponentAdd( pTgtDim, pTgtHier, vEle, sChildElement, sChildWeight ); + EndIf; + nCount = nCount + 1; + End; +EndIf; + +### End MetaData ### +574,97 + +#****Begin: Generated Statements*** +#****End: Generated Statements**** + +################################################################################################# +##~~Join the bedrock TM1 community on GitHub https://github.com/cubewise-code/bedrock Ver 4.0.0~~## +################################################################################################# + + +### Check for errors in prolog ### + +If( nErrors <> 0 ); + If( pStrictErrorHandling = 1 ); + ProcessQuit; + Else; + ProcessBreak; + EndIf; +EndIf; + +### Replicate Attributes ### +# Note: DTYPE on Attr dim returns "AS", "AN" or "AA" need to strip off leading "A" + + +If( pAttr >= 1 & DimensionExists( sAttrTragetDim ) = 1 ); + + nAttr = 1; + While( nAttr <= nNumAttrs ); + sAttrName = DimNm( sAttrTragetDim, nAttr ); + sAttrType = SubSt( DTYPE( sAttrTragetDim, sAttrName ), 2, 1 ); + + if(pAttr > 1 & (DIMIX(sAttrTragetDim, sAttrName) = 0 % DIMIX(sAttrDim, sAttrName) = 0)); + #Do nothing, only existing attributes will be copied in this case + else; + + If( sAttrType @= 'S' % sAttrType @= 'A' ); + sAttrVal = ElementAttrS( pSrcDim, pSrcHier, vEle, sAttrName ); + + If( sAttrVal @<> '' ); + If( CellIsUpdateable( '}ElementAttributes_' | pTgtDim, pTgtHier:vEle, sAttrName ) = 1 ); + If( sAttrType @= 'A' ); + ElementAttrPutS( sAttrVal, pTgtDim, pTgtHier, vEle, sAttrName, 1 ); + Else; + ElementAttrPutS( sAttrVal, pTgtDim, pTgtHier, vEle, sAttrName ); + EndIf; + EndIf; + EndIf; + Else; + nAttrVal = ElementAttrN( pSrcDim, pSrcHier, vEle, sAttrName ); + If( nAttrVal <> 0 ); + If( CellIsUpdateable( '}ElementAttributes_' | pTgtDim, pTgtHier:vEle, sAttrName ) = 1 ); + ElementAttrPutN( nAttrVal, pTgtDim, pTgtHier, vEle, sAttrName ); + EndIf; + EndIf; + EndIf; + # check for localized attributes + If( CubeExists( sAttrLoc ) = 1 ); + + nLang = 1; + While( nLang <= nNumLang ); + sLang = DimNm( cLangDim, nLang ); + If( sAttrType @= 'A' % sAttrType @= 'S' ); + sAttrVal = ElementAttrS( pSrcDim, pSrcHier, vEle, sAttrName ); + sAttrValLoc = ElementAttrSL( pSrcDim, pSrcHier, vEle, sAttrName, sLang ); + If( sAttrValLoc @= sAttrVal ); sAttrValLoc = ''; EndIf; + Else; + nAttrVal = ElementAttrN( pSrcDim, pSrcHier, vEle, sAttrName ); + nAttrValLoc = ElementAttrNL( pSrcDim, pSrcHier, vEle, sAttrName, sLang ); + EndIf; + If( CubeExists( sAttrLocTarget ) = 0 ); + If( sAttrType @= 'A' ); + ElementAttrPutS( sAttrValLoc, pTgtDim, pTgtHier, vEle, sAttrName, sLang, 1 ); + ElseIf( sAttrType @= 'N' ); + ElementAttrPutN( nAttrValLoc, pTgtDim, pTgtHier, vEle, sAttrName, sLang ); + Else; + ElementAttrPutS( sAttrValLoc, pTgtDim, pTgtHier, vEle, sAttrName, sLang ); + EndIf; + ElseIf(CubeExists( sAttrLocTarget ) = 1 ); + If( CellIsUpdateable( sAttrLocTarget, pTgtHier:vEle, sLang, sAttrName ) = 1 ); + If( sAttrType @= 'A' ); + ElementAttrPutS( sAttrValLoc, pTgtDim, pTgtHier, vEle, sAttrName, sLang, 1 ); + ElseIf( sAttrType @= 'N' ); + ElementAttrPutN( nAttrValLoc, pTgtDim, pTgtHier, vEle, sAttrName, sLang ); + Else; + ElementAttrPutS( sAttrValLoc, pTgtDim, pTgtHier, vEle, sAttrName, sLang ); + EndIf; + EndIf; + EndIf; + nLang = nLang + 1; + End; + EndIf; + endif; + nAttr = nAttr + 1; + End; + +EndIf; + +### End Data ### +575,62 + +#****Begin: Generated Statements*** +#****End: Generated Statements**** + +################################################################################################# +##~~Join the bedrock TM1 community on GitHub https://github.com/cubewise-code/bedrock Ver 4.0~~## +################################################################################################# + + +If(pTgtDim @=pTgtHier); + sTargetDimHier = pTgtDim; +Else; + sTargetDimHier =pTgtDim|':'|pTgtHier; +EndIf; + +### Set the target Sort Order ### + CELLPUTS( sSortElementsType, '}DimensionProperties', sTargetDimHier, 'SORTELEMENTSTYPE'); + CELLPUTS( sSortElementsSense, '}DimensionProperties', sTargetDimHier, 'SORTELEMENTSSENSE'); + CELLPUTS( sSortComponentsType, '}DimensionProperties',sTargetDimHier, 'SORTCOMPONENTSTYPE'); + CELLPUTS( sSortComponentsSense, '}DimensionProperties', sTargetDimHier, 'SORTCOMPONENTSSENSE'); + +### Clean up temporary subset ### +If( nTempSubsetCreated = 1 ); + SubsetDestroy( pSrcDim, sTempSubset ); + nTempSubsetCreated = 0; +EndIf; + +### If a new dimension has been created, call the process recursively to clone the alternate hierarchy, after the same named hierarchy has been processed +If( nProcessSameNamedHier = 1 ); + nRet = EXECUTEPROCESS(GetProcessName(), + 'pLogOutput', pLogOutput, + 'pStrictErrorHandling', pStrictErrorHandling, + 'pSrcDim', pSrcDim, + 'pSrcHier',pSrcHier, + 'pTgtDim', pTgtDim, + 'pTgtHier', sEpilogTgtHier, + 'pAttr', pAttr, + 'pUnwind', pUnwind, + 'pIfNthanC', pIfNthanC, + 'pSrcFilter', pSrcFilter + ); +EndIf; + +### Return code & final error message handling +If( nErrors > 0 ); + sMessage = 'the process incurred at least 1 error. Please see above lines in this file for more details.'; + nProcessReturnCode = 0; + LogOutput( cMsgErrorLevel, Expand( cMsgErrorContent ) ); + sProcessReturnCode = Expand( '%sProcessReturnCode% Process:%cThisProcName% completed with errors. Check tm1server.log for details.' ); + If( pStrictErrorHandling = 1 ); + ProcessQuit; + EndIf; +Else; + sProcessAction = Expand( 'Process:%cThisProcName% successfully cloned the %pSrcDim%:%pSrcHier% dimension:hierarchy to %pTgtDim%:%pTgtHier%' ); + sProcessReturnCode = Expand( '%sProcessReturnCode% %sProcessAction%' ); + nProcessReturnCode = 1; + If( pLogoutput = 1 ); + LogOutput('INFO', Expand( sProcessAction ) ); + EndIf; +EndIf; + +### End Epilog ### +576,CubeAction=1511 DataAction=1503 CubeLogChanges=0 +930,0 +638,1 +804,0 +1217,1 +900, +901, +902, +938,0 +937, +936, +935, +934, +932,0 +933,0 +903, +906, +929, +907, +908, +904,0 +905,0 +909,0 +911, +912, +913, +914, +915, +916, +917,0 +918,1 +919,0 +920,50000 +921,"" +922,"" +923,0 +924,"" +925,"" +926,"" +927,"" diff --git a/main_asJSON/}bedrock.hier.clone.json b/main_asJSON/}bedrock.hier.clone.json new file mode 100644 index 0000000..5c91f01 --- /dev/null +++ b/main_asJSON/}bedrock.hier.clone.json @@ -0,0 +1,89 @@ +{ + "Name": "}bedrock.hier.clone.LS", + "PrologProcedure": "#Region CallThisProcess\r\n# A snippet of code provided as an example how to call this process should the developer be working on a system without access to an editor with auto-complete.\r\nIf( 1 = 0 );\r\n ExecuteProcess( '}bedrock.hier.clone', 'pLogOutput', pLogOutput,\r\n 'pStrictErrorHandling', pStrictErrorHandling,\r\n \t'pSrcDim', '', 'pSrcHier', '',\r\n \t'pTgtDim', '', 'pTgtHier', '',\r\n \t'pAttr', 0, 'pUnwind', 0, 'pIfNthanC', 0, 'pSrcFilter', ''\r\n\t);\r\nEndIf;\r\n#EndRegion CallThisProcess\r\n\r\n#****Begin: Generated Statements***\r\n#****End: Generated Statements****\r\n\r\n################################################################################################# \r\n##~~Join the bedrock TM1 community on GitHub https://github.com/cubewise-code/bedrock Ver 4.0~~##\r\n################################################################################################# \r\n\r\n#Region @DOC\r\n# Description:\r\n# This process will clone the source dimension Hierarchy.\r\n\r\n# Use case: Mostly in Development.\r\n# 1/ Create a duplicate of an existing hierarchy for testing.\r\n\r\n# Note:\r\n# Valid source dimension name (pSrcDim) and target dimension (pTgtDim) names are mandatory otherwise the process will abort.\r\n# Valid source hierarchy name (pSrcHier) is mandatory otherwise the process will abort.\r\n\r\n# Caution:\r\n# - Target hierarchy cannot be `Leaves`.\r\n# - If the target dimension Hierarchy exists then it will be overwritten.\r\n#EndRegion @DOC\r\n\r\n### Global Varaibales ###\r\nStringGlobalVariable ('sProcessReturnCode');\r\nNumericGlobalVariable('nProcessReturnCode');\r\nnProcessReturnCode = 0;\r\n\r\n### Constants ###\r\ncThisProcName = GetProcessName();\r\ncUserName = TM1User();\r\ncTimeStamp = TimSt( Now, '\\Y\\m\\d\\h\\i\\s' );\r\ncRandomInt = NumberToString( INT( RAND( ) * 1000 ));\r\ncTempSub = cThisProcName |'_'| cTimeStamp |'_'| cRandomInt;\r\ncMsgErrorLevel = 'ERROR';\r\ncMsgErrorContent = '%cThisProcName% : %sMessage% : %cUserName%';\r\ncLogInfo = 'Process:%cThisProcName% run with parameters pSrcDim:%pSrcDim%, pSrcHier:%pSrcHier%, pTgtDim:%pTgtDim%, pTgtHier:%pTgtHier%, pAttr:%pAttr%, pUnwind:%pUnwind%, pIfNthanC:%pIfNthanC%, pSrcFilter:%pSrcFilter%.';\r\ncLangDim = '}Cultures';\r\nnNumLang = DimSiz( cLangDim );\r\n\r\nnProcessSameNamedHier = 0;\r\nsEpilogTgtHier = '';\r\nnTempSubsetCreated = 0;\r\nsTempSubset = '';\r\nsFilterPrefix = '';\r\nsFilterValue = '';\r\n\r\n## LogOutput parameters\r\nIF ( pLogoutput = 1 );\r\n LogOutput('INFO', Expand( cLogInfo ) ); \r\nENDIF;\r\n\r\n### Validate Parameters ###\r\nnErrors = 0;\r\n\r\nIf( Scan( ':', pSrcDim ) > 0 & pSrcHier @= '' );\r\n # A hierarchy has been passed as dimension. Handle the input error by splitting dim:hier into dimension & hierarchy\r\n pSrcHier = SubSt( pSrcDim, Scan( ':', pSrcDim ) + 1, Long( pSrcDim ) );\r\n pSrcDim = SubSt( pSrcDim, 1, Scan( ':', pSrcDim ) - 1 );\r\nEndIf;\r\n\r\n## Validate Source dimension\r\nIF( Trim( pSrcDim ) @= '' );\r\n nErrors = 1;\r\n sMessage = 'No source dimension specified.';\r\n LogOutput( cMsgErrorLevel, Expand( cMsgErrorContent ) );\r\nEndIf;\r\n\r\nIF( DimensionExists( pSrcDim ) = 0 );\r\n nErrors = 1;\r\n sMessage = 'Invalid source dimension: ' | pSrcDim;\r\n LogOutput( cMsgErrorLevel, Expand( cMsgErrorContent ) );\r\nEndIf;\r\n\r\n# Validate Source hierarchy\r\nIF( Trim( pSrcHier ) @= '' );\r\n pSrcHier = pSrcDim;\r\nElseIF(HierarchyExists(pSrcDim,pSrcHier ) = 0 );\r\n nErrors = 1;\r\n sMessage = 'Invalid source hierarchy: ' | pSrcHier;\r\n LogOutput( cMsgErrorLevel, Expand( cMsgErrorContent ) );\r\nEndIf;\r\n\r\n# Validate Target dimension\r\nIF( Trim( pTgtDim ) @= '' );\r\n nErrors = 1;\r\n sMessage = 'No target dimension specified.';\r\n LogOutput( cMsgErrorLevel, Expand( cMsgErrorContent ) );\r\nElseIf( Scan( ':', pTgtDim ) > 0 & pTgtHier @= '' );\r\n # A hierarchy has been passed as dimension. Handle the input error by splitting dim:hier into dimension & hierarchy\r\n pTgtHier = SubSt( pTgtDim, Scan( ':', pTgtDim ) + 1, Long( pTgtDim ) );\r\n pTgtDim = SubSt( pTgtDim, 1, Scan( ':', pTgtDim ) - 1 );\r\nEndIf;\r\n\r\nIf ( DimensionExists( pTgtDim ) = 0 );\r\n DimensionCreate( pTgtDim );\r\n ### In this case clone source hierarchy into same-named hierarchy of the new target dimension first. This will allow attributes to be processed in the data tab.\r\n nProcessSameNamedHier = 1;\r\nEndIf;\r\n\r\n# Validate target hierarchy\r\nIf( pSrcDim @= pTgtDim);\r\n If( pTgtHier @= '' % pTgtHier @= pSrcHier );\r\n pTgtHier = pSrcHier | '_Clone';\r\n EndIf;\r\nElseIf(pTgtHier @= '');\r\n If( nProcessSameNamedHier = 1 );\r\n sEpilogTgtHier = pTgtHier;\r\n pTgtHier = pTgtDim;\r\n Else;\r\n pTgtHier = pSrcHier;\r\n EndIf;\r\nElseIf( nProcessSameNamedHier = 1 );\r\n sEpilogTgtHier = pTgtHier;\r\n pTgtHier = pTgtDim;\r\nEndif;\r\n\r\npTgtHier = Trim(pTgtHier);\r\n\r\nIF(pTgtHier @= 'Leaves' );\r\n nErrors = 1;\r\n sMessage = 'Leaves is an invalid selection for Target Hierarchy: ' | pTgtDim |':'|pTgtHier;\r\n LogOutput( cMsgErrorLevel, Expand( cMsgErrorContent ) );\r\nEndIf;\r\n\r\nIf( DimensionExists( pTgtDim ) = 0 );\r\n If( pUnwind >= 1 );\r\n pUnwind = 2;\r\n EndIf;\r\nElseIf( HierarchyExists( pTgtDim, pTgtHier ) = 0 );\r\n If( pUnwind >= 1 );\r\n pUnwind = 2;\r\n EndIf;\r\nEndIf; \r\n\r\n### Check for errors before continuing\r\nIf( nErrors <> 0 );\r\n If( pStrictErrorHandling = 1 ); \r\n ProcessQuit; \r\n Else;\r\n ProcessBreak;\r\n EndIf;\r\nEndIf;\r\n\r\n### Resolve pSrcFilter ###\r\nIf( Trim( pSrcFilter ) @<> '' );\r\n If( SubSt( pSrcFilter, 1, 7 ) @= 'Subset:' );\r\n sFilterPrefix = 'Subset';\r\n sFilterValue = Trim( SubSt( pSrcFilter, 8, Long( pSrcFilter ) ) );\r\n ElseIf( SubSt( pSrcFilter, 1, 4 ) @= 'MDX:' );\r\n sFilterPrefix = 'MDX';\r\n sFilterValue = Trim( SubSt( pSrcFilter, 5, Long( pSrcFilter ) ) );\r\n Else;\r\n nErrors = 1;\r\n sMessage = 'Invalid pSrcFilter prefix. Use \\\"Subset:\\\" or \\\"MDX:\\\".';\r\n LogOutput( cMsgErrorLevel, Expand( cMsgErrorContent ) );\r\n EndIf;\r\nEndIf;\r\n\r\nIf( sFilterPrefix @= 'Subset' );\r\n If( SubsetExists( pSrcDim, sFilterValue ) = 0 );\r\n nErrors = 1;\r\n sMessage = 'Subset not found: ' | sFilterValue | ' on dimension ' | pSrcDim;\r\n LogOutput( cMsgErrorLevel, Expand( cMsgErrorContent ) );\r\n Else;\r\n sTempSubset = sFilterValue;\r\n EndIf;\r\nElseIf( sFilterPrefix @= 'MDX' );\r\n sTempSubset = cTempSub;\r\n nRet = ExecuteProcess( '}bedrock.hier.sub.create.bymdx',\r\n 'pLogOutput', pLogOutput,\r\n 'pStrictErrorHandling', pStrictErrorHandling,\r\n 'pDim', pSrcDim,\r\n 'pHier', pSrcHier,\r\n 'pSub', sTempSubset,\r\n 'pMDXExpr', sFilterValue,\r\n 'pConvertToStatic', 1,\r\n 'pTemp', 1\r\n );\r\n If( nRet = 0 );\r\n nTempSubsetCreated = 1;\r\n Else;\r\n nErrors = 1;\r\n sMessage = 'Failed to create MDX subset. Check MDX expression: ' | sFilterValue;\r\n LogOutput( cMsgErrorLevel, Expand( cMsgErrorContent ) );\r\n EndIf;\r\nElse;\r\n sTempSubset = 'ALL';\r\nEndIf;\r\n\r\nIf( nErrors <> 0 );\r\n If( pStrictErrorHandling = 1 );\r\n ProcessQuit;\r\n Else;\r\n ProcessBreak;\r\n EndIf;\r\nEndIf;\r\n\r\n### Create target dimension Hierarchy ###\r\nIf( HierarchyExists( pTgtDim, pTgtHier) = 0 );\r\n HierarchyCreate( pTgtDim, pTgtHier );\r\nElse;\r\n IF(pUnwind = 1 );\r\n nRet = ExecuteProcess('}bedrock.hier.unwind',\r\n 'pLogOutput', pLogOutput,\r\n 'pStrictErrorHandling', pStrictErrorHandling,\r\n 'pDim', pTgtDim,\r\n 'pHier', pTgtHier,\r\n 'pConsol', '*',\r\n 'pRecursive', 1\r\n );\r\n ELSEIF(pUnwind = 2 );\r\n #Do nothing\r\n ELSEIF(pUnwind = 0 );\r\n HierarchyDeleteAllElements( pTgtDim, pTgtHier );\r\n EndIf;\r\nEndIf;\r\n \r\nIf(pSrcDim @=pSrcHier);\r\n sDimHier = pSrcDim;\r\n Else;\r\n sDimHier =pSrcDim|':'|pSrcHier;\r\n Endif;\r\n \r\n### Set the target Sort Order ###\r\nsSortElementsType = CELLGETS( '}DimensionProperties', sDimHier, 'SORTELEMENTSTYPE');\r\nsSortElementsSense = CELLGETS( '}DimensionProperties', sDimHier, 'SORTELEMENTSSENSE');\r\nsSortComponentsType = CELLGETS( '}DimensionProperties', sDimHier, 'SORTCOMPONENTSTYPE');\r\nsSortComponentsSense = CELLGETS( '}DimensionProperties', sDimHier, 'SORTCOMPONENTSSENSE');\r\n\r\nHierarchySortOrder(pTgtDim, pTgtHier, sSortComponentsType, sSortComponentsSense, sSortElementsType , sSortElementsSense);\r\n\r\nnSourceHierSize = SubsetGetSize( pSrcDim, sTempSubset );\r\n\r\nnIndex = 1;\r\nWHILE( nIndex <= nSourceHierSize );\r\n sElName = SubsetGetElementName( pSrcDim, sTempSubset, nIndex );\r\n sElType = ElementType( pSrcDim, pSrcHier, sElName );\r\n \r\n if( sElType @<> 'S' & pIfNthanC = 1 );\r\n\tHierarchyElementInsert( pTgtDim, pTgtHier, '', sElName, 'C' );\r\n else;\r\n\tHierarchyElementInsert( pTgtDim, pTgtHier, '', sElName, sElType );\r\n endif;\r\n nIndex = nIndex + 1;\r\nEND;\r\n\r\n### Assign Data Source ###\r\n\r\nDatasourceNameForServer = pSrcDim|':'|pSrcHier;\r\nDataSourceType = 'SUBSET';\r\nDatasourceDimensionSubset = sTempSubset;\r\n\r\n### Replicate Attributes ###\r\n\r\n# Note: DType on Attr dim returns \"AS\", \"AN\" or \"AA\" need to strip off leading \"A\"\r\n\r\nsAttrDim = '}ElementAttributes_' | pSrcDim;\r\nsAttrLoc = '}LocalizedElementAttributes_' | pSrcDim;\r\nsAttrTragetDim = '}ElementAttributes_' | pTgtDim;\r\nsAttrLocTarget = '}LocalizedElementAttributes_' | pTgtDim;\r\n\r\nIf( pAttr = 1 & DimensionExists( sAttrDim ) = 1 );\r\n nNumAttrs = DimSiz( sAttrDim );\r\n nCount = 1;\r\n While( nCount <= nNumAttrs );\r\n sAttrName = DimNm( sAttrDim, nCount );\r\n sAttrType = SubSt(DType( sAttrDim, sAttrName ), 2, 1 );\r\n If ( DimensionExists( sAttrTragetDim ) = 0);\r\n AttrInsert(pTgtDim,'',sAttrName,sAttrType );\r\n ElseIF(DimIx(sAttrTragetDim, sAttrName) = 0);\r\n AttrInsert(pTgtDim,'',sAttrName,sAttrType );\r\n Endif;\r\n nCount = nCount + 1;\r\n End;\r\nElseif(pAttr > 1 & DimensionExists( sAttrDim ) = 1 );\r\n nNumAttrs = DimSiz( sAttrTragetDim );\r\nEndIf;\r\n\r\n### End Prolog ###", + "MetadataProcedure": "\r\n#****Begin: Generated Statements***\r\n#****End: Generated Statements****\r\n\r\n################################################################################################# \r\n##~~Join the bedrock TM1 community on GitHub https://github.com/cubewise-code/bedrock Ver 4.0.0~~##\r\n################################################################################################# \r\n\r\n\r\n### Check for errors in prolog ###\r\n\r\nIf( nErrors <> 0 );\r\n If( pStrictErrorHandling = 1 ); \r\n ProcessQuit; \r\n Else;\r\n ProcessBreak;\r\n EndIf;\r\nEndIf;\r\n\r\n### Add Elements to target dimension ###\r\n\r\nsElType = ElementType(pSrcDim, pSrcHier, vEle);\r\n\r\n\r\nIF( sElType @= 'C' & ElementComponentCount( pSrcDim, pSrcHier, vEle ) > 0 );\r\n nChildren = ElementComponentCount( pSrcDim, pSrcHier, vEle );\r\n nCount = 1;\r\n While( nCount <= nChildren );\r\n sChildElement = ElementComponent( pSrcDim, pSrcHier, vEle, nCount );\r\n sChildWeight = ElementWeight( pSrcDim, pSrcHier, vEle, sChildElement );\r\n If( SubsetGetIndex( pSrcDim, sTempSubset, sChildElement ) > 0 );\r\n HierarchyElementComponentAdd( pTgtDim, pTgtHier, vEle, sChildElement, sChildWeight );\r\n EndIf;\r\n nCount = nCount + 1;\r\n End;\r\nEndIf;\r\n\r\n### End MetaData ###", + "DataProcedure": "\r\n#****Begin: Generated Statements***\r\n#****End: Generated Statements****\r\n\r\n################################################################################################# \r\n##~~Join the bedrock TM1 community on GitHub https://github.com/cubewise-code/bedrock Ver 4.0.0~~##\r\n################################################################################################# \r\n\r\n\r\n### Check for errors in prolog ###\r\n\r\nIf( nErrors <> 0 );\r\n If( pStrictErrorHandling = 1 ); \r\n ProcessQuit; \r\n Else;\r\n ProcessBreak;\r\n EndIf;\r\nEndIf;\r\n\r\n### Replicate Attributes ###\r\n# Note: DTYPE on Attr dim returns \"AS\", \"AN\" or \"AA\" need to strip off leading \"A\"\r\n\r\n\r\nIf( pAttr >= 1 & DimensionExists( sAttrTragetDim ) = 1 );\r\n\r\n nAttr = 1;\r\n While( nAttr <= nNumAttrs );\r\n sAttrName = DimNm( sAttrTragetDim, nAttr );\r\n sAttrType = SubSt( DTYPE( sAttrTragetDim, sAttrName ), 2, 1 );\r\n \r\n\t\tif(pAttr > 1 & (DIMIX(sAttrTragetDim, sAttrName) = 0 % DIMIX(sAttrDim, sAttrName) = 0));\r\n\t\t\t#Do nothing, only existing attributes will be copied in this case\r\n\t\telse;\r\n\t\t\r\n\t\t\tIf( sAttrType @= 'S' % sAttrType @= 'A' );\r\n\t\t\t\tsAttrVal = ElementAttrS( pSrcDim, pSrcHier, vEle, sAttrName );\r\n\t\t\t\t\r\n\t\t\t\tIf( sAttrVal @<> '' );\r\n\t\t\t\t\tIf( CellIsUpdateable( '}ElementAttributes_' | pTgtDim, pTgtHier:vEle, sAttrName ) = 1 );\r\n\t\t\t\t\t\tIf( sAttrType @= 'A' );\r\n\t\t\t\t\t\t\tElementAttrPutS( sAttrVal, pTgtDim, pTgtHier, vEle, sAttrName, 1 );\r\n\t\t\t\t\t\tElse;\r\n\t\t\t\t\t\t\tElementAttrPutS( sAttrVal, pTgtDim, pTgtHier, vEle, sAttrName );\r\n\t\t\t\t\t\tEndIf;\r\n\t\t\t\t\tEndIf;\r\n\t\t\t\tEndIf;\r\n\t\t\tElse;\r\n\t\t\t\tnAttrVal = ElementAttrN( pSrcDim, pSrcHier, vEle, sAttrName );\r\n\t\t\t\tIf( nAttrVal <> 0 );\r\n\t\t\t\t\tIf( CellIsUpdateable( '}ElementAttributes_' | pTgtDim, pTgtHier:vEle, sAttrName ) = 1 );\r\n\t\t\t\t\t\tElementAttrPutN( nAttrVal, pTgtDim, pTgtHier, vEle, sAttrName );\r\n\t\t\t\t\tEndIf;\r\n\t\t\t\tEndIf; \r\n\t\t\tEndIf;\r\n\t\t\t# check for localized attributes\r\n\t\t\tIf( CubeExists( sAttrLoc ) = 1 );\r\n\t\t\t\r\n\t\t\t\tnLang = 1;\r\n\t\t\t\tWhile( nLang <= nNumLang );\r\n\t\t\t\t\tsLang = DimNm( cLangDim, nLang );\r\n\t\t\t\t\tIf( sAttrType @= 'A' % sAttrType @= 'S' );\r\n\t\t\t\t\t\tsAttrVal = ElementAttrS( pSrcDim, pSrcHier, vEle, sAttrName );\r\n\t\t\t\t\t\tsAttrValLoc = ElementAttrSL( pSrcDim, pSrcHier, vEle, sAttrName, sLang );\r\n\t\t\t\t\t\tIf( sAttrValLoc @= sAttrVal ); sAttrValLoc = ''; EndIf;\r\n\t\t\t\t\tElse;\r\n\t\t\t\t\t\tnAttrVal = ElementAttrN( pSrcDim, pSrcHier, vEle, sAttrName );\r\n\t\t\t\t\t\tnAttrValLoc = ElementAttrNL( pSrcDim, pSrcHier, vEle, sAttrName, sLang );\r\n\t\t\t\t\tEndIf;\r\n\t\t\t\t\tIf( CubeExists( sAttrLocTarget ) = 0 );\r\n\t\t\t\t\t\tIf( sAttrType @= 'A' );\r\n\t\t\t\t\t\t\tElementAttrPutS( sAttrValLoc, pTgtDim, pTgtHier, vEle, sAttrName, sLang, 1 );\r\n\t\t\t\t\t\tElseIf( sAttrType @= 'N' );\r\n\t\t\t\t\t\t\tElementAttrPutN( nAttrValLoc, pTgtDim, pTgtHier, vEle, sAttrName, sLang );\r\n\t\t\t\t\t\tElse;\r\n\t\t\t\t\t\t\tElementAttrPutS( sAttrValLoc, pTgtDim, pTgtHier, vEle, sAttrName, sLang );\r\n\t\t\t\t\t\tEndIf;\r\n\t\t\t\t\tElseIf(CubeExists( sAttrLocTarget ) = 1 );\r\n\t\t\t\t\t\tIf( CellIsUpdateable( sAttrLocTarget, pTgtHier:vEle, sLang, sAttrName ) = 1 );\r\n\t\t\t\t\t\t\tIf( sAttrType @= 'A' );\r\n\t\t\t\t\t\t\t\tElementAttrPutS( sAttrValLoc, pTgtDim, pTgtHier, vEle, sAttrName, sLang, 1 );\r\n\t\t\t\t\t\t\tElseIf( sAttrType @= 'N' );\r\n\t\t\t\t\t\t\t\tElementAttrPutN( nAttrValLoc, pTgtDim, pTgtHier, vEle, sAttrName, sLang );\r\n\t\t\t\t\t\t\tElse;\r\n\t\t\t\t\t\t\t\tElementAttrPutS( sAttrValLoc, pTgtDim, pTgtHier, vEle, sAttrName, sLang );\r\n\t\t\t\t\t\t\tEndIf;\r\n\t\t\t\t\t\tEndIf;\r\n\t\t\t\t\tEndIf;\r\n\t\t\t\t\tnLang = nLang + 1;\r\n\t\t\t\tEnd;\r\n\t\t\tEndIf;\r\n\t\tendif;\r\n nAttr = nAttr + 1;\r\n End;\r\n\r\nEndIf;\r\n\r\n### End Data ###", + "EpilogProcedure": "\r\n#****Begin: Generated Statements***\r\n#****End: Generated Statements****\r\n\r\n################################################################################################# \r\n##~~Join the bedrock TM1 community on GitHub https://github.com/cubewise-code/bedrock Ver 4.0~~##\r\n################################################################################################# \r\n\r\n\r\nIf(pTgtDim @=pTgtHier);\r\n sTargetDimHier = pTgtDim;\r\nElse;\r\n sTargetDimHier =pTgtDim|':'|pTgtHier;\r\nEndIf;\r\n\r\n### Set the target Sort Order ###\r\n CELLPUTS( sSortElementsType, '}DimensionProperties', sTargetDimHier, 'SORTELEMENTSTYPE');\r\n CELLPUTS( sSortElementsSense, '}DimensionProperties', sTargetDimHier, 'SORTELEMENTSSENSE');\r\n CELLPUTS( sSortComponentsType, '}DimensionProperties',sTargetDimHier, 'SORTCOMPONENTSTYPE');\r\n CELLPUTS( sSortComponentsSense, '}DimensionProperties', sTargetDimHier, 'SORTCOMPONENTSSENSE');\r\n\r\n### Clean up temporary subset ###\r\nIf( nTempSubsetCreated = 1 );\r\n SubsetDestroy( pSrcDim, sTempSubset );\r\n nTempSubsetCreated = 0;\r\nEndIf;\r\n \r\n### If a new dimension has been created, call the process recursively to clone the alternate hierarchy, after the same named hierarchy has been processed\r\nIf( nProcessSameNamedHier = 1 );\r\n nRet = EXECUTEPROCESS(GetProcessName(),\r\n 'pLogOutput', pLogOutput,\r\n 'pStrictErrorHandling', pStrictErrorHandling,\r\n 'pSrcDim', pSrcDim,\r\n 'pSrcHier',pSrcHier,\r\n 'pTgtDim', pTgtDim,\r\n 'pTgtHier', sEpilogTgtHier,\r\n 'pAttr', pAttr,\r\n 'pUnwind', pUnwind,\r\n 'pIfNthanC', pIfNthanC,\r\n 'pSrcFilter', pSrcFilter\r\n );\r\nEndIf;\r\n \r\n### Return code & final error message handling\r\nIf( nErrors > 0 );\r\n sMessage = 'the process incurred at least 1 error. Please see above lines in this file for more details.';\r\n nProcessReturnCode = 0;\r\n LogOutput( cMsgErrorLevel, Expand( cMsgErrorContent ) );\r\n sProcessReturnCode = Expand( '%sProcessReturnCode% Process:%cThisProcName% completed with errors. Check tm1server.log for details.' );\r\n If( pStrictErrorHandling = 1 ); \r\n ProcessQuit; \r\n EndIf;\r\nElse;\r\n sProcessAction = Expand( 'Process:%cThisProcName% successfully cloned the %pSrcDim%:%pSrcHier% dimension:hierarchy to %pTgtDim%:%pTgtHier%' );\r\n sProcessReturnCode = Expand( '%sProcessReturnCode% %sProcessAction%' );\r\n nProcessReturnCode = 1;\r\n If( pLogoutput = 1 );\r\n LogOutput('INFO', Expand( sProcessAction ) ); \r\n EndIf;\r\nEndIf;\r\n\r\n### End Epilog ###", + "HasSecurityAccess": true, + "UIData": "CubeAction=1511\fDataAction=1503\fCubeLogChanges=0\f", + "DataSource": { + "Type": "TM1DimensionSubset", + "dataSourceNameForClient": "}Cubes", + "dataSourceNameForServer": "}Cubes", + "subset": "All" + }, + "Parameters": [ + { + "Name": "pLogOutput", + "Prompt": "OPTIONAL: Write parameters and action summary to server message log (Boolean True = 1)", + "Value": 0, + "Type": "Numeric" + }, + { + "Name": "pStrictErrorHandling", + "Prompt": "OPTIONAL: On encountering any error, exit with major error status by ProcessQuit after writing to the server message log (Boolean True = 1)", + "Value": 0, + "Type": "Numeric" + }, + { + "Name": "pSrcDim", + "Prompt": "REQUIRED: Source Dimension", + "Value": "", + "Type": "String" + }, + { + "Name": "pSrcHier", + "Prompt": "REQUIRED: Source Hierarchy", + "Value": "", + "Type": "String" + }, + { + "Name": "pTgtDim", + "Prompt": "REQUIRED: Target Dimension (can be the same as source)", + "Value": "", + "Type": "String" + }, + { + "Name": "pTgtHier", + "Prompt": "OPTIONAL: Target Hierarchy (will default to SrcHier_Clone if the dimensions are the same)", + "Value": "", + "Type": "String" + }, + { + "Name": "pAttr", + "Prompt": "OPTIONAL: Include Attributes? (Boolean 1=True; 2 = only existing)", + "Value": 0, + "Type": "Numeric" + }, + { + "Name": "pUnwind", + "Prompt": "REQUIRED: Unwind? (0 = Delete all Elements, 1 = Unwind Existing Elements, 2 = Do not change Existing Elements (Only relevant if target hierarchy exists) )", + "Value": 0, + "Type": "Numeric" + }, + { + "Name": "pIfNthanC", + "Prompt": "OPTIONAL: if 1 than all N-elemens will be created as c-elements", + "Value": 0, + "Type": "Numeric" + }, + { + "Name": "pSrcFilter", + "Prompt": "OPTIONAL: Source filter. Use Subset: or MDX:", + "Value": "", + "Type": "String" + } + ], + "Variables": [ + { + "Name": "vEle", + "Type": "String", + "Position": 1, + "StartByte": 0, + "EndByte": 0 + } + ], + "VariablesUIData": [ + "VarType=32\fColType=827\f" + ] +} \ No newline at end of file diff --git a/wiki_content/wiki_bedrock.hier.clone.md b/wiki_content/wiki_bedrock.hier.clone.md new file mode 100644 index 0000000..1eb16c7 --- /dev/null +++ b/wiki_content/wiki_bedrock.hier.clone.md @@ -0,0 +1,182 @@ +# }bedrock.hier.clone + +## Overview + +This process clones a source dimension hierarchy into a target dimension hierarchy. It replicates the element structure, consolidation relationships, sort order, and optionally element attributes (including localized attributes). + +**Bedrock Version:** 4.0+ +**GitHub:** [cubewise-code/bedrock](https://github.com/cubewise-code/bedrock) + +--- + +## Use Cases + +- Create a duplicate of an existing hierarchy for testing or development purposes. +- Use an existing dimension as a **structural skeleton** for a new, more detailed dimension by converting all leaf (N) elements to consolidation (C) elements (`pIfNthanC = 1`). +- Clone a hierarchy into a new dimension while optionally replicating or selectively copying element attributes. +- Clone only a **filtered subset of elements** from a large hierarchy using a named subset or an MDX expression (`pSrcFilter`). + +--- + +## Parameters + +| Parameter | Type | Required | Default | Description | +|-----------------------|---------|----------|---------|-------------| +| `pLogOutput` | Numeric | Optional | `0` | Write parameters and action summary to the server message log. `1` = enabled. | +| `pStrictErrorHandling`| Numeric | Optional | `0` | On any error, exit with major error status via `ProcessQuit`. `1` = enabled. | +| `pSrcDim` | String | Required | `""` | Source dimension name. May be supplied as `Dim:Hier` – the process will split it automatically. | +| `pSrcHier` | String | Required | `""` | Source hierarchy name. Defaults to the dimension name if left empty. | +| `pTgtDim` | String | Required | `""` | Target dimension name. May be the same as the source. If the dimension does not exist it will be created. | +| `pTgtHier` | String | Optional | `""` | Target hierarchy name. Defaults to `_Clone` when source and target dimension are the same. | +| `pAttr` | Numeric | Optional | `0` | Attribute handling. `0` = no attributes; `1` = create missing attributes and copy all values; `2` = copy values only for attributes that already exist on both source and target. | +| `pUnwind` | Numeric | Required | `0` | How to handle an existing target hierarchy. `0` = delete all elements; `1` = unwind existing consolidations; `2` = leave existing structure untouched. | +| `pIfNthanC` | Numeric | Optional | `0` | If `1`, all Numeric (N) elements from the source are inserted as Consolidated (C) elements in the target. String (S) elements are always kept as-is. | +| `pSrcFilter` | String | Optional | `""` | Element filter. `Subset:` uses an existing named subset; `MDX:` creates a temporary static subset from the MDX expression. Empty = clone all elements. | + +--- + +## Behaviour + +### Source & Target Resolution + +- If `pSrcDim` is supplied in `Dim:Hier` format and `pSrcHier` is empty, the process automatically splits the value into dimension and hierarchy. +- The same auto-split logic applies to `pTgtDim`. +- If the target dimension does not exist it is created automatically. In this case the process first clones into the same-named hierarchy of the new dimension (to allow attributes to be processed in the Data tab), then calls itself recursively to create the requested alternate hierarchy. + +### Element Insertion (`pIfNthanC`) + +By default, element types are copied 1:1 from source to target. +When `pIfNthanC = 1`: + +- All **N-elements** (Numeric/Leaf) are inserted as **C-elements** (Consolidated) in the target hierarchy. +- **S-elements** (String) are always inserted as S-elements regardless of `pIfNthanC`. + +This is useful when cloning a dimension that will serve as the structural basis for a new, more detailed dimension: all elements are immediately available as consolidations that can receive child members without needing a separate conversion step. + +### Consolidation Relationships (Metadata tab) + +The process iterates over all C-elements in the source hierarchy and replicates their child–weight relationships to the target hierarchy via `HierarchyElementComponentAdd`. + +### Sort Order + +The sort order (`SORTELEMENTSTYPE`, `SORTELEMENTSSENSE`, `SORTCOMPONENTSTYPE`, `SORTCOMPONENTSSENSE`) is read from the source hierarchy's `}DimensionProperties` and applied to the target hierarchy in both the Prolog and Epilog. + +### Attribute Replication (`pAttr`) + +| `pAttr` | Behaviour | +|---------|-----------| +| `0` | No attributes are copied. | +| `1` | Missing attributes are created on the target dimension. All attribute values (String, Numeric, Alias) are copied from source to target elements. | +| `2` | No new attributes are created. Only attribute values for attributes that already exist on **both** source and target dimension are copied. Useful when the target has a curated attribute schema that must not be altered. | + +Localized attributes (`}LocalizedElementAttributes_*`) are replicated when the source localization cube exists. + +### Element Filter (`pSrcFilter`) + +When `pSrcFilter` is supplied, only the elements resolved by the filter are cloned. Both the element insertion loop (Prolog) and the consolidation relationship loop (Metadata) are restricted to the working subset. + +| Prefix | Behaviour | +|--------|-----------| +| *(empty)* | No filter – full hierarchy is cloned (`ALL` subset). | +| `Subset:` | Uses the named subset on `pSrcDim:pSrcHier`. The subset must exist; an error is raised otherwise. | +| `MDX:` | Calls `}bedrock.hier.sub.create.bymdx` to create a temporary **public static** subset from the MDX expression. The subset is destroyed at the end of the Epilog. | + +**Partial hierarchy behaviour (Strategy A — strict):** +Consolidation relationships are only written when the child element is also present in the working subset. Parent elements whose children are entirely outside the filter are inserted without children. + +> If the MDX expression resolves to zero elements, the target hierarchy is created/cleared but left empty. No error is raised. + +### Unwind behaviour (`pUnwind`) + +| `pUnwind` | Behaviour | +|-----------|-----------| +| `0` | All elements in the target hierarchy are deleted before cloning (`HierarchyDeleteAllElements`). | +| `1` | Existing consolidations are unwound by calling `}bedrock.hier.unwind` before cloning. | +| `2` | The existing target hierarchy structure is left untouched; only missing elements/relationships are added. | + +> **Note:** If the target dimension or hierarchy does not yet exist, `pUnwind` is automatically set to `2` internally (nothing to unwind). + +--- + +## Notes & Cautions + +- **Target hierarchy cannot be `Leaves`** – the process will abort with an error if `pTgtHier` resolves to `Leaves`. +- If source and target dimension are the same and no `pTgtHier` is provided, the target hierarchy is automatically named `_Clone`. +- When `pIfNthanC = 1`, the Metadata tab still processes consolidation relationships based on the **source** element type. Only C-elements in the source have their children replicated. Elements that were N in the source but inserted as C in the target will have no children initially – they are ready to receive children as part of subsequent detailing work. +- `pAttr = 2` does not raise an error if no matching attributes are found; it simply copies nothing. +- `pSrcFilter` requires `}bedrock.hier.sub.create.bymdx` to be present on the server when using the `MDX:` prefix. +- The temporary subset created for `MDX:` filters uses the existing `cTempSub` constant (process name + timestamp + random int) and is automatically destroyed in the Epilog. It is safe under concurrent execution. +- An unrecognised `pSrcFilter` prefix (i.e. neither `Subset:` nor `MDX:`) causes an immediate abort. + +--- + +## Example Call + +``` +# Clone hierarchy and convert all N-elements to C-elements +ExecuteProcess( '}bedrock.hier.clone', + 'pLogOutput', 1, + 'pStrictErrorHandling', 0, + 'pSrcDim', 'Product', + 'pSrcHier', 'Product', + 'pTgtDim', 'Product_Detail', + 'pTgtHier', '', + 'pAttr', 2, + 'pUnwind', 0, + 'pIfNthanC', 1 +); +``` + +This call: +1. Clones the `Product` hierarchy into a new `Product_Detail` dimension. +2. Converts all N-elements to C-elements so the new dimension can immediately receive child members. +3. Copies attribute values only for attributes that already exist on the target (`pAttr = 2`). + +### Filter by named subset + +``` +ExecuteProcess( '}bedrock.hier.clone', + 'pLogOutput', 1, + 'pStrictErrorHandling', 0, + 'pSrcDim', 'Product', + 'pSrcHier', 'Product', + 'pTgtDim', 'Product_Region_A', + 'pTgtHier', '', + 'pAttr', 1, + 'pUnwind', 0, + 'pIfNthanC', 0, + 'pSrcFilter', 'Subset:Region_A_Products' +); +``` + +Clones only the elements contained in the named subset `Region_A_Products`. + +### Filter by MDX expression + +``` +ExecuteProcess( '}bedrock.hier.clone', + 'pLogOutput', 1, + 'pStrictErrorHandling', 1, + 'pSrcDim', 'Product', + 'pSrcHier', 'Product', + 'pTgtDim', 'Product_HW', + 'pTgtHier', '', + 'pAttr', 1, + 'pUnwind', 0, + 'pIfNthanC', 1, + 'pSrcFilter', 'MDX:{[Product].[Product].[Hardware].Children}' +); +``` + +Clones only the direct children of `Hardware`, inserts them as C-elements, and cleans up the temporary subset automatically. + +--- + +## Related Processes + +| Process | Description | +|---------|-------------| +| [`}bedrock.hier.unwind`](https://github.com/cubewise-code/bedrock/wiki/%7Dbedrock.hier.unwind) | Unwinds consolidation relationships in a hierarchy | +| [`}bedrock.dim.clone`](https://github.com/cubewise-code/bedrock/wiki/%7Dbedrock.dim.clone) | Clones an entire dimension including all hierarchies | +| [`}bedrock.hier.create`](https://github.com/cubewise-code/bedrock/wiki/%7Dbedrock.hier.create) | Creates a new hierarchy in an existing dimension | +| [`}bedrock.hier.sub.create.bymdx`](https://github.com/cubewise-code/bedrock/wiki/%7Dbedrock.hier.sub.create.bymdx) | Creates a named subset from an MDX expression (used internally by `pSrcFilter`) | From 51af8bca376841d955bfb551adeb946577ade295 Mon Sep 17 00:00:00 2001 From: Paul Niederbracht - OLAPLINE GmbH Date: Mon, 18 May 2026 14:28:44 +0200 Subject: [PATCH 2/2] =?UTF-8?q?}bedrock.hier.clone=20=E2=80=93=20N?= =?UTF-8?q?=E2=86=92C=20Element=20Conversion,=20Extended=20Attribute=20Han?= =?UTF-8?q?dling=20&=20Subset/MDX=20Filter=20Support?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main/}bedrock.hier.clone (2).pro | 617 ------------------------------- main/}bedrock.hier.clone.pro | 257 ++++++++----- 2 files changed, 174 insertions(+), 700 deletions(-) delete mode 100644 main/}bedrock.hier.clone (2).pro diff --git a/main/}bedrock.hier.clone (2).pro b/main/}bedrock.hier.clone (2).pro deleted file mode 100644 index 0913a1c..0000000 --- a/main/}bedrock.hier.clone (2).pro +++ /dev/null @@ -1,617 +0,0 @@ -601,100 -602,"}bedrock.hier.clone" -562,"SUBSET" -586,"}Cubes" -585,"}Cubes" -564, -565,"x1Wi2=X?2Gz6r3ZWh3[r28Zba@pwD]Aw^_WDtYcQ7F8bIRkrOsgwsNN[IFhTei[:IZBrxBNQ:yD4wM7Lfw6TAVT64EBoTF_MA``H;6z\6Uhvfzjdu6lBe>VbLXZEWbsbvB0@4yrot2oaGz6vhKE_dKClT>LMiJVyd:dV_S^?O1bcMcbpNRR>w;_3DndoRD==nP@wj;Pc" -559,1 -928,0 -593, -594, -595, -597, -598, -596, -800, -801, -566,0 -567,"," -588,"," -589,"." -568,"""" -570, -571,All -569,0 -592,0 -599,1000 -560,10 -pLogOutput -pStrictErrorHandling -pSrcDim -pSrcHier -pTgtDim -pTgtHier -pAttr -pUnwind -pIfNthanC -pSrcFilter -561,10 -1 -1 -2 -2 -2 -2 -1 -1 -1 -2 -590,10 -pLogOutput,0 -pStrictErrorHandling,0 -pSrcDim,"" -pSrcHier,"" -pTgtDim,"" -pTgtHier,"" -pAttr,0 -pUnwind,0 -pIfNthanC,0 -pSrcFilter,"" -637,10 -pLogOutput,"OPTIONAL: Write parameters and action summary to server message log (Boolean True = 1)" -pStrictErrorHandling,"OPTIONAL: On encountering any error, exit with major error status by ProcessQuit after writing to the server message log (Boolean True = 1)" -pSrcDim,"REQUIRED: Source Dimension" -pSrcHier,"REQUIRED: Source Hierarchy" -pTgtDim,"REQUIRED: Target Dimension (can be the same as source)" -pTgtHier,"OPTIONAL: Target Hierarchy (will default to SrcHier_Clone if the dimensions are the same)" -pAttr,"OPTIONAL: Include Attributes? (Boolean 1=True; 2 = only existing)" -pUnwind,"REQUIRED: Unwind? (0 = Delete all Elements, 1 = Unwind Existing Elements, 2 = Do not change Existing Elements (Only relevant if target hierarchy exists) )" -pIfNthanC,"OPTIONAL: if 1 than all N-elemens will be created as c-elements" -pSrcFilter,"OPTIONAL: Source filter. Use Subset: or MDX:" -577,1 -vEle -578,1 -2 -579,1 -1 -580,1 -0 -581,1 -0 -582,1 -VarType=32 ColType=827 -603,0 -572,292 -#Region CallThisProcess -# A snippet of code provided as an example how to call this process should the developer be working on a system without access to an editor with auto-complete. -If( 1 = 0 ); - ExecuteProcess( '}bedrock.hier.clone', 'pLogOutput', pLogOutput, - 'pStrictErrorHandling', pStrictErrorHandling, - 'pSrcDim', '', 'pSrcHier', '', - 'pTgtDim', '', 'pTgtHier', '', - 'pAttr', 0, 'pUnwind', 0, 'pIfNthanC', 0, 'pSrcFilter', '' - ); -EndIf; -#EndRegion CallThisProcess - -#****Begin: Generated Statements*** -#****End: Generated Statements**** - -################################################################################################# -##~~Join the bedrock TM1 community on GitHub https://github.com/cubewise-code/bedrock Ver 4.0~~## -################################################################################################# - -#Region @DOC -# Description: -# This process will clone the source dimension Hierarchy. - -# Use case: Mostly in Development. -# 1/ Create a duplicate of an existing hierarchy for testing. - -# Note: -# Valid source dimension name (pSrcDim) and target dimension (pTgtDim) names are mandatory otherwise the process will abort. -# Valid source hierarchy name (pSrcHier) is mandatory otherwise the process will abort. - -# Caution: -# - Target hierarchy cannot be `Leaves`. -# - If the target dimension Hierarchy exists then it will be overwritten. -#EndRegion @DOC - -### Global Varaibales ### -StringGlobalVariable ('sProcessReturnCode'); -NumericGlobalVariable('nProcessReturnCode'); -nProcessReturnCode = 0; - -### Constants ### -cThisProcName = GetProcessName(); -cUserName = TM1User(); -cTimeStamp = TimSt( Now, '\Y\m\d\h\i\s' ); -cRandomInt = NumberToString( INT( RAND( ) * 1000 )); -cTempSub = cThisProcName |'_'| cTimeStamp |'_'| cRandomInt; -cMsgErrorLevel = 'ERROR'; -cMsgErrorContent = '%cThisProcName% : %sMessage% : %cUserName%'; -cLogInfo = 'Process:%cThisProcName% run with parameters pSrcDim:%pSrcDim%, pSrcHier:%pSrcHier%, pTgtDim:%pTgtDim%, pTgtHier:%pTgtHier%, pAttr:%pAttr%, pUnwind:%pUnwind%, pIfNthanC:%pIfNthanC%, pSrcFilter:%pSrcFilter%.'; -cLangDim = '}Cultures'; -nNumLang = DimSiz( cLangDim ); - -nProcessSameNamedHier = 0; -sEpilogTgtHier = ''; -nTempSubsetCreated = 0; -sTempSubset = ''; -sFilterPrefix = ''; -sFilterValue = ''; - -## LogOutput parameters -IF ( pLogoutput = 1 ); - LogOutput('INFO', Expand( cLogInfo ) ); -ENDIF; - -### Validate Parameters ### -nErrors = 0; - -If( Scan( ':', pSrcDim ) > 0 & pSrcHier @= '' ); - # A hierarchy has been passed as dimension. Handle the input error by splitting dim:hier into dimension & hierarchy - pSrcHier = SubSt( pSrcDim, Scan( ':', pSrcDim ) + 1, Long( pSrcDim ) ); - pSrcDim = SubSt( pSrcDim, 1, Scan( ':', pSrcDim ) - 1 ); -EndIf; - -## Validate Source dimension -IF( Trim( pSrcDim ) @= '' ); - nErrors = 1; - sMessage = 'No source dimension specified.'; - LogOutput( cMsgErrorLevel, Expand( cMsgErrorContent ) ); -EndIf; - -IF( DimensionExists( pSrcDim ) = 0 ); - nErrors = 1; - sMessage = 'Invalid source dimension: ' | pSrcDim; - LogOutput( cMsgErrorLevel, Expand( cMsgErrorContent ) ); -EndIf; - -# Validate Source hierarchy -IF( Trim( pSrcHier ) @= '' ); - pSrcHier = pSrcDim; -ElseIF(HierarchyExists(pSrcDim,pSrcHier ) = 0 ); - nErrors = 1; - sMessage = 'Invalid source hierarchy: ' | pSrcHier; - LogOutput( cMsgErrorLevel, Expand( cMsgErrorContent ) ); -EndIf; - -# Validate Target dimension -IF( Trim( pTgtDim ) @= '' ); - nErrors = 1; - sMessage = 'No target dimension specified.'; - LogOutput( cMsgErrorLevel, Expand( cMsgErrorContent ) ); -ElseIf( Scan( ':', pTgtDim ) > 0 & pTgtHier @= '' ); - # A hierarchy has been passed as dimension. Handle the input error by splitting dim:hier into dimension & hierarchy - pTgtHier = SubSt( pTgtDim, Scan( ':', pTgtDim ) + 1, Long( pTgtDim ) ); - pTgtDim = SubSt( pTgtDim, 1, Scan( ':', pTgtDim ) - 1 ); -EndIf; - -If ( DimensionExists( pTgtDim ) = 0 ); - DimensionCreate( pTgtDim ); - ### In this case clone source hierarchy into same-named hierarchy of the new target dimension first. This will allow attributes to be processed in the data tab. - nProcessSameNamedHier = 1; -EndIf; - -# Validate target hierarchy -If( pSrcDim @= pTgtDim); - If( pTgtHier @= '' % pTgtHier @= pSrcHier ); - pTgtHier = pSrcHier | '_Clone'; - EndIf; -ElseIf(pTgtHier @= ''); - If( nProcessSameNamedHier = 1 ); - sEpilogTgtHier = pTgtHier; - pTgtHier = pTgtDim; - Else; - pTgtHier = pSrcHier; - EndIf; -ElseIf( nProcessSameNamedHier = 1 ); - sEpilogTgtHier = pTgtHier; - pTgtHier = pTgtDim; -Endif; - -pTgtHier = Trim(pTgtHier); - -IF(pTgtHier @= 'Leaves' ); - nErrors = 1; - sMessage = 'Leaves is an invalid selection for Target Hierarchy: ' | pTgtDim |':'|pTgtHier; - LogOutput( cMsgErrorLevel, Expand( cMsgErrorContent ) ); -EndIf; - -If( DimensionExists( pTgtDim ) = 0 ); - If( pUnwind >= 1 ); - pUnwind = 2; - EndIf; -ElseIf( HierarchyExists( pTgtDim, pTgtHier ) = 0 ); - If( pUnwind >= 1 ); - pUnwind = 2; - EndIf; -EndIf; - -### Check for errors before continuing -If( nErrors <> 0 ); - If( pStrictErrorHandling = 1 ); - ProcessQuit; - Else; - ProcessBreak; - EndIf; -EndIf; - -### Resolve pSrcFilter ### -If( Trim( pSrcFilter ) @<> '' ); - If( SubSt( pSrcFilter, 1, 7 ) @= 'Subset:' ); - sFilterPrefix = 'Subset'; - sFilterValue = Trim( SubSt( pSrcFilter, 8, Long( pSrcFilter ) ) ); - ElseIf( SubSt( pSrcFilter, 1, 4 ) @= 'MDX:' ); - sFilterPrefix = 'MDX'; - sFilterValue = Trim( SubSt( pSrcFilter, 5, Long( pSrcFilter ) ) ); - Else; - nErrors = 1; - sMessage = 'Invalid pSrcFilter prefix. Use \"Subset:\" or \"MDX:\".'; - LogOutput( cMsgErrorLevel, Expand( cMsgErrorContent ) ); - EndIf; -EndIf; - -If( sFilterPrefix @= 'Subset' ); - If( SubsetExists( pSrcDim, sFilterValue ) = 0 ); - nErrors = 1; - sMessage = 'Subset not found: ' | sFilterValue | ' on dimension ' | pSrcDim; - LogOutput( cMsgErrorLevel, Expand( cMsgErrorContent ) ); - Else; - sTempSubset = sFilterValue; - EndIf; -ElseIf( sFilterPrefix @= 'MDX' ); - sTempSubset = cTempSub; - nRet = ExecuteProcess( '}bedrock.hier.sub.create.bymdx', - 'pLogOutput', pLogOutput, - 'pStrictErrorHandling', pStrictErrorHandling, - 'pDim', pSrcDim, - 'pHier', pSrcHier, - 'pSub', sTempSubset, - 'pMDXExpr', sFilterValue, - 'pConvertToStatic', 1, - 'pTemp', 1 - ); - If( nRet = 0 ); - nTempSubsetCreated = 1; - Else; - nErrors = 1; - sMessage = 'Failed to create MDX subset. Check MDX expression: ' | sFilterValue; - LogOutput( cMsgErrorLevel, Expand( cMsgErrorContent ) ); - EndIf; -Else; - sTempSubset = 'ALL'; -EndIf; - -If( nErrors <> 0 ); - If( pStrictErrorHandling = 1 ); - ProcessQuit; - Else; - ProcessBreak; - EndIf; -EndIf; - -### Create target dimension Hierarchy ### -If( HierarchyExists( pTgtDim, pTgtHier) = 0 ); - HierarchyCreate( pTgtDim, pTgtHier ); -Else; - IF(pUnwind = 1 ); - nRet = ExecuteProcess('}bedrock.hier.unwind', - 'pLogOutput', pLogOutput, - 'pStrictErrorHandling', pStrictErrorHandling, - 'pDim', pTgtDim, - 'pHier', pTgtHier, - 'pConsol', '*', - 'pRecursive', 1 - ); - ELSEIF(pUnwind = 2 ); - #Do nothing - ELSEIF(pUnwind = 0 ); - HierarchyDeleteAllElements( pTgtDim, pTgtHier ); - EndIf; -EndIf; - -If(pSrcDim @=pSrcHier); - sDimHier = pSrcDim; - Else; - sDimHier =pSrcDim|':'|pSrcHier; - Endif; - -### Set the target Sort Order ### -sSortElementsType = CELLGETS( '}DimensionProperties', sDimHier, 'SORTELEMENTSTYPE'); -sSortElementsSense = CELLGETS( '}DimensionProperties', sDimHier, 'SORTELEMENTSSENSE'); -sSortComponentsType = CELLGETS( '}DimensionProperties', sDimHier, 'SORTCOMPONENTSTYPE'); -sSortComponentsSense = CELLGETS( '}DimensionProperties', sDimHier, 'SORTCOMPONENTSSENSE'); - -HierarchySortOrder(pTgtDim, pTgtHier, sSortComponentsType, sSortComponentsSense, sSortElementsType , sSortElementsSense); - -nSourceHierSize = SubsetGetSize( pSrcDim, sTempSubset ); - -nIndex = 1; -WHILE( nIndex <= nSourceHierSize ); - sElName = SubsetGetElementName( pSrcDim, sTempSubset, nIndex ); - sElType = ElementType( pSrcDim, pSrcHier, sElName ); - - if( sElType @<> 'S' & pIfNthanC = 1 ); - HierarchyElementInsert( pTgtDim, pTgtHier, '', sElName, 'C' ); - else; - HierarchyElementInsert( pTgtDim, pTgtHier, '', sElName, sElType ); - endif; - nIndex = nIndex + 1; -END; - -### Assign Data Source ### - -DatasourceNameForServer = pSrcDim|':'|pSrcHier; -DataSourceType = 'SUBSET'; -DatasourceDimensionSubset = sTempSubset; - -### Replicate Attributes ### - -# Note: DType on Attr dim returns "AS", "AN" or "AA" need to strip off leading "A" - -sAttrDim = '}ElementAttributes_' | pSrcDim; -sAttrLoc = '}LocalizedElementAttributes_' | pSrcDim; -sAttrTragetDim = '}ElementAttributes_' | pTgtDim; -sAttrLocTarget = '}LocalizedElementAttributes_' | pTgtDim; - -If( pAttr = 1 & DimensionExists( sAttrDim ) = 1 ); - nNumAttrs = DimSiz( sAttrDim ); - nCount = 1; - While( nCount <= nNumAttrs ); - sAttrName = DimNm( sAttrDim, nCount ); - sAttrType = SubSt(DType( sAttrDim, sAttrName ), 2, 1 ); - If ( DimensionExists( sAttrTragetDim ) = 0); - AttrInsert(pTgtDim,'',sAttrName,sAttrType ); - ElseIF(DimIx(sAttrTragetDim, sAttrName) = 0); - AttrInsert(pTgtDim,'',sAttrName,sAttrType ); - Endif; - nCount = nCount + 1; - End; -Elseif(pAttr > 1 & DimensionExists( sAttrDim ) = 1 ); - nNumAttrs = DimSiz( sAttrTragetDim ); -EndIf; - -### End Prolog ### -573,38 - -#****Begin: Generated Statements*** -#****End: Generated Statements**** - -################################################################################################# -##~~Join the bedrock TM1 community on GitHub https://github.com/cubewise-code/bedrock Ver 4.0.0~~## -################################################################################################# - - -### Check for errors in prolog ### - -If( nErrors <> 0 ); - If( pStrictErrorHandling = 1 ); - ProcessQuit; - Else; - ProcessBreak; - EndIf; -EndIf; - -### Add Elements to target dimension ### - -sElType = ElementType(pSrcDim, pSrcHier, vEle); - - -IF( sElType @= 'C' & ElementComponentCount( pSrcDim, pSrcHier, vEle ) > 0 ); - nChildren = ElementComponentCount( pSrcDim, pSrcHier, vEle ); - nCount = 1; - While( nCount <= nChildren ); - sChildElement = ElementComponent( pSrcDim, pSrcHier, vEle, nCount ); - sChildWeight = ElementWeight( pSrcDim, pSrcHier, vEle, sChildElement ); - If( HierarchyElementExists( pTgtDim, pTgtHier, sChildElement ) = 1 ); - HierarchyElementComponentAdd( pTgtDim, pTgtHier, vEle, sChildElement, sChildWeight ); - EndIf; - nCount = nCount + 1; - End; -EndIf; - -### End MetaData ### -574,97 - -#****Begin: Generated Statements*** -#****End: Generated Statements**** - -################################################################################################# -##~~Join the bedrock TM1 community on GitHub https://github.com/cubewise-code/bedrock Ver 4.0.0~~## -################################################################################################# - - -### Check for errors in prolog ### - -If( nErrors <> 0 ); - If( pStrictErrorHandling = 1 ); - ProcessQuit; - Else; - ProcessBreak; - EndIf; -EndIf; - -### Replicate Attributes ### -# Note: DTYPE on Attr dim returns "AS", "AN" or "AA" need to strip off leading "A" - - -If( pAttr >= 1 & DimensionExists( sAttrTragetDim ) = 1 ); - - nAttr = 1; - While( nAttr <= nNumAttrs ); - sAttrName = DimNm( sAttrTragetDim, nAttr ); - sAttrType = SubSt( DTYPE( sAttrTragetDim, sAttrName ), 2, 1 ); - - if(pAttr > 1 & (DIMIX(sAttrTragetDim, sAttrName) = 0 % DIMIX(sAttrDim, sAttrName) = 0)); - #Do nothing, only existing attributes will be copied in this case - else; - - If( sAttrType @= 'S' % sAttrType @= 'A' ); - sAttrVal = ElementAttrS( pSrcDim, pSrcHier, vEle, sAttrName ); - - If( sAttrVal @<> '' ); - If( CellIsUpdateable( '}ElementAttributes_' | pTgtDim, pTgtHier:vEle, sAttrName ) = 1 ); - If( sAttrType @= 'A' ); - ElementAttrPutS( sAttrVal, pTgtDim, pTgtHier, vEle, sAttrName, 1 ); - Else; - ElementAttrPutS( sAttrVal, pTgtDim, pTgtHier, vEle, sAttrName ); - EndIf; - EndIf; - EndIf; - Else; - nAttrVal = ElementAttrN( pSrcDim, pSrcHier, vEle, sAttrName ); - If( nAttrVal <> 0 ); - If( CellIsUpdateable( '}ElementAttributes_' | pTgtDim, pTgtHier:vEle, sAttrName ) = 1 ); - ElementAttrPutN( nAttrVal, pTgtDim, pTgtHier, vEle, sAttrName ); - EndIf; - EndIf; - EndIf; - # check for localized attributes - If( CubeExists( sAttrLoc ) = 1 ); - - nLang = 1; - While( nLang <= nNumLang ); - sLang = DimNm( cLangDim, nLang ); - If( sAttrType @= 'A' % sAttrType @= 'S' ); - sAttrVal = ElementAttrS( pSrcDim, pSrcHier, vEle, sAttrName ); - sAttrValLoc = ElementAttrSL( pSrcDim, pSrcHier, vEle, sAttrName, sLang ); - If( sAttrValLoc @= sAttrVal ); sAttrValLoc = ''; EndIf; - Else; - nAttrVal = ElementAttrN( pSrcDim, pSrcHier, vEle, sAttrName ); - nAttrValLoc = ElementAttrNL( pSrcDim, pSrcHier, vEle, sAttrName, sLang ); - EndIf; - If( CubeExists( sAttrLocTarget ) = 0 ); - If( sAttrType @= 'A' ); - ElementAttrPutS( sAttrValLoc, pTgtDim, pTgtHier, vEle, sAttrName, sLang, 1 ); - ElseIf( sAttrType @= 'N' ); - ElementAttrPutN( nAttrValLoc, pTgtDim, pTgtHier, vEle, sAttrName, sLang ); - Else; - ElementAttrPutS( sAttrValLoc, pTgtDim, pTgtHier, vEle, sAttrName, sLang ); - EndIf; - ElseIf(CubeExists( sAttrLocTarget ) = 1 ); - If( CellIsUpdateable( sAttrLocTarget, pTgtHier:vEle, sLang, sAttrName ) = 1 ); - If( sAttrType @= 'A' ); - ElementAttrPutS( sAttrValLoc, pTgtDim, pTgtHier, vEle, sAttrName, sLang, 1 ); - ElseIf( sAttrType @= 'N' ); - ElementAttrPutN( nAttrValLoc, pTgtDim, pTgtHier, vEle, sAttrName, sLang ); - Else; - ElementAttrPutS( sAttrValLoc, pTgtDim, pTgtHier, vEle, sAttrName, sLang ); - EndIf; - EndIf; - EndIf; - nLang = nLang + 1; - End; - EndIf; - endif; - nAttr = nAttr + 1; - End; - -EndIf; - -### End Data ### -575,62 - -#****Begin: Generated Statements*** -#****End: Generated Statements**** - -################################################################################################# -##~~Join the bedrock TM1 community on GitHub https://github.com/cubewise-code/bedrock Ver 4.0~~## -################################################################################################# - - -If(pTgtDim @=pTgtHier); - sTargetDimHier = pTgtDim; -Else; - sTargetDimHier =pTgtDim|':'|pTgtHier; -EndIf; - -### Set the target Sort Order ### - CELLPUTS( sSortElementsType, '}DimensionProperties', sTargetDimHier, 'SORTELEMENTSTYPE'); - CELLPUTS( sSortElementsSense, '}DimensionProperties', sTargetDimHier, 'SORTELEMENTSSENSE'); - CELLPUTS( sSortComponentsType, '}DimensionProperties',sTargetDimHier, 'SORTCOMPONENTSTYPE'); - CELLPUTS( sSortComponentsSense, '}DimensionProperties', sTargetDimHier, 'SORTCOMPONENTSSENSE'); - -### Clean up temporary subset ### -If( nTempSubsetCreated = 1 ); - SubsetDestroy( pSrcDim, sTempSubset ); - nTempSubsetCreated = 0; -EndIf; - -### If a new dimension has been created, call the process recursively to clone the alternate hierarchy, after the same named hierarchy has been processed -If( nProcessSameNamedHier = 1 ); - nRet = EXECUTEPROCESS(GetProcessName(), - 'pLogOutput', pLogOutput, - 'pStrictErrorHandling', pStrictErrorHandling, - 'pSrcDim', pSrcDim, - 'pSrcHier',pSrcHier, - 'pTgtDim', pTgtDim, - 'pTgtHier', sEpilogTgtHier, - 'pAttr', pAttr, - 'pUnwind', pUnwind, - 'pIfNthanC', pIfNthanC, - 'pSrcFilter', pSrcFilter - ); -EndIf; - -### Return code & final error message handling -If( nErrors > 0 ); - sMessage = 'the process incurred at least 1 error. Please see above lines in this file for more details.'; - nProcessReturnCode = 0; - LogOutput( cMsgErrorLevel, Expand( cMsgErrorContent ) ); - sProcessReturnCode = Expand( '%sProcessReturnCode% Process:%cThisProcName% completed with errors. Check tm1server.log for details.' ); - If( pStrictErrorHandling = 1 ); - ProcessQuit; - EndIf; -Else; - sProcessAction = Expand( 'Process:%cThisProcName% successfully cloned the %pSrcDim%:%pSrcHier% dimension:hierarchy to %pTgtDim%:%pTgtHier%' ); - sProcessReturnCode = Expand( '%sProcessReturnCode% %sProcessAction%' ); - nProcessReturnCode = 1; - If( pLogoutput = 1 ); - LogOutput('INFO', Expand( sProcessAction ) ); - EndIf; -EndIf; - -### End Epilog ### -576,CubeAction=1511 DataAction=1503 CubeLogChanges=0 -930,0 -638,1 -804,0 -1217,1 -900, -901, -902, -938,0 -937, -936, -935, -934, -932,0 -933,0 -903, -906, -929, -907, -908, -904,0 -905,0 -909,0 -911, -912, -913, -914, -915, -916, -917,0 -918,1 -919,0 -920,50000 -921,"" -922,"" -923,0 -924,"" -925,"" -926,"" -927,"" diff --git a/main/}bedrock.hier.clone.pro b/main/}bedrock.hier.clone.pro index 6e652ba..0913a1c 100644 --- a/main/}bedrock.hier.clone.pro +++ b/main/}bedrock.hier.clone.pro @@ -4,7 +4,7 @@ 586,"}Cubes" 585,"}Cubes" 564, -565,"wleeZe@zs7:tX9hx?u8=<0FaW__6oO_IW\i]GERwH5`Hw`6q9e0r_mjF4dnqAvM0p`FzSI9dbQewiAIAJZ:9z]onUjR5yxbZv@p]FnptevOM8bUkkO_:U`O0w2PB^a5Co7ez`=RVbLXZEWbsbvB0@4yrot2oaGz6vhKE_dKClT>LMiJVyd:dV_S^?O1bcMcbpNRR>w;_3DndoRD==nP@wj;Pc" 559,1 928,0 593, @@ -17,15 +17,15 @@ 801, 566,0 567,"," -588,"." -589,"," +588,"," +589,"." 568,"""" 570, 571,All 569,0 592,0 599,1000 -560,8 +560,10 pLogOutput pStrictErrorHandling pSrcDim @@ -34,7 +34,9 @@ pTgtDim pTgtHier pAttr pUnwind -561,8 +pIfNthanC +pSrcFilter +561,10 1 1 2 @@ -43,7 +45,9 @@ pUnwind 2 1 1 -590,8 +1 +2 +590,10 pLogOutput,0 pStrictErrorHandling,0 pSrcDim,"" @@ -52,15 +56,19 @@ pTgtDim,"" pTgtHier,"" pAttr,0 pUnwind,0 -637,8 +pIfNthanC,0 +pSrcFilter,"" +637,10 pLogOutput,"OPTIONAL: Write parameters and action summary to server message log (Boolean True = 1)" pStrictErrorHandling,"OPTIONAL: On encountering any error, exit with major error status by ProcessQuit after writing to the server message log (Boolean True = 1)" pSrcDim,"REQUIRED: Source Dimension" pSrcHier,"REQUIRED: Source Hierarchy" pTgtDim,"REQUIRED: Target Dimension (can be the same as source)" pTgtHier,"OPTIONAL: Target Hierarchy (will default to SrcHier_Clone if the dimensions are the same)" -pAttr,"OPTIONAL: Include Attributes? (Boolean 1=True)" +pAttr,"OPTIONAL: Include Attributes? (Boolean 1=True; 2 = only existing)" pUnwind,"REQUIRED: Unwind? (0 = Delete all Elements, 1 = Unwind Existing Elements, 2 = Do not change Existing Elements (Only relevant if target hierarchy exists) )" +pIfNthanC,"OPTIONAL: if 1 than all N-elemens will be created as c-elements" +pSrcFilter,"OPTIONAL: Source filter. Use Subset: or MDX:" 577,1 vEle 578,1 @@ -74,7 +82,7 @@ vEle 582,1 VarType=32 ColType=827 603,0 -572,227 +572,292 #Region CallThisProcess # A snippet of code provided as an example how to call this process should the developer be working on a system without access to an editor with auto-complete. If( 1 = 0 ); @@ -82,7 +90,7 @@ If( 1 = 0 ); 'pStrictErrorHandling', pStrictErrorHandling, 'pSrcDim', '', 'pSrcHier', '', 'pTgtDim', '', 'pTgtHier', '', - 'pAttr', 0, 'pUnwind', 0 + 'pAttr', 0, 'pUnwind', 0, 'pIfNthanC', 0, 'pSrcFilter', '' ); EndIf; #EndRegion CallThisProcess @@ -123,12 +131,16 @@ cRandomInt = NumberToString( INT( RAND( ) * 1000 )); cTempSub = cThisProcName |'_'| cTimeStamp |'_'| cRandomInt; cMsgErrorLevel = 'ERROR'; cMsgErrorContent = '%cThisProcName% : %sMessage% : %cUserName%'; -cLogInfo = 'Process:%cThisProcName% run with parameters pSrcDim:%pSrcDim%, pSrcHier:%pSrcHier%, pTgtDim:%pTgtDim%, pTgtHier:%pTgtHier%, pAttr:%pAttr%, pUnwind:%pUnwind%.'; +cLogInfo = 'Process:%cThisProcName% run with parameters pSrcDim:%pSrcDim%, pSrcHier:%pSrcHier%, pTgtDim:%pTgtDim%, pTgtHier:%pTgtHier%, pAttr:%pAttr%, pUnwind:%pUnwind%, pIfNthanC:%pIfNthanC%, pSrcFilter:%pSrcFilter%.'; cLangDim = '}Cultures'; nNumLang = DimSiz( cLangDim ); nProcessSameNamedHier = 0; sEpilogTgtHier = ''; +nTempSubsetCreated = 0; +sTempSubset = ''; +sFilterPrefix = ''; +sFilterValue = ''; ## LogOutput parameters IF ( pLogoutput = 1 ); @@ -227,6 +239,60 @@ If( nErrors <> 0 ); EndIf; EndIf; +### Resolve pSrcFilter ### +If( Trim( pSrcFilter ) @<> '' ); + If( SubSt( pSrcFilter, 1, 7 ) @= 'Subset:' ); + sFilterPrefix = 'Subset'; + sFilterValue = Trim( SubSt( pSrcFilter, 8, Long( pSrcFilter ) ) ); + ElseIf( SubSt( pSrcFilter, 1, 4 ) @= 'MDX:' ); + sFilterPrefix = 'MDX'; + sFilterValue = Trim( SubSt( pSrcFilter, 5, Long( pSrcFilter ) ) ); + Else; + nErrors = 1; + sMessage = 'Invalid pSrcFilter prefix. Use \"Subset:\" or \"MDX:\".'; + LogOutput( cMsgErrorLevel, Expand( cMsgErrorContent ) ); + EndIf; +EndIf; + +If( sFilterPrefix @= 'Subset' ); + If( SubsetExists( pSrcDim, sFilterValue ) = 0 ); + nErrors = 1; + sMessage = 'Subset not found: ' | sFilterValue | ' on dimension ' | pSrcDim; + LogOutput( cMsgErrorLevel, Expand( cMsgErrorContent ) ); + Else; + sTempSubset = sFilterValue; + EndIf; +ElseIf( sFilterPrefix @= 'MDX' ); + sTempSubset = cTempSub; + nRet = ExecuteProcess( '}bedrock.hier.sub.create.bymdx', + 'pLogOutput', pLogOutput, + 'pStrictErrorHandling', pStrictErrorHandling, + 'pDim', pSrcDim, + 'pHier', pSrcHier, + 'pSub', sTempSubset, + 'pMDXExpr', sFilterValue, + 'pConvertToStatic', 1, + 'pTemp', 1 + ); + If( nRet = 0 ); + nTempSubsetCreated = 1; + Else; + nErrors = 1; + sMessage = 'Failed to create MDX subset. Check MDX expression: ' | sFilterValue; + LogOutput( cMsgErrorLevel, Expand( cMsgErrorContent ) ); + EndIf; +Else; + sTempSubset = 'ALL'; +EndIf; + +If( nErrors <> 0 ); + If( pStrictErrorHandling = 1 ); + ProcessQuit; + Else; + ProcessBreak; + EndIf; +EndIf; + ### Create target dimension Hierarchy ### If( HierarchyExists( pTgtDim, pTgtHier) = 0 ); HierarchyCreate( pTgtDim, pTgtHier ); @@ -261,13 +327,18 @@ sSortComponentsSense = CELLGETS( '}DimensionProperties', sDimHier, 'SORTCOMPONE HierarchySortOrder(pTgtDim, pTgtHier, sSortComponentsType, sSortComponentsSense, sSortElementsType , sSortElementsSense); -nSourceHierSize = DimSiz(pSrcDim|':'|pSrcHier); +nSourceHierSize = SubsetGetSize( pSrcDim, sTempSubset ); nIndex = 1; WHILE( nIndex <= nSourceHierSize ); - sElName = ElementName(pSrcDim, pSrcHier, nIndex); - sElType = ElementType(pSrcDim, pSrcHier, sElName); - HierarchyElementInsert(pTgtDim, pTgtHier, '', sElName, sElType); + sElName = SubsetGetElementName( pSrcDim, sTempSubset, nIndex ); + sElType = ElementType( pSrcDim, pSrcHier, sElName ); + + if( sElType @<> 'S' & pIfNthanC = 1 ); + HierarchyElementInsert( pTgtDim, pTgtHier, '', sElName, 'C' ); + else; + HierarchyElementInsert( pTgtDim, pTgtHier, '', sElName, sElType ); + endif; nIndex = nIndex + 1; END; @@ -275,7 +346,7 @@ END; DatasourceNameForServer = pSrcDim|':'|pSrcHier; DataSourceType = 'SUBSET'; -DatasourceDimensionSubset = 'ALL'; +DatasourceDimensionSubset = sTempSubset; ### Replicate Attributes ### @@ -299,10 +370,12 @@ If( pAttr = 1 & DimensionExists( sAttrDim ) = 1 ); Endif; nCount = nCount + 1; End; +Elseif(pAttr > 1 & DimensionExists( sAttrDim ) = 1 ); + nNumAttrs = DimSiz( sAttrTragetDim ); EndIf; ### End Prolog ### -573,35 +573,38 #****Begin: Generated Statements*** #****End: Generated Statements**** @@ -326,19 +399,22 @@ EndIf; sElType = ElementType(pSrcDim, pSrcHier, vEle); + IF( sElType @= 'C' & ElementComponentCount( pSrcDim, pSrcHier, vEle ) > 0 ); nChildren = ElementComponentCount( pSrcDim, pSrcHier, vEle ); nCount = 1; While( nCount <= nChildren ); sChildElement = ElementComponent( pSrcDim, pSrcHier, vEle, nCount ); - sChildWeight = ElementWeight( pSrcDim,pSrcHier, vEle, sChildElement ); - HierarchyElementComponentAdd(pTgtDim, pTgtHier, vEle, sChildElement, sChildWeight); + sChildWeight = ElementWeight( pSrcDim, pSrcHier, vEle, sChildElement ); + If( HierarchyElementExists( pTgtDim, pTgtHier, sChildElement ) = 1 ); + HierarchyElementComponentAdd( pTgtDim, pTgtHier, vEle, sChildElement, sChildWeight ); + EndIf; nCount = nCount + 1; End; EndIf; ### End MetaData ### -574,90 +574,97 #****Begin: Generated Statements*** #****End: Generated Statements**** @@ -361,75 +437,82 @@ EndIf; ### Replicate Attributes ### # Note: DTYPE on Attr dim returns "AS", "AN" or "AA" need to strip off leading "A" -If( pAttr = 1 & DimensionExists( sAttrDim ) = 1 ); + +If( pAttr >= 1 & DimensionExists( sAttrTragetDim ) = 1 ); nAttr = 1; While( nAttr <= nNumAttrs ); - sAttrName = DimNm( sAttrDim, nAttr ); - sAttrType = SubSt( DTYPE( sAttrDim, sAttrName ), 2, 1 ); + sAttrName = DimNm( sAttrTragetDim, nAttr ); + sAttrType = SubSt( DTYPE( sAttrTragetDim, sAttrName ), 2, 1 ); - If( sAttrType @= 'S' % sAttrType @= 'A' ); - sAttrVal = ElementAttrS( pSrcDim, pSrcHier, vEle, sAttrName ); - - If( sAttrVal @<> '' ); - If( CellIsUpdateable( '}ElementAttributes_' | pTgtDim, pTgtHier:vEle, sAttrName ) = 1 ); - If( sAttrType @= 'A' ); - ElementAttrPutS( sAttrVal, pTgtDim, pTgtHier, vEle, sAttrName, 1 ); - Else; - ElementAttrPutS( sAttrVal, pTgtDim, pTgtHier, vEle, sAttrName ); - EndIf; - EndIf; - EndIf; - Else; - nAttrVal = ElementAttrN( pSrcDim, pSrcHier, vEle, sAttrName ); - If( nAttrVal <> 0 ); - If( CellIsUpdateable( '}ElementAttributes_' | pTgtDim, pTgtHier:vEle, sAttrName ) = 1 ); - ElementAttrPutN( nAttrVal, pTgtDim, pTgtHier, vEle, sAttrName ); - EndIf; - EndIf; - EndIf; - # check for localized attributes - If( CubeExists( sAttrLoc ) = 1 ); - nLang = 1; - While( nLang <= nNumLang ); - sLang = DimNm( cLangDim, nLang ); - If( sAttrType @= 'A' % sAttrType @= 'S' ); - sAttrVal = ElementAttrS( pSrcDim, pSrcHier, vEle, sAttrName ); - sAttrValLoc = ElementAttrSL( pSrcDim, pSrcHier, vEle, sAttrName, sLang ); - If( sAttrValLoc @= sAttrVal ); sAttrValLoc = ''; EndIf; - Else; - nAttrVal = ElementAttrN( pSrcDim, pSrcHier, vEle, sAttrName ); - nAttrValLoc = ElementAttrNL( pSrcDim, pSrcHier, vEle, sAttrName, sLang ); - EndIf; - If( CubeExists( sAttrLocTarget ) = 0 ); - If( sAttrType @= 'A' ); - ElementAttrPutS( sAttrValLoc, pTgtDim, pTgtHier, vEle, sAttrName, sLang, 1 ); - ElseIf( sAttrType @= 'N' ); - ElementAttrPutN( nAttrValLoc, pTgtDim, pTgtHier, vEle, sAttrName, sLang ); - Else; - ElementAttrPutS( sAttrValLoc, pTgtDim, pTgtHier, vEle, sAttrName, sLang ); - EndIf; - ElseIf(CubeExists( sAttrLocTarget ) = 1 ); - If( CellIsUpdateable( sAttrLocTarget, pTgtHier:vEle, sLang, sAttrName ) = 1 ); - If( sAttrType @= 'A' ); - ElementAttrPutS( sAttrValLoc, pTgtDim, pTgtHier, vEle, sAttrName, sLang, 1 ); - ElseIf( sAttrType @= 'N' ); - ElementAttrPutN( nAttrValLoc, pTgtDim, pTgtHier, vEle, sAttrName, sLang ); - Else; - ElementAttrPutS( sAttrValLoc, pTgtDim, pTgtHier, vEle, sAttrName, sLang ); - EndIf; - EndIf; - EndIf; - nLang = nLang + 1; - End; - EndIf; + if(pAttr > 1 & (DIMIX(sAttrTragetDim, sAttrName) = 0 % DIMIX(sAttrDim, sAttrName) = 0)); + #Do nothing, only existing attributes will be copied in this case + else; + + If( sAttrType @= 'S' % sAttrType @= 'A' ); + sAttrVal = ElementAttrS( pSrcDim, pSrcHier, vEle, sAttrName ); + + If( sAttrVal @<> '' ); + If( CellIsUpdateable( '}ElementAttributes_' | pTgtDim, pTgtHier:vEle, sAttrName ) = 1 ); + If( sAttrType @= 'A' ); + ElementAttrPutS( sAttrVal, pTgtDim, pTgtHier, vEle, sAttrName, 1 ); + Else; + ElementAttrPutS( sAttrVal, pTgtDim, pTgtHier, vEle, sAttrName ); + EndIf; + EndIf; + EndIf; + Else; + nAttrVal = ElementAttrN( pSrcDim, pSrcHier, vEle, sAttrName ); + If( nAttrVal <> 0 ); + If( CellIsUpdateable( '}ElementAttributes_' | pTgtDim, pTgtHier:vEle, sAttrName ) = 1 ); + ElementAttrPutN( nAttrVal, pTgtDim, pTgtHier, vEle, sAttrName ); + EndIf; + EndIf; + EndIf; + # check for localized attributes + If( CubeExists( sAttrLoc ) = 1 ); + + nLang = 1; + While( nLang <= nNumLang ); + sLang = DimNm( cLangDim, nLang ); + If( sAttrType @= 'A' % sAttrType @= 'S' ); + sAttrVal = ElementAttrS( pSrcDim, pSrcHier, vEle, sAttrName ); + sAttrValLoc = ElementAttrSL( pSrcDim, pSrcHier, vEle, sAttrName, sLang ); + If( sAttrValLoc @= sAttrVal ); sAttrValLoc = ''; EndIf; + Else; + nAttrVal = ElementAttrN( pSrcDim, pSrcHier, vEle, sAttrName ); + nAttrValLoc = ElementAttrNL( pSrcDim, pSrcHier, vEle, sAttrName, sLang ); + EndIf; + If( CubeExists( sAttrLocTarget ) = 0 ); + If( sAttrType @= 'A' ); + ElementAttrPutS( sAttrValLoc, pTgtDim, pTgtHier, vEle, sAttrName, sLang, 1 ); + ElseIf( sAttrType @= 'N' ); + ElementAttrPutN( nAttrValLoc, pTgtDim, pTgtHier, vEle, sAttrName, sLang ); + Else; + ElementAttrPutS( sAttrValLoc, pTgtDim, pTgtHier, vEle, sAttrName, sLang ); + EndIf; + ElseIf(CubeExists( sAttrLocTarget ) = 1 ); + If( CellIsUpdateable( sAttrLocTarget, pTgtHier:vEle, sLang, sAttrName ) = 1 ); + If( sAttrType @= 'A' ); + ElementAttrPutS( sAttrValLoc, pTgtDim, pTgtHier, vEle, sAttrName, sLang, 1 ); + ElseIf( sAttrType @= 'N' ); + ElementAttrPutN( nAttrValLoc, pTgtDim, pTgtHier, vEle, sAttrName, sLang ); + Else; + ElementAttrPutS( sAttrValLoc, pTgtDim, pTgtHier, vEle, sAttrName, sLang ); + EndIf; + EndIf; + EndIf; + nLang = nLang + 1; + End; + EndIf; + endif; nAttr = nAttr + 1; End; EndIf; ### End Data ### -575,54 +575,62 #****Begin: Generated Statements*** #****End: Generated Statements**** @@ -450,10 +533,16 @@ EndIf; CELLPUTS( sSortElementsSense, '}DimensionProperties', sTargetDimHier, 'SORTELEMENTSSENSE'); CELLPUTS( sSortComponentsType, '}DimensionProperties',sTargetDimHier, 'SORTCOMPONENTSTYPE'); CELLPUTS( sSortComponentsSense, '}DimensionProperties', sTargetDimHier, 'SORTCOMPONENTSSENSE'); + +### Clean up temporary subset ### +If( nTempSubsetCreated = 1 ); + SubsetDestroy( pSrcDim, sTempSubset ); + nTempSubsetCreated = 0; +EndIf; ### If a new dimension has been created, call the process recursively to clone the alternate hierarchy, after the same named hierarchy has been processed If( nProcessSameNamedHier = 1 ); - nRet = ExecuteProcess('}bedrock.hier.clone', + nRet = EXECUTEPROCESS(GetProcessName(), 'pLogOutput', pLogOutput, 'pStrictErrorHandling', pStrictErrorHandling, 'pSrcDim', pSrcDim, @@ -461,7 +550,9 @@ If( nProcessSameNamedHier = 1 ); 'pTgtDim', pTgtDim, 'pTgtHier', sEpilogTgtHier, 'pAttr', pAttr, - 'pUnwind', pUnwind + 'pUnwind', pUnwind, + 'pIfNthanC', pIfNthanC, + 'pSrcFilter', pSrcFilter ); EndIf; @@ -484,7 +575,7 @@ Else; EndIf; ### End Epilog ### -576, +576,CubeAction=1511 DataAction=1503 CubeLogChanges=0 930,0 638,1 804,0 @@ -516,7 +607,7 @@ EndIf; 917,0 918,1 919,0 -920,0 +920,50000 921,"" 922,"" 923,0