| Introduction | Table description | Main principles | YCOMBD class definition |
| YCOMB class definition | YCOMB representation | YCOMB_CSTD script | YCOMB_RSTD script |
A combined object is made of a unique table containing a key with two components. This table has multiple records that are associated with a given value of the first key component.
In this mode:
While the generation of the CRUD code for this type of object is not automated, objects can be created using the supervisor.
Table "YCOMB [YCO]" has the following structure (technical columns are not listed):
| Column | Type | Description | Place |
|---|---|---|---|
| YGRP | Character 10 | Group | Header |
| YNAM | Character 80 | Group description | Header |
| YSGRP | Character 5 | Group member | Line |
| YTEXT | Character 40 | Member text | Line |
| YDATE | Date | Member Date | Line |
| YNUM | Decimal 9.2 | Member value | Line |
"YCO0" is the unique key of the table. It has no duplicates and it is made of two components: YGRP+YSGRP.
This class has the following characteristics:
As there are no particular controls on this class, there is no script associated with it. However, you can add one if necessary.
This class has the following characteristics:
This representation has the following characteristics:
Both can be found on all facets and can be entered.
All can be found on facets Detail and Edit, and can be entered.
| Header | Read method | Insertion method | Update method |
| Delete method | Subprograms | Events on collection | Events on properties |
The script implements the CRUD method for the combined object. The "YCOMB" class is not persistent, therefore, the AREAD, AINSERT, AUPDATE, and ADELETE events are used. They are located in the script, right after the $METHOD label in case "CURPTH" is empty.
Additionally, events AREAD_AFTER and ADDLINE_AFTER have to be handled on every "YCOMBD" record. When this happens, "CURPTH" is equal to "YCOMBD".
The beginning of the script is as follows:
sh
###############
# METHODS
###############
$METHODS
Case CURPTH
When ""
Case ACTION
When "AREAD" : Gosub AREAD
When "AINSERT" : Gosub AINSERT
When "AUPDATE" : Gosub AUPDATE
When "ADELETE" : Gosub ADELETE
Endcase
When "YCOMBD"
Case ACTION
When "AREAD_AFTER" : Gosub YCOMBD_AREAD_AFTER
When "ADDLINE_AFTER" : Gosub YCOMBD_ADDLINE_AFTER
Endcase
Endcase
Return
The AREAD method performs a reading loop on the "YCOMBD" table. For every existing record, the ADDLINE method is invoked on the "YCOMBD" collection to add a line at the end of the table. The standard AREAD method is then used on the line instance to fill the record. The loop process stops if any error is found. This corresponds to the following code:
sh
$AREAD
Local File YCOMB [YCO]
Local Integer ILINE
For [YCO] Where YGRP=this.YGRP
ILINE = fmet this.ADDLINE("YCOMBD",CST_ALASTPOS)
[L]ASTATUS = fmet this.YCOMBD(ILINE).AREAD([F:YCO]YGRP,[F:YCO]YSGRP)
# The syntax Break condition means that if condition is true (ie 1), a Break 1 is done (Break 0 does nothing)
Break [L]ASTATUS>=[V]CST_AERROR
Next
Return
Consistency checks must be performed on the insertion method:
The corresponding sub-program is CTL_CONSISTENCY.
A loop is performed to insert all of the lines with "CST_ANEW" as the line status. While in insertion mode, the only other status that can be encountered is "CST_ANEWDEL".
In this case, there is no need to make sure this.YCOMBD(ILINE) is not null because the instance collection was created by only adding lines at the end of the table, and because the deletion is exclusively logical.
The code is as follows:
sh
$AINSERT
Local Integer ILINE
# Consistency controls
Gosub CTL_CONSISTENCY : If [L]ASTATUS>=[V]CST_AERROR : Return : Endif
# Loop on every line that has to be created
For ILINE=1 To maxtab(this.YCOMBD)
If this.YCOMBD(ILINE)<>null
If this.YCOMBD(ILINE).ASTALIN = CST_ANEW
[L]ASTATUS = fmet this.YCOMBD(ILINE).AINSERT()
Break ([L]ASTATUS>=[V]CST_AERROR)
Endif
Endif
Next
Return
The same initial control is performed on the update method.
Three loops handle the different modifications that are made on the lines:
The code is as follows:
sh
$AUPDATE
Local Integer ILINE
Gosub CTL_CONSISTENCY : If [L]ASTATUS>=[V]CST_AERROR : Return : Endif
# Delete the lines
For ILINE= 1 To maxtab(this.YCOMBD)
If this.YVOMB(ILINE)<>null
If this.YCOMBD(ILINE).ASTALIN = [V]CST_ADEL
[L]ASTATUS = fmet this.YCOMBD(ILINE).ADELETE()
If [L]ASTATUS>=[V]CST_AERROR : Return : Endif
Endif
Endif
Next
# Update the lines
For ILINE= 1 To maxtab(this.YCOMBD)
If this.YCOMBD(ILINE)<>null
If this.YCOMBD(ILINE).ASTALIN = [V]CST_AUPD
[L]ASTATUS = fmet this.YCOMB(ILINE).AUPDATE()
If [L]ASTATUS>=[V]CST_AERROR : Return : Endif
Endif
Endif
Next
# Insert the lines
For ILINE= 1 To maxtab(this.YCOMBD)
If this.YCOMBD(ILINE)<>null
If this.YCOMBD(ILINE).ASTALIN = [V]CST_ANEW
[L]ASTATUS = fmet this.YCOMBD(ILINE).AINSERT()
Break [L]ASTATUS>=[V]CST_AERROR
Endif
Endif
Next
Return
A loop is initiated on every line that invokes the DELETE method. The loop stops when an error occurs.
The code is as follows:
sh
$ADELETE
Local Integer ILINE
For ILINE= 1 To maxtab(this.YCOMBD)
If this.YCOMBD(ILINE)<>null
[L]ASTATUS = fmet this.YCOMBD(ILINE).ADELETE()
Break [L]ASTATUS>=[V]CST_AERROR
Endif
Next
Return
This subprogram performs a loop on the "YCOMBD" collection. If at least one line is found, "LINE_FOUND" is set to 1. A second loop, concatenated with the first one, checks whether the same "YGRP" value has been used on another line. If this is the case, an error is invoked and the loop is stopped.
The code is as follows:
sh
# Check the consistency
$CTL_CONSISTENCY
Local Shortint LINE_FOUND
Local Integer IL, JL
For IL=1 To maxtab(this.YCOMBD)
If this.YCOMB(IL)<>null
If find(this.YCOMB(IL).ASTALIN,[V]CST_ADEL,[V]CST_ANEWDEL)=0
LINE_FOUND=1
For JL= IL+1 To maxtab(this.YCOMBD)
If this.YCOMB(JL)<>null
If find(this.YCOMB(JL).ASTALIN,[V]CST_ADEL,[V]CST_ANEWDEL)=0
If this.YCOMB(IL).YSGRP= this.YCOMB(JL).YSGRP
[L]ASTATUS = fmet this.ASETERROR("YGRP", this.YCOMB(IL).YSGRP -":"-mess(94,139,1),[V]CST_AERROR)
Break 2
Endif
Endif
Endif
Next JL
Endif
Endif
Next IL
If LINE_FOUND=0
[L]ASTATUS = fmet this.ASETERROR("",mess(178,123,1),[V]CST_AERROR)
Endif
Return
Two events are necessary to properly manage the collection:
This provides the following code:
sh $YCOMB_AREAD_AFTER # Assign ASTALIN to CST_ALL (they have the value 'CST_ANEW' just after AREAD method) this.ASTALIN = [V]CST_ALL Return $YCOMB_ADDLINE_AFTER # To initialize properties of the header this.YGRP = this.APARENT.YGRP this.YNAM = this.APARENT.YNAM Return
The following additional controls must be performed on the properties (after the $PROPERTIES label in the script below):
This provides the following code:
sh
$PROPERTIES
# If YGRP or YNAM have been modified, perform a loop to update all the lines
Case CURPRO
When "YGRP"
Case ACTION
When 'PROPAGATE'
Local Integer IL
For IL= 1 To maxtab(this.YCOMBD)
If this.YCOMBD(IL)<>null
this.YCOMBD(IL).YGRP = this.YGRP
Endif
Next IL
Endcase
When "YNAM"
Case ACTION
When 'PROPAGATE'
Local Integer IL
For IL= 1 To maxtab(this.YCOMBD)
If this.YCOMBD(IL)<>null
this.YCOMBD(IL).YGRP = this.YGRP
Endif
Next IL
Endcase
Endcase
Return
This script manages the list of codes by using a table in memory. The code is as follows:
sh
#########################
# Representation YCOMB
#########################
###############
# METHODS
###############
$METHODS
Case CURPTH
When ""
Case ACTION
When "AQUERY_DECODE_CRITERIA_AFTER" : Gosub AQUERY_DECODE_CRITERIA_AFTER
When "AQUERY_PRIMARYKEYS_AFTER" : Gosub AQUERY_PRIMARYKEYS_AFTER
When "AQUERY_OPEN_AFTER" : Gosub AQUERY_OPEN_AFTER
When "AQUERY_TRANS_AFTER" : Gosub AQUERY_TRANS_AFTER
When "AQUERY_CLOSE_AFTER" : Gosub AQUERY_CLOSE_AFTER
Endcase
Endcase
Return
#################### Standard Query Events #########################
$AQUERY_DECODE_CRITERIA_AFTER
Raz NBPRO
NBPRO += 1
TBPRO(NBPRO) = "YGRP" : TBTYP(NBPRO) = 7 : TBPTH(NBPRO) = "YCOMBH.YGRP" : TBFIL(NBPRO) = "[LNK_]YGRP"
NBPRO += 1
TBPRO(NBPRO) = "YNAM" : TBTYP(NBPRO) = 7 : TBPTH(NBPRO) = "YCOMBH.YNAM" : TBFIL(NBPRO) = "[LNK_]YNAM"
Return
$AQUERY_PRIMARYKEYS_AFTER
ASTDKEY = "[LNK_]YGRP"
Return
$AQUERY_OPEN_AFTER
Local File YCOMB [QRY_YC]
Local Integer I : I=0
Local Char TYGRP(12)(1..), TYNAM(40)(1..)
For [QRY_YC]YCO0(1)
I+=1
TYGRP(I) = [F:QRY_YC]YGRP
TYNAM(I) = [F:QRY_YC]YNAM
Next
# A test must be done on I (this will be fixed later)
# On empty arrays, for behaves as if 32,768 lines were here!
If I<>0
Local File (Char YGRP(100),Char YNAM(100)) From Variable TYGRP,TYNAM As [LNK_]
Else
Local File YCOMB [LNK_]
Endif
Return
$AQUERY_TRANS_AFTER
this.YCOMB.YGRP = [LNK_]YGRP
this.YCOMB.YNAM = [LNK_]YNAM
Return
$AQUERY_CLOSE_AFTER
Close Local File [LNK_]
Return