Thoughts, ideas and solutions from a few EPM consultants.

DRM Enumeration

DRM appears to be going away from the formula engine and toward JavaScript (JS was one of the first languages I learned back in 1996.) Unfortunately I find the documentation to be a bit lacking especially in regards to some of the enumeration. Below I will attempt to make it a little easier to understand.

PropType

The PropType enumerator is used to provide information about the property itself it value does not change regardless of what data is in the property.

EnumeratorValue
PropType.Invalid0
PropType.System1
PropType.Defined2
PropType.Lookup3
PropType.Derived4
PropType.Stats5
PropType.Validation6
PropType.Verification7
PropType.LimbAccessGroup8
PropType.LeafAccessGroup9
PropType.UserSpecific10
PropType.RWDerived11
PropType.SharedInfo12

Example

Core.Descr is a system defined property type. So when running the following code you would see a value of 1. Regardless of the value of the property.

print("PropType: " + node.Prop("Core.Descr").PropType);
if (node.Prop("Core.Descr").PropType = PropType.System) {
    return true;
}
else {
    return false;
}

PropOrign

Unlike PropType, PropOrign describes the value in the property. So if the value in the property is overridden, derived or inherited the value of Orign will be different.

EnumeratorValue
PropOrigin.Default0
PropOrigin.Inherited1
PropOrigin.Overridden2
PropOrigin.InheritedHier3
PropOrigin.InheritedVer4
PropOrigin.Derived5
PropOrigin.InheritedDomain6
PropOrigin.Unknown7

Example

I have a property thats an alternate alias in this property I derive the description using the following code: node.PropValue('Core.Descr') however I have allow this value to be overrideable. Therefore the Origin value changes depending on if the value is derived or I have overriden it.

var prop = node.Prop("Custom.Alias");
if (prop.Origin == PropOrigin.Derived) {
    return 'Derrived!';
}
else if (prop.Origin == PropOrigin.Overridden) {
    return 'Overridden';
}

PropLevel

Like PropType, PropLevel describes the property. Specifically where the property exists (Node, Hierarchy or Version).

EnumeratorValue
PropLevel.Node0
PropLevel.Hier1
PropLevel.Version2

Example

In the example below we will look at three different system properties that exist in different places. Accessing this value was not as intuitive. As I would have expeceted node.Prop("Core.Desc").Level to work but I didn't get a result.

if (node.Prop("Core.EnableSharedNodes").GetPropDef().Level == PropLevel.Hier) {
    print("Core.EnableSharedNodes is a Hierarchy property");
}
if (node.Prop("Core.Descr").GetPropDef().Level == PropLevel.Node) {
    print("Core.Descr is a Node property");
}
if (node.Prop("Core.VersionName").GetPropDef().Level == PropLevel.Version) {
    print("Core.VersionName is a Version property");
}

DataType

Once again DataType is like PropType and PropLevel in that it describes the property. This enumerator defines the type of data (shocking I know).

EnumeratorValue
DataType.Boolean1
DataType.LeafNode2
DataType.Date3
DataType.Time4
DataType.Float5
DataType.Integer6
DataType.Sort7
DataType.Group8
DataType.Node9
DataType.LimbNode10
DataType.String11
DataType.Hier12
DataType.Version13
DataType.ListGroup16
DataType.MultiNode17
DataType.AscNode18
DataType.AscNodes19
DataType.AscGroup20
DataType.Memo21
DataType.FormatMemo22
DataType.SortProp23
DataType.Property24
DataType.Query25
DataType.StdQuery26
DataType.GlobalNode27
DataType.NodeProps28
DataType.RangeList29
DataType.DateTime30
DataType.Hyperlink31
DataType.HierarchyGroup36

Example

Obviously based on the numbering there are a few DataTypes thats are not part of the documentation (11.1.2.3.500) so I encourage you to run the script below to see for yourself.

if (node.Prop("Core.Descr").DataType == DataType.String) {
    print("Core.Descr is a String");
}
print("DataType.Boolean        = " + DataType.Boolean);
print("DataType.LeafNode       = " + DataType.LeafNode);
print("DataType.Date           = " + DataType.Date);
print("DataType.Time           = " + DataType.Time);
print("DataType.Float          = " + DataType.Float);
print("DataType.Integer        = " + DataType.Integer);
print("DataType.Sort           = " + DataType.Sort);
print("DataType.Group          = " + DataType.Group);
print("DataType.Node           = " + DataType.Node);
print("DataType.LimbNode       = " + DataType.LimbNode);
print("DataType.String         = " + DataType.String);
print("DataType.Hier           = " + DataType.Hier);
print("DataType.Version        = " + DataType.Version);
print("DataType.ListGroup      = " + DataType.ListGroup);
print("DataType.MultiNode      = " + DataType.MultiNode);
print("DataType.AscNode        = " + DataType.AscNode);
print("DataType.AscNodes       = " + DataType.AscNodes);
print("DataType.AscGroup       = " + DataType.AscGroup);
print("DataType.Memo           = " + DataType.Memo);
print("DataType.FormatMemo     = " + DataType.FormatMemo);
print("DataType.SortProp       = " + DataType.SortProp);
print("DataType.Property       = " + DataType.Property);
print("DataType.Query          = " + DataType.Query);
print("DataType.StdQuery       = " + DataType.StdQuery);
print("DataType.GlobalNode     = " + DataType.GlobalNode);
print("DataType.NodeProps      = " + DataType.NodeProps);
print("DataType.RangeList      = " + DataType.RangeList);
print("DataType.DateTime       = " + DataType.DateTime);
print("DataType.Hyperlink      = " + DataType.Hyperlink);
print("DataType.HierarchyGroup = " + DataType.HierarchyGroup);