Having a created a dynamic picklist for Department, it is not unreasonable that a picklist might also be required for Section and subsequently employee.
The code following can be used for Section. As with the previous example, the Load method populates the picklist. However, as Section needs to be linked to Deptment at run time the reusable part also implements iMonitorSubject.
Function Options(*DIRECT)
Begin_Com Role(*EXTENDS #PRIM_OBJT *implements #Prim_dc.iDynamicPicklist #Prim_dc.iMonitorSubject)
Mthroutine Name(Load) Options(*redefine)
#Picklist.RemoveAll
Select Fields(*all) From_File(Sectab) With_Key(#Deptment)
#Picklist.Add( #Section #Secdesc )
Endselect
Endroutine
Mthroutine Name(ApplyMonitoredValue) Options(*Redefine)
#Deptment := #MonitorSubject.GetValue
Endroutine
End_Com
The form following makes use of both the Deptment and Section visualizations. A monitor is defined with a source of Deptment and a target of Section. When Deptment changes, the ApplyMonitorValue method in the Section visualization is run. A reference to the source object is received allowing the GetValue method to be called to obtain the value.
Immediately after the ApplyMonitorValue has finished, the Load method will be run.
Function Options(*DIRECT)
Begin_Com Role(*EXTENDS #PRIM_FORM) Clientheight(304) Clientwidth(589) Left(277) Top(135) Width(605)
Define_Com Class(#Deptment.VisualPicklist) Name(#Deptment) Displayposition(1) Left(8) Parent(#COM_OWNER) Tabposition(1) Top(8) Width(401)
Define_Com Class(#Section.VisualPicklist) Name(#Section) Displayposition(2) Left(8) Parent(#COM_OWNER) Tabposition(2) Top(32) Width(401)
Define_Com Class(#prim_lm) Name(#DepartmentSection) Source(#Deptment) Target(#Section)
Evtroutine Handling(#Deptment.Changed)
* Ensure the Section is valid after a department change
#Section := *null
Select Fields(#Section) From_File(sectab) With_Key(#Deptment)
Leave
Endselect
Endroutine
End_Com
Note how it is still necessary to ensure that the variable values in the form are maintained. When Deptment changes the user must ensure that section is changed to a reasonable value, in this case, the first section in the table for the new department value.
The code following is for a dynamic picklist for EMPNO.
Function Options(*DIRECT)
Begin_Com Role(*EXTENDS #PRIM_OBJT *implements #Prim_dc.iDynamicPicklist #Prim_dc.iMonitorSubject)
Mthroutine Name(Load) Options(*redefine)
#Picklist.RemoveAll
Select Fields(*all) From_File(pslmst1) With_Key(#Deptment #Section)
#Picklist.Add( #Empno ("&1 &2 (&3)").Substitute( #Givename #Surname #Empno ) )
Endselect
Endroutine
Mthroutine Name(ApplyMonitoredValue) Options(*Redefine)
Case ((#MonitorSubject *As #Prim_objt).ComponentPatternName)
When (= Deptment)
#Deptment := #MonitorSubject.GetValue
When (= Section)
#Section := #MonitorSubject.GetValue
Endcase
Endroutine
End_Com
This is much the same, in concept, as the code for section. However, note the change to ApplyMonitorValue. Empno needs to know the value of both Deptment and Section. As the iMonitorSubject received is a reference to the source component, you can use the ComponentPatternName to determine which variable has been changed.
Note that the ComponentPatternName will return the field identifier, so please take care when using this code for fields with names longer than 9 characters, or if the Identifer is different to the Field Name.
If Empno is then added to the form, as following, a further two monitors are required to inform Empno of changes to Deptment and Section.
Function Options(*DIRECT)
Begin_Com Role(*EXTENDS #PRIM_FORM) Clientheight(304) Clientwidth(589) Left(277) Top(135) Width(605)
Define_Com Class(#Deptment.VisualPicklist) Name(#Deptment) Displayposition(1) Left(8) Parent(#COM_OWNER) Tabposition(1) Top(8) Width(401)
Define_Com Class(#Section.VisualPicklist) Name(#Section) Displayposition(2) Left(8) Parent(#COM_OWNER) Tabposition(2) Top(32) Width(401)
Define_Com Class(#EMPNO.VisualPicklist) Name(#Empno) Displayposition(3) Left(8) Parent(#COM_OWNER) Tabposition(3) Top(56) Width(401)
Define_Com Class(#prim_lm) Name(#DepartmentSection) Source(#Deptment) Target(#Section)
Define_Com Class(#prim_lm) Name(#SectionEmployee) Source(#Section) Target(#Empno)
Define_Com Class(#prim_lm) Name(#DepartmentEmployee) Source(#Deptment) Target(#Empno)
Evtroutine Handling(#Deptment.Changed)
* Ensure the Section and Empno are valid after a department change
#Com_owner.GetDefaultSection
#Com_owner.GetDefaultEmpno
Endroutine
Evtroutine Handling(#Section.Changed)
* Ensure the Empno is valid after a department change
#Com_owner.GetDefaultEmpno
Endroutine
Mthroutine Name(GetDefaultSection) Access(*private)
#Section := *null
Select Fields(#Section) From_File(sectab) With_Key(#Deptment)
Leave
Endselect
Endroutine
Mthroutine Name(GetDefaultEmpno) Access(*private)
#Empno := *null
Select Fields(#Empno) From_File(pslmst1) With_Key(#Deptment #Section)
Leave
Endselect
Endroutine
End_Com