how to create one VALUELIST from a class parameters ?
Hello everyone!
I have an abstract class representing the possible inputs for an Enum field, in the following way:
Class system.dto.sector.SectorStatusEnum [ Abstract ]{Parameter Active = 1;Parameter Inactive = 2;Parameter Production = 3;Parameter Upkeep = 4;}I need to create a persistent class referencing the abstract class in the status field, so that the result of the operation is the same as the example:
Class datas.TblSector Extends %Persistent{Property Description As %String( MAXLEN = 100 ) [ Required ];Property Status As %String(VALUELIST=",1,2,3,4", DISPLAYLIST=", Active, Inactive, Production, Upkeep") [ Required ];
}Can someone help me pls?
Comments
PARAMETER and DISPLAYLIST are both compiler directives and you can't mix them.
But you may workaround it by writing your own pair of DisplayToLogical / LogicalToDisplay ClassMethods for this property´.
Parameter Active = 1;
Parameter Inactive =2;
Parameter Production = 3;
Parameter Upkeep 4;
/// DISPLAYLIST = ", Active, Inactive, Production, Upkeep",
Property StatusAs %String(VALUELIST = ",1,2,3,4") [ Required ];
ClassMethod StatusDisplayToLogical(%val) As %String
{ Quit $case(%val,..#Active:1,..#Inactive:2,..#Production:3,..#Upkeep:4,:"") }
ClassMethod StatusLogicalToDisplay(%val) As %String
{ Quit $case(%val,1:..#Active,2:..#Inactive,3:..#Production,4:..#Upkeep,:"") }
Is there a function that returns a string or list with all the parameters of the class?
Not as string.
Parameters are stored as sub-object with the class object in %Dictionary.* classes.
And serve as Information for the code to be compiled.
not a built-in, but you can easily create one
ClassMethod ParamList() [ CodeMode = objectgenerator ] As %List
{
set params=""
for i=1:1:%class.Parameters.Count() set params=params_$lb(%class.Parameters.GetAt(i).Name)
do %code.WriteLine($c(9)_"quit """_params_"""")
}
ClassMethod ParamString() As %String
{
quit $listtostring(..ParamList())
}Thanks !
Is possible to use the return of the Method to build the VALUELIST ?
Or other property with the same purpose?
Do I understand you right, you want to get the Value of a VALUELIST as a return value of a method? If yes, then the answer is yes.
Class Some.Class
{
Property Status As %String (VALUELIST = ",1,2,3,4");
Property Rating As %String(VALUELIST = ",Bad,Good,Excellent");
/// For the Status property only
ClassMethod StatusValues() As %String [ CodeMode = objectgenerator ]
{
for i=%class.Properties.Count():-1:0 if i,%class.Properties.GetAt(i).Name="Status" quit
set val=$select(i:%class.Properties.GetAt(i).Parameters.GetAt("VALUELIST"), 1:"")
do %code.WriteLine($c(9)_"quit """_val_"""")
}
/// For all properties with a VALUELIST parameter
ClassMethod Values(prop) [ CodeMode = objectgenerator ]
{
set sel=""
for i=1:1:%class.Properties.Count() {
set val=%class.Properties.GetAt(i).Parameters.GetAt("VALUELIST")
set:val]"" sel=sel_""""_%class.Properties.GetAt(i).Name_""":"""_val_""", "
}
do %code.WriteLine($c(9)_"quit $case(prop,"_sel_":"""")")
}
}
And a few examples...
Write ##class(Some.Class).StatusValues() ==> ,1,2,3
Write ##class(Some.Class).Values("Status") ==> ,1,2,3
Write ##class(Some.Class).Values("Rating") ==> Bad,Good,Excellent
Write ##class(Some.Class).Values("OtherProperty") ==>
Alternatively, %Dictionary package macros can be used:
ClassMethod Values(class = {$classname()}, property) As %Status [ CodeMode = expression]
{
$$$defMemberArrayGet(class,$$$cCLASSproperty,property,$$$cPROPparameter,"VALUELIST")
}Also, you can find object from list without explicitly iterating the whole thing:
set i = %class.Properties.FindObjectId(%class.Name _ "||" _ "Status")instead of:
for i=%class.Properties.Count():-1:0 if i,%class.Properties.GetAt(i).Name="Status" quitHi Davi,
A simplest way is creating a datatype class:
Class system.dto.sector.SectorStatusEnum Extends %Integer [ ClassType = datatype ]{
Parameter DISPLAYLIST = ",Active,Inactive,Production,Upkeep,NewValue";
Parameter VALUELIST = ",1,2,3,4,5";}And use the datatype in your class:
Class system.dto.sector.Test Extends %Persistent{Property SectorStatus As SectorStatusEnum;
}Example:
.png)
Hello everyone !
I thank the help of all!
with everyone's help, it was possible to create a property with the same behavior as VALUE LIST from the parameters of a class.
below is the test code:
First create the abstraction
Class ing.shared.abstracts.AbstractEnum [ Abstract ]{
ClassMethod BuildValueList() As %String{ Set valueList = ","_..GetValuesOfParametersString() Return valueList}
ClassMethod BuildDisplayList() As %String{ Set displayList = ","_..GetParametersString() Return displayList}
ClassMethod GetValuesOfParameters(){ Set parametersList = ..GetParameters() Set valueList= $lb("") For i=1:1:$LISTLENGTH(parametersList){ Set value = $PARAMETER($CLASSNAME(),$LIST(parametersList,i)) Set $LIST(valueList,i) = value } Return valueList}
ClassMethod GetParameters() [ CodeMode = objectgenerator ]{ Set parametersClass="" For i=1:1:%class.Parameters.Count(){ Set parametersClass=parametersClass_$LISTBUILD(%class.Parameters.GetAt(i).Name) } Do %code.WriteLine($char(9)_"Return """_parametersClass_"""")}
ClassMethod GetParametersString() As %String{ Return $listtostring(..GetParameters())}
ClassMethod GetValuesOfParametersString() As %String{ Return $listtostring(..GetValuesOfParameters())}
}Second I created the class with the parameters, containing extension of the abstract class
Class ing.dto.AbstractionItemSectorStatus Extends ing.shared.abstracts.AbstractEnum{Parameter Active = 1;Parameter Inactive = 2;Parameter Production = 3;Parameter Upkeep = 4;}Create a datatype class referencing a parameter class in your property:
Class ing.dataMap.DataTypeSectorStatusEnum Extends %Integer [ ClassType = datatype ]{
Parameter DISPLAYLIST = {##class(ing.dto.AbstractionItemSectorStatus).BuildDisplayList()};
Parameter VALUELIST = {##class(ing.dto.AbstractionItemSectorStatus).BuildValueList()};}And finally create a Persistent class:
Class ing.dataMap.TblSector Extends %Persistent{Property Description As %String;Property SectorStatus As DataTypeSectorStatusEnum;}This architecture can be useful for future code maintenance, creating or changing new abstract classes