Field options can be set at the Data Dictionary Object level. In most cases, changing field options at the object level makes little sense and would not be used. There are some options such as No-Enter, Retain and Retain-All where it is quite useful. In particular, the retain options should almost always be set at the object level.
This section will show the various ways field options can be set at the DD object level. Throughout this section we will use as our sample the retain option. Retain is a good sample choice because it is one of the options that is most likely to only be set within the DDO.
For example, if you had a customer DDO where you wanted to place a retain on City, State and Zip you could do the following:
Object oCustomer_DD is a Customer_DataDictionary
Set Field_Option Field Customer.City DD_RETAIN to True
Set Field_Option Field Customer.State DD_RETAIN to True
Set Field_Option Field Customer.Zip DD_RETAIN to True
End_Object
Masks can be changed within DDOs by setting File_Field_Mask or Field_Mask.
Labels can be changed within DDOs by setting File_Field_Label or Field_label. Labels only are changed if the DEO’s Auto_Label_State is true (usually it is not).
DDO Field Option settings, Mask Setting and Label Settings may be changed dynamically within an object. If one of these properties is changed in a DDO, all DEOs that use that DD will reflect the change. This can be used to dynamically change retains, change masks, change zero suppress in DDOs, make a field no-entry, etc.
For example, the above Customer DDO could toggle the Retain states for City, State and Zip by pressing Ctrl+F4. Adding the following code to your view could do this.
On_key key_Ctrl+Key_F4 Send ToggleRetain
:
Procedure ToggleRetain
Handle hoDDO
Integer iOpt
Move oCustomer_DD to hoDDO
Get Field_Option of hoDDO Field Customer.City DD_RETAIN to iOpt
Set Field_Option of hoDDO Field Customer.City DD_RETAIN to (Not(iOpt))
Get Field_Option of hoDDO Field Customer.State DD_RETAIN to iOpt
Set Field_Option of hoDDO Field Customer.State DD_RETAIN to (Not(iOpt))
Get Field_Option of hoDDO Field Customer.Zip DD_RETAIN to iOpt
Set Field_Option of hoDDO Field Customer.Zip DD_RETAIN to (Not(iOpt))
End_Procedure
Or the following code added to a DEO for Customer.City that would allow you to toggle retains just for this one DEO.
On_key key_Ctrl+Key_F4 Send ToggleRetain
Procedure ToggleRetain
Handle hoDDO
Int iOpt
Get Server to hoDDO
Get File_Field_Option of hoDDO File_Field Customer.City DD_RETAIN to iOpt
Set File_Field_Option of hoDDO File_Field Customer.City DD_RETAIN to (Not(iOpt))
End_Procedure
A more generic version of this which could be applied to a DEO would be:
Procedure ToggleRetain
Integer iFile iField iOpt
Handle hoDDO
Get Server to hoDDO
Get Data_File to iFile
Get Data Field to iField
If (iFile AND hoDDO) begin
Get File_Field_Option of hoDDO iFile iField DD_RETAIN to iOpt
Set File_Field_Option of hoDDO iFile iField DD_RETAIN to (Not(iOpt))
End
End_Procedure
An even more generic version of this is provided below. The following sample code could be added to your view object and would let the user toggle the retain state of any field in the view.
// all objects in this view will send ToggleRetain when
// Ctrl/F4 is pressed.
On_key key_ctrl+key_f4 send ToggleRetain
// When sent from a Ctrl/F4, the message will delegate here to
// the view because ToggleRetain is not directly understood by the
// other objects
Procedure ToggleRetain
Handle hoDEO hoServer
Integer iFile iField iOpt
// we want to react to the focus object. The object where
// ctrl/f4 was pressed
Get Focus to hoDEO
// non deos will understand this message via delegation...see below
Get Data_File of hoDEO to iFile
If (iFile=0) Procedure_Return // probably not a DEO that has the focus
Get Server of hoDEO to hoServer
If (hoServer) Begin
Get Data_Field of hoDEO to iField
Get File_Field_Option of hoServer iFile iField DD_Retain to iOpt
Set File_Field_Option of hoServer iFile iField DD_Retain to (Not(iOpt))
End
End_Procedure
// this augmentation was created to allow non-deos to respond to ctrl/f4
// without an error message. Non-deos will delegate this message to
// here, return 0 and do nothing... look at toggle retain
Function Data_File DESKTOP returns integer
Function_Return 0
End_Function
The Studio’s Data Dictionary Modeler allows you to create default values for fields. For example, the default value for Customer.state is “FL”. These defaults are applied after field values are retained and consequently they will overwrite the value of the retained data. So, normally you would not use retains and defaults on the same field.
You could use both retains and defaults together to create intelligent defaults. Remember that default values are set within the procedure Field_Defaults. You can augment the Field_Defaults method to create custom default values. During that process you can check to see if a value has been retained and respond however you want.
The following code added to the customer DDO would retain the current state value if it exists. If the state is blank or if the state is “CA”, the default “FL” will get used.
Object oCustomer_DD is a Customer_DataDictionary
Set Field_Option Field Customer.State to DD_Retain
Procedure Field_Defaults
String sState
Forward Send Field_Defaults
// get current state value, could be cleared or a retained value
Get Field_Current_Value Field Customer.state to sState
// If state is cleared or it is CA, set a default of FL
If (sState="" or sState="CA") Begin
Set Field_Changed_Value Field Customer.state to "FL"
End
End_Procedure
End_Object
The Field_Defaults method should only be used to set default values for fields from its own DDO. It should not try to change the value of parent or child DDOs and it should not try to perform additional DDO operations (like an auto-find).
We expect you to assign Retains at the object level. Therefore it is up to you to decide if it makes sense to retain fields from parent DDOs. Normally a parent DDO requires an auto-find (see Key Foreign Fields). Therefore retaining any field other than the key-field auto-find field probably makes little sense. Retaining the key field(s) of a parent table may make a great deal of sense.
If you retain a key parent field, the data will be retained but the record will not be found automatically. This is intentional and it gives you two choices. You can either let the auto-find occur when you navigate out of the field or you can force an auto-find as part of the clear operation. We will show you examples of both.
The OrderHea DDO in an order-entry view could define a parent retain as follows:
Object oCustomer_DD is a Customer_DataDictionary
End_Object
Object oOrderHea_DD is a OrderHea_DataDictionary
Set DDO_Server to oCustomer_DD
Set File_Field_Option File_Field Customer.Customer_number to DD_Retain
End_Object
When you clear the order view, the customer ID will be retained but the rest of the customer data will be blank. When you navigate out of the customer-number DEO, an auto-find will occur. This is one way to use retains with parents. It allows the user to select a different customer id before performing the auto-find.
Alternately, your OrderHea DDO could look like this:
Object oCustomer_DD is a Customer_DataDictionary
End_Object
Object oOrderHea_DD is a OrderHea_DataDictionary
Set DDO_Server to oCustomer_DD
Set File_Field_Option File_Field Customer.Customer_number to DD_Retain
// Augment Clear so that it performs an auto-find for the Customer.
// The retained data will be used to perform this auto-find
Procedure Clear
Forward send clear
Send File_Field_Default_Autofind File_Field Customer.Customer_number
End_Procedure
End_Object
Now when you clear the order view, you will see that the entire customer appears to be retained. Actually the key field is retained and then after the clear, an auto-find is performed. The DDO message File_Field_Default_Autofind is used here to perform the auto-find in “default” mode (the DDO’s changed state is not set by the find). Note that you should not try doing an auto-find as part of the Field_Defaults process. The Field_Defaults method can only be used to set defaults for the fields that belong to its DDO and you should never perform database activity (and particularly DDO database activity) within this method.