Eventually got my code working.
Did not need a recursive procedure after all. Apologies to Ankur for saying his code did not cope with more levels than 2 - once I looked at it I saw it was fine.
Here is the code FYI with no warranty etc.
Prolog of proc1 - based on Wim Gelis' dimension copier - thanks Wim
Code: Select all
IF(LONG(pDimensionNew)=0);
pDimensionNew=pDimensionOld | '_Copy';
ENDIF;
# this does not work because of various commit problems. You will have to delete new dimension manually in UI or it may require an alldatasave to be e
xecuted.
# deleting the dimension from the UI cascades remova of the attributes but programmatically both have to be removed explicitly.
CubeDestroy('}ElementAttributes_' | pDimensionNew);
DimensionDestroy('}ElementAttributes_' | pDimensionNew);
DimensionDestroy(pDimensionNew);
IF ( DIMENSIONEXISTS(pDimensionOld) = 0 ) ;
asciioutput('c:\prolog.txt','Old dimension does not exist' ) ;
PROCESSQUIT;
ENDIF;
# old dimension must have attributes - should also check attribute exists
IF ( DIMENSIONEXISTS('}ElementAttributes_' | pDimensionOld) <>1 ) ;
asciioutput('c:\prolog.txt','Old dimension has no attributes' ) ;
PROCESSQUIT;
ENDIF ;
# loop through attributes to check if we have alias
j=1;
vFoundAliasOld = 0 ;
WHILE (j<=DIMSIZ('}ElementAttributes_'|pDimensionOld));
vAttributeName=DIMNM('}ElementAttributes_' | pDimensionOld,j);
vAttributeType=SUBST(DTYPE('}ElementAttributes_'|pDimensionOld, vAttributeName),2,1);
# insert attribute itself but we replace the old alias with the new
IF (vAttributeName @= pDimensionOldAlias & vAttributeType @= 'A' );
vFoundAliasOld = 1 ;
ENDIF ;
j = j + 1 ;
END ;
# old dimension must have attributes - should also check attribute exists
IF ( vFoundAliasOld <>1 ) ;
asciioutput('c:\prolog.txt','Old dimension does not have Alias=' | pDimensionOldAlias ) ;
PROCESSQUIT;
ENDIF ;
# Use this for testing. NB no sort order for new dimension will be set it will be set to manual
# DimensionSortOrder(pDimensionOld, 'ByName', 'Ascending', 'ByLevel' , 'Ascending');
DIMENSIONCREATE(pDimensionNew);
# loop through the elements of the original dimension
# to copy to the new dimension
i=1;
relationcount = 0 ;
hierarchycount = 0 ;
WHILE(i<=DIMSIZ(pDimensionOld));
# CHILD
vChildElement=DIMNM(pDimensionOld,i);
vChildType=DTYPE(pDimensionOld,vChildElement);
vChildAlias = ATTRS (pDimensionOld, vChildElement, pDimensionOldAlias );
# if the default value of the alias (same as element) is not overridden it is stored as an empty string so set it to the element
IF (vChildAlias @= '' ) ;
vChildAlias = vChildElement ;
ENDIF ;
vChildLevel = ELLEV(pDimensionOld, vChildElement) ;
asciioutput('c:\prolog.txt',numbertostring(i) | ' Child Element ' | ' Level=' | numbertostring(vChildLevel) | ' Type=' | vChildType | ' [' | vChil
dElement | '] Replaced with [' | vChildAlias | ']' ) ;
DIMENSIONELEMENTINSERT(pDimensionNew,'',vChildAlias,vChildType);
# PARENT (loop through them)
j=1;
parentcount = ELPARN(pDimensionOld,vChildElement) ;
IF (parentcount = 0 ) ;
hierarchycount = hierarchycount + 1 ;
asciioutput('c:\prolog.txt','%%% Hierarchy Start #' | numbertostring(hierarchycount) | ' [' | vChildElement | '] / [' | vChil
dAlias | '] level=' | numbertostring(vChildLevel) | ' Type=' | vChildType) ;
ENDIF ;
WHILE( j <= parentcount );
vParentElement = ELPAR(pDimensionOld,vChildElement,j);
vChildWeight = ELWEIGHT(pDimensionOld,vParentElement,vChildElement);
vParentAlias = ATTRS(pDimensionOld, vParentElement, pDimensionOldAlias );
# if the default value of the alias (same as element) is not overridden it is stored as an empty string so set it to the element
IF (vParentAlias @= '' ) ;
vParentAlias = vParentElement ;
ENDIF ;
asciioutput('c:\prolog.txt',' --- Parent Element #' | numbertostring(j) | ' [' | vParentElement | '] Replaced with [' | vParentAlias | ']' ) ;
DIMENSIONELEMENTINSERT(pDimensionNew,'',vParentAlias,'C');
relationcount = relationcount + 1 ;
asciioutput('c:\prolog.txt',' ------ Parent/Child rel #' | numbertostring(relationcount) | ' [' | vParentAlias | '] / [' | vChildAlias | ']') ;
DIMENSIONELEMENTCOMPONENTADD(pDimensionNew,vParentAlias,vChildAlias,vChildWeight);
j=j+1;
END;
i=i+1;
END;
and the epilog which copies the attributes
Code: Select all
# loop through attributes
vAttributeCount = DIMSIZ('}ElementAttributes_'|pDimensionOld);
asciioutput('c:\epilog.txt','Count of Attributes to be processed ' | numbertostring(vAttributeCount) ) ;
j=1;
WHILE (j<= vAttributeCount);
# process attributes in reverse order so they have the same order as original
vAttributeName=DIMNM('}ElementAttributes_' | pDimensionOld,vAttributeCount - j + 1 );
vAttributeType=SUBST(DTYPE('}ElementAttributes_'|pDimensionOld, vAttributeName),2,1);
# insert attribute itself but we replace the old alias with the new
IF (vAttributeName @= pDimensionOldAlias);
asciioutput('c:\epilog.txt','+++ Creating alias ' | pDimensionNewAlias | ' Type A' ) ;
ATTRINSERT(pDimensionNew,'',pDimensionNewAlias,'A');
ELSE ;
asciioutput('c:\epilog.txt','+++ Creating alias ' | vAttributeName | ' Type ' | vAttributeType ) ;
ATTRINSERT(pDimensionNew,'',vAttributeName, vAttributeType);
ENDIF ;
i=1;
WHILE (i<=DIMSIZ(pDimensionNew));
# nb both dimensions will not have the same order - see note about sorting
vElementNew=DIMNM(pDimensionNew,i);
# use the alias to find the old element
vElementOld=DimensionElementPrincipalName( pDimensionOld, vElementNew ) ;
# update attribute values for the element
IF(vAttributeType@='N');
vNumericAliasOld = ATTRN(pDimensionOld,vElementOld,vAttributeName) ;
asciioutput('c:\epilog.txt',numbertostring(i) | ' Type=N [' | numbertostring(vNumericAliasOld) | '] for Element [' | vElementNew | ']' ) ;
ATTRPUTN(vNumericAliasOld,pDimensionNew,vElementNew,vAttributeName);
ELSE;
IF (vAttributeName @= pDimensionOldAlias);
vAliasOld = vElementOld ;
asciioutput('c:\epilog.txt',numbertostring(i) | ' Type=' | vAttributeType | ' [' | vAliasOld | '] for Element [' | vElementNew | ']' ) ;
ATTRPUTS(vAliasOld,pDimensionNew,vElementNew,pDimensionNewAlias);
ELSE ;
vAliasOld = ATTRS(pDimensionOld,vElementOld,vAttributeName) ;
asciioutput('c:\epilog.txt',numbertostring(i) | ' Type=' | vAttributeType | ' [' | vAliasOld | '] for Element [' | vElementNew | ']' ) ;
ATTRPUTS(vAliasOld,pDimensionNew,vElementNew,vAttributeName);
ENDIF ;
ENDIF;
i=i+1;
END;
j=j+1;
END;
Finally this recreates the non MDX subsets
Code: Select all
Pathname = pDimensionOld | '}subs\*.sub' ;
PriorFileName = '' ;
SubsetNameOld = WildcardFileSearch( Pathname, PriorFilename);
PriorFileName = SubsetNameOld ;
i = 1 ;
WHILE (PriorFileName @<> '' ) ;
#
IF (SCAN('$',SubsetNameOld) = LONG( SubsetNameOld) ) ;
asciioutput('c:\prolog.txt','+++ MDX based subset cannot be copied automatically [' | SubsetNameOld | ']') ;
ELSE ;
SubsetOld = SUBST(SubsetNameOld,1,LONG( SubsetNameOld) - 4 ) ;
asciioutput('c:\prolog.txt','+++ [' | SubsetOld | ']') ;
SubsetOldSize = SubsetGetSize(pDimensionOld, SubsetOld);
SubsetDestroy(pDimensionNew, SubsetOld);
SubsetCreate(pDimensionNew, SubsetOld);
j = 1 ;
WHILE ( j <= SubsetOldSize ) ;
SubsetOldElement = SubsetGetElementName(pDimensionOld, SubsetOld, j);
asciioutput('c:\prolog.txt','Element ' | SubsetOldElement ) ;
SubsetOldAlias = ATTRS (pDimensionOld, SubsetOldElement , pDimensionOldAlias );
# if the default value of the alias (same as element) is not overridden it is stored as an empty string so set it to the element
IF (SubsetOldAlias @= '' ) ;
SubsetOldAlias = SubsetOldElement ;
ENDIF ;
asciioutput('c:\prolog.txt','Alias ' | SubsetOldAlias ) ;
SubsetElementInsert(pDimensionNew, SubsetOld, SubsetOldAlias, j);
j = j + 1 ;
IF ( j > 10000 ) ;
PROCESSQUIT ;
ENDIF ;
END ;
#
ENDIF ;
SubsetNameOld = WildcardFileSearch( Pathname, PriorFilename);
PriorFileName = SubsetNameOld ;
# safety feature
i = i + 1 ;
IF ( i > 1000 ) ;
PROCESSQUIT ;
ENDIF ;
END ;