You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 2 Next »

Sorted array collections are a dynamically sized, sorted collection of components that can be located by indexing. Indexing is always relative to 1.
In this example a form invokes a reusable part that returns a an array collection that has been sorted into the order you requested.  The example also uses an employee reusable part which is used to store employee details.
Type in the name of the field on which you want the list sorted and then click the "Get List" Push button to display the sorted list. The fields you can sort by are EMPNO, SURNAME, GIVENAME, POSTCODE, SALARY, and DEPTMENT.

Define the Collection and Adding Items to It
A sorted array collection is defined In the reusable part used to sort the employees. Employee details are retrieved from file PSLMST,  #SortedEmployee objects are created based on the #Employee object and assigned the retrieved employee details. The collection is then filled with the #SortedEmployee objects:
Set_Ref Com(#SortedEmployeeList) To(*Create_as #Prim_SACO<#Employee>)
Select Fields(#EMPNO #GIVENAME #SURNAME #DEPTMENT #SALARY #POSTCODE) From_File(PSLMST)
Set_Ref Com(#SortedEmployee) To(*Create_as #Employee)
Set Com(#SortedEmployee) Pempno(#Empno) Pgivename(#GiveName) Psurname(#Surname) Psalary(#Salary) Pdepartment(#Deptment) Ppostcode(#PostCode)
Invoke Method(#SortedEmployeeList.Insert) Item(#SortedEmployee)
Endselect
As every item is added to the collection, the Compare event is triggered. This event is used to provide the logic for sorting the collection. #ObjectEmployee and #SubjectEmployee objects are created to be used as the Object and #Subject parameters to compare the employees:
Evtroutine Handling(#SortedEmployeeList.Compare) Object(#Object) Subject(#Subject) Result(#Result)
Define_Com Class(#Employee) Name(#ObjectEmployee) Reference(*Dynamic)
Define_Com Class(#Employee) Name(#SubjectEmployee) Reference(*Dynamic)

  • Cast the object and subject objects to the Employee object
    Set_Ref Com(#ObjectEmployee) To(*Dynamic #Object)
    Set_Ref Com(#SubjectEmployee) To(*Dynamic #Subject)
  • Now compare the objects based on the current #R_OrderBy value
    Case Of_Field(#R_ORDERBY)
    When Value_Is('= GiveName')
    Invoke Method(#Com_Owner.CompareAlpha) Object(#ObjectEmployee.pGiveName) Subject(#SubjectEmployee.pGiveName) Result(#Result)
    When Value_Is('= Surname')
    Invoke Method(#Com_Owner.CompareAlpha) Object(#ObjectEmployee.pSurName) Subject(#SubjectEmployee.pSurName) Result(#Result)
    When Value_Is('= Deptment')
    Invoke Method(#Com_Owner.CompareAlpha) Object(#ObjectEmployee.pDepartment) Subject(#SubjectEmployee.pDepartment) Result(#Result)
    When Value_Is('= Salary')
    Invoke Method(#Com_Owner.CompareNumeric) Object(#ObjectEmployee.pSalary) Subject(#SubjectEmployee.pSalary) Result(#Result)
    When Value_Is('= PostCode')
    Invoke Method(#Com_Owner.CompareNumeric) Object(#ObjectEmployee.pPostCode) Subject(#SubjectEmployee.pPostCode) Result(#Result)
    Otherwise
    Invoke Method(#Com_Owner.CompareAlpha) Object(#ObjectEmployee.pEmpNo) Subject(#SubjectEmployee.pEmpNo) Result(#Result)
    Endcase
    Endroutine
    Retrieve the Items in the Collection
    The form retrieves the values in the sorted collection by defining a reference to the employee list and then invoking the method in the reusable part to get the employees.
    Define_Com Class(#Prim_SACO<#Employee>) Name(#ReturnedList) Reference(*Dynamic)
    Invoke Method(#LCOL00002.GetEmployees) Employeelist(#ReturnedList) Orderby(#Sort_By_Field)
    The collection is iterated through to add the entries to the visible #Emp_List:
     
    For Each(#EmployeeObject) In(#ReturnedList)
    Change Field(#EMPNO) To('#EMPLOYEEOBJECT.PEMPNO')
    Change Field(#GIVENAME) To('#EMPLOYEEOBJECT.PGIVENAME')
    Change Field(#SURNAME) To('#EMPLOYEEOBJECT.PSURNAME')
    Change Field(#POSTCODE) To('#EMPLOYEEOBJECT.PPOSTCODE')
    Change Field(#DEPTMENT) To('#EMPLOYEEOBJECT.PDEPARTMENT')
    Change Field(#SALARY) To('#EMPLOYEEOBJECT.PSALARY')
    Add_Entry To_List(#EMP_LIST)
    Endfor
    Source for Sorted Array Collection Example
    Employee Object
    Create this object as a reusable part. In this example it is named #Employee.
    Function Options(*DIRECT)
    Begin_Com Role(*EXTENDS #PRIM_OBJT)
  • ----------------------------
  • This is an "Employee" object
  • ----------------------------
  • Define the member variables that define an "Employee" object ....
    Define_Com Class(#Empno)
    Define_Com Class(#GiveName)
    Define_Com Class(#SurName)
    Define_Com Class(#Deptment)
    Define_Com Class(#Salary)
    Define_Com Class(#PostCode)
  • Publish the properties that an "Employee" exposes .....
    Define_Pty Name(pEmpno) Get(*Auto #Empno) Set(*Auto #Empno)
    Define_Pty Name(pGiveName) Get(*Auto #GiveName) Set(*Auto #GiveName)
    Define_Pty Name(pSurName) Get(*Auto #SurName) Set(*Auto #SurName)
    Define_Pty Name(pDepartment) Get(*Auto #Deptment) Set(*Auto #Deptment)
    Define_Pty Name(pSalary) Get(*Auto #Salary) Set(*Auto #Salary)
    Define_Pty Name(pPostCode) Get(*Auto #PostCode) Set(*Auto #PostCode)
    End_Com
    Reusable Part For Sorting The List
    In this example this component is named #LCOL00002.
    Function Options(*DIRECT)
    Begin_Com Role(*EXTENDS #PRIM_OBJT)
    Define_Com Class(#Prim_SACO<#Employee>) Name(#SortedEmployeeList) Reference(*Dynamic)
    Define Field(#R_ORDERBY) Reffld(#STD_TEXTS)
  • This method is passed an OrderBy() parameter set to EMPNO, SURNAME, GIVENAME,
  • SALARY, DEPTMENT or ZIPCODE. It extracts a list of all employees in the PSLMST
  • table and returns their details as a sorted array colelction of employee objects.
    Mthroutine Name(GetEmployees)
    Define_Map For(*Output) Class(#Prim_SACO<#Employee>) Name(#EmployeeList) Pass(*By_Reference)
    Define_Map For(*input) Class(#Std_Texts) Name(#OrderBy)
  • Define an Employee object reference
    Define_Com Class(#Employee) Name(#SortedEmployee) Reference(*Dynamic)
  • Make the requested order by parameter visible to the #SortEmployeeList.Compare routine
    Change Field(#R_ORDERBY) To('#ORDERBY.VALUE')
  • Dynamically create a new sorted array list to contain the employee objects
    Set_Ref Com(#SortedEmployeeList) To(*Create_as #Prim_SACO<#Employee>)
  • Fill the sorted array collection list with employee objects
    Select Fields(#EMPNO #GIVENAME #SURNAME #DEPTMENT #SALARY #POSTCODE) From_File(PSLMST)
    Set_Ref Com(#SortedEmployee) To(*Create_as #Employee)
    Set Com(#SortedEmployee) Pempno(#Empno) Pgivename(#GiveName) Psurname(#Surname) Psalary(#Salary) Pdepartment(#Deptment) Ppostcode(#PostCode)
    Invoke Method(#SortedEmployeeList.Insert) Item(#SortedEmployee)
    Endselect
  • Return a refernence to the list that was created
    Set_Ref Com(#EmployeeList) To(#SortedEmployeeList)
  • Drop the reference in this component as this list is finished with
    Set_Ref Com(#SortedEmployeeList) To(*null)
    Endroutine
  • This routine is invoked to compare the employees in #SortEmployeeList as they are added
  • by the GetEmployees method above.
    Evtroutine Handling(#SortedEmployeeList.Compare) Object(#Object) Subject(#Subject) Result(#Result)
    Define_Com Class(#Employee) Name(#ObjectEmployee) Reference(*Dynamic)
    Define_Com Class(#Employee) Name(#SubjectEmployee) Reference(*Dynamic)
  • Cast the object and subject objects to the Employee object
    Set_Ref Com(#ObjectEmployee) To(*Dynamic #Object)
    Set_Ref Com(#SubjectEmployee) To(*Dynamic #Subject)
  • Now compare the objects based on the current #R_OrderBy value
    Case Of_Field(#R_ORDERBY)
    When Value_Is('= GiveName')
    Invoke Method(#Com_Owner.CompareAlpha) Object(#ObjectEmployee.pGiveName) Subject(#SubjectEmployee.pGiveName) Result(#Result)
    When Value_Is('= Surname')
    Invoke Method(#Com_Owner.CompareAlpha) Object(#ObjectEmployee.pSurName) Subject(#SubjectEmployee.pSurName) Result(#Result)
    When Value_Is('= Deptment')
    Invoke Method(#Com_Owner.CompareAlpha) Object(#ObjectEmployee.pDepartment) Subject(#SubjectEmployee.pDepartment) Result(#Result)
    When Value_Is('= Salary')
    Invoke Method(#Com_Owner.CompareNumeric) Object(#ObjectEmployee.pSalary) Subject(#SubjectEmployee.pSalary) Result(#Result)
    When Value_Is('= PostCode')
    Invoke Method(#Com_Owner.CompareNumeric) Object(#ObjectEmployee.pPostCode) Subject(#SubjectEmployee.pPostCode) Result(#Result)
    Otherwise
    Invoke Method(#Com_Owner.CompareAlpha) Object(#ObjectEmployee.pEmpNo) Subject(#SubjectEmployee.pEmpNo) Result(#Result)
    Endcase
    Endroutine
  • Alpha compare routine
    Mthroutine Name(CompareAlpha)
    Define_Map For(*input) Class(#Std_TextL) Name(#Object)
    Define_Map For(*input) Class(#Std_TextL) Name(#Subject)
    Define_Map For(*output) Class(#Std_Texts) Name(#Result)
    If Cond('#Subject.Value < #Object.Value')
    Set Com(#Result) Value(Less)
    Else
    If Cond('#Subject.Value > #Object.Value')
    Set Com(#Result) Value(Greater)
    Else
    Set Com(#Result) Value(Equal)
    Endif
    Endif
    Endroutine
  • Numeric compare routine
    Mthroutine Name(CompareNumeric)
    Define_Map For(*input) Class(#dem_dptot) Name(#Object)
    Define_Map For(*input) Class(#dem_dptot) Name(#Subject)
    Define_Map For(*output) Class(#Std_Texts) Name(#Result)
    If Cond('#Subject.Value < #Object.Value')
    Set Com(#Result) Value(Less)
    Else
    If Cond('#Subject.Value > #Object.Value')
    Set Com(#Result) Value(Greater)
    Else
    Set Com(#Result) Value(Equal)
    Endif
    Endif
    Endroutine
    End_Com
    The Form
    Function Options(*DIRECT)
    Begin_Com Role(*EXTENDS #PRIM_FORM) Clientheight(330) Clientwidth(657) Height(357) Left(219) Top(173) Visualstyle(#VS_NORM) Width(665)
  • Define the component that returns the sorted employee number list
    Define_Com Class(#PRIM_LTVW) Name(#Emp_LIst) Componentversion(1) Displayposition(1) Fullrowselect(True) Height(233) Left(27) Parent(#COM_OWNER) Showsortarrow(True) Tabposition(1) Top(72) Width(606)
    Define_Com Class(#PRIM_LVCL) Name(#LVCL_1) Displayposition(1) Parent(#Emp_LIst) Source(#EMPNO) Width(12)
    Define_Com Class(#PRIM_LVCL) Name(#LVCL_2) Displayposition(2) Parent(#Emp_LIst) Source(#SURNAME) Width(20)
    Define_Com Class(#PRIM_LVCL) Name(#LVCL_3) Displayposition(3) Parent(#Emp_LIst) Source(#GIVENAME) Width(20)
    Define_Com Class(#PRIM_LVCL) Name(#LVCL_4) Displayposition(4) Parent(#Emp_LIst) Source(#POSTCODE) Width(20)
    Define_Com Class(#PRIM_LVCL) Name(#LVCL_5) Displayposition(5) Parent(#Emp_LIst) Source(#SALARY) Width(20)
    Define_Com Class(#PRIM_LVCL) Name(#LVCL_6) Displayposition(6) Parent(#Emp_LIst) Source(#DEPTMENT) Width(20) Widthtype(Remainder)
    Define_Com Class(#STD_OBJ.Visual) Name(#Sort_By_Field) Caption('Get List Sorted by Field Named') Displayposition(2) Height(19) Labeltype(Caption) Left(24) Parent(#COM_OWNER) Tabposition(2) Top(24) Width(233)
    Define_Com Class(#PRIM_PHBN) Name(#PHBN_Get_List) Caption('Get List') Displayposition(3) Left(272) Parent(#COM_OWNER) Tabposition(3) Top(24)
  • Define the component that builds the sorted employee lists
  • (in this example it is called #LCOL00002, change it to the name you have
  • given to the reusable part)
    Define_Com Class(#LCOL00002)
  • Handle form initialization
    Evtroutine Handling(#com_owner.Initialize)
    Set Com(#Sort_By_Field) Value(SALARY)
    Endroutine
    Evtroutine Handling(#PHBN_Get_List.Click)
  • Define a reference to the employee list that will be returned
    Define_Com Class(#Prim_SACO<#Employee>) Name(#ReturnedList) Reference(*Dynamic)
  • Invoke the method that returns the sorted list of employees
    Invoke Method(#LCOL00002.GetEmployees) Employeelist(#ReturnedList) Orderby(#Sort_By_Field)
  • Now go through the returned list and add the entries to the visible #Emp_List
    Clr_List Named(#EMP_LIST)
    For Each(#EmployeeObject) In(#ReturnedList)
    Change Field(#EMPNO) To('#EMPLOYEEOBJECT.PEMPNO')
    Change Field(#GIVENAME) To('#EMPLOYEEOBJECT.PGIVENAME')
    Change Field(#SURNAME) To('#EMPLOYEEOBJECT.PSURNAME')
    Change Field(#POSTCODE) To('#EMPLOYEEOBJECT.PPOSTCODE')
    Change Field(#DEPTMENT) To('#EMPLOYEEOBJECT.PDEPARTMENT')
    Change Field(#SALARY) To('#EMPLOYEEOBJECT.PSALARY')
    Add_Entry To_List(#EMP_LIST)
    Endfor
    Endroutine
    End_Com

  • No labels