CDS037

Display/Select Records

Last Revised: 01/05/22

This program can be called to display records from a data file.  Each record is displayed on one row.  The display can include data from the main file, from one or more related files, and from other called programs.  The records are displayed in a grid with graphical lines separating columns.  The user can move up, down, left, right, to the first and last rows, and in some cases, jump to a position within the file.  CDS037 can also be used to return an operator selected record from the list of records displayed, or to call an external program to process the selected record, then return to the record selection display.

The records are displayed in a window which is created and popped by CDS037.  You can specify a fixed window size and position, or allow CDS037 to assume defaults.

CDS037 is called in several places by various Dynamo Tool components and applications:

Calling Format:

CALL "CDS037",FILENAME$ {,KNO, KEYPFX$, DISP$, WINX, WINY, WINROWS, WINCOLS, WINTITLE$, COLORS$, SELRTN$, WHERE$, SORTBY$, S037$, LIMITVAL, SELREC$}

CDS037 uses either the KNO and KEYPFX$ with an OPEN () or WHERE$, SORTBY$, MODE$, and LIMIT with SELECT().  If none of the SELECT arguments are specified then the KNO and KEYPFX$ will be used.  Otherwise they are ignored.

CDS037 Arguments
FILENAME$ the only required parameter and is the primary file to be displayed.  See Example 1.  A template must exist for this file.  The file may be MKY, SKY, or DIR.  It may also be IND if used with the WHERE$, SORTBY$, MODE$, or LIMIT options.
KNO applies to MKY files only and controls the sequence that the data will be displayed when WHERE$, SORTBY$, and MODE$ are null, and LIMITVAL is zero.  If not passed to CDS037, then KNO zero will be assumed.  See Example 4.
KEYPFX$ may be null or indicate the starting characters of the keys to be displayed.  If KEYPFX$ is passed to CDS037, only keys that begin with the KEYPFX$ characters will be displayed.
DISP$ DISP$ may be used to indicate the columns to be displayed.  If not passed to CDS037, or passed as null, then all fields in the template for FILENAME$ will be displayed in the same order as contained in the template.

If DISP$ is passed to CDS037, it contains the field names and optional formatting details.  In the most basic form DISP$ contains the field names to be displayed separated by the pipe (|) character.  The trailing pipe is optional.

"CUSTNO|NAME|ADDRESS|CITY|STATE|ZIP" would be a valid DISP$See Example 2.

Following each field name, you may specify additional positional arguments separated by back slash (\).  The complete format for each field is: FILPGM.FIELD[INDEX]\Title\Mask.

DISP$ Options

FILPGM.If present, FILPGM indicates the file name for a related field, or a program name to call.  When specified, separate from the FIELD with a period.  If the first two characters are XX, they will be replaced with Y.COMPCODE$.  See Using Related Files and Using Called Routines for additional details.  See Example 3.
FIELDTemplated field name.  Not case-sensitive.  Only segment of DISP$ that is required.  Can also be * indicating all fields in FILPGM.

FIELD can also contain any of the following special names:

_CHG%(TOCOL,FROMCOL)Used to compute percent change between two values.  TOCOL is the sequential field# in DISP$ representing the final value with 1 being the first field in DISP$FROMCOL is the sequential field# in DISP$ representing the original value.  You can also omit the (TOCOL,FROMCOL) in which case the last two columns will be used.  Default values will be assigned to TITLE and MASK if not specified.
_GM(SALES,COST)Used to compute gross margin, i.e., sales minus cost.  If SALES and COST are specified, they refer to the sequential column number in DISP$ for the sales and cost.  If not specified, then it is assumed that the two columns to the left contain the sales and cost.  Default values will be assigned to TITLE and MASK if not specified.
_GM%(SALES,COST)Used to compute gross margin percentage.  If SALES and COST are specified, they refer to the sequential column number in DISP$ for the sales and cost.  If not specified, then it is assumed that the two columns to the left contain the sales and cost.  Default values will be assigned to TITLE and MASK if not specified.
_FILL(SIZE,CHAR)Used to fill a field with SIZE number of CHAR characters.  FILL(10,*) will show 10 *'s in the field.
[INDEX]Applies to repeating fields only.  If not specified, or if [ALL] is specified, then each element of the field will be displayed.
Title

The Title is used as the column heading.  The best practice is to specify the title in the Data Dictionary and not specify a Title in DISP$.  This is so that if changed, all programs that display the field will use the exact same column title.  When it is required to specify a different title than that stored in the Data Dictionary, then it can be specified in this position in DISP$.

If FILPGM is a data file and not a program, CDS037 obtains the column title from the title= user defined field contained within the template itself.   This means that if the title is changed in the Data Dictionary for a data file, then you must use the File Utility Compare to Data Dictionary option to update the .tpl file on the disc.

If neither DISP$ nor the template specify a title, then the title will be derived from the field name.  Regardless of the method used to obtain the Title, all underscore characters are replaced with blanks.  To specify no column title, use a single blank character.

If FIELD is a repeating field with 12 elements, then specifying a Title of Month or Mth will generate long or short month names as titles.  See Example 5.

Mask

The best practice is to specify the output mask for numeric fields in the Data Dictionary and not to specify Mask in DISP$.  This is so that if changed, all programs that display the field will use the exact same output mask.  When it is required to override the output mask specified in the Data Dictionary, then the mask can be specified in this position in DISP$.

If FILPGM is a data file and not a program, CDS037 obtains the output mask from the omask= user defined field contained within the template itself.   This means that if the mask is changed in the Data Dictionary for a data file, then you must use the File Utility Compare to Data Dictionary option to update the .tpl file on the disc.

If a mask is not provided in DISP$ nor in the template, then CDS037 will assume a default mask based on the field name, template field type, and size.  See Example 6.

NumericsBoth traditional masks (###,###.00CR) and floating decimal masks (N7.2) may be used.
Strings String fields may also be masked using the standard BBx masking characters.  For example to format a general ledger account number you could specify a mask of XXX-XX for a C(9) field.  Unlike the BBx STR() function, CDS037 and CDS038 will not cause an error if there are more characters in the data field than in the mask.  Processing is done left to right and any characters that do not fit it the mask are ignored and not printed.  This permits the insignificant trailing characters of the account number to be suppressed. This feature also provides a mechanism to truncate strings.  For example, if you only have room to display the first 5 characters of a field, set the mask to XXXXX.

Instead of a mask, a substring expression may also be used.  For example, the mask segment could contain (1,10) or (5,10) or (5).

Dates Use any of the masking characters used by the BBx DATE() function.  This permits displaying dates formatted as in 01/05/95 or Jan 1, 1995, Sat Sep 24, 1993, etc.  Since BBx does not have a template type field reserved for dates, you inform CDS037 that a numeric field is a date by specifying a mask that contains %M or %D or %Y or by setting the mask field to the letter "d".  If a mask is not specified, and not passed as "d", then a mask of "%Mz/%Dz/%Yz" will be used if CDS037 assumes the field is a date.  It makes this assumption for the following template fields that contain the word DATE in the field name (DATE, LASTDATE, DATESHIPPED, etc):
  • U(3) -julian
  • I(3) - julian
  • N(7) - julian
  • C(5) or N(5) or N(6) - Microsoft format
  • N(6) or C(6) - YYMMDD
  • C(8) - MM/DD/YY or YYYYMMDD

Note that CDS037 can easily mis-identify a field as a date when in fact it should not, i.e., YTDATE_SALES:N(7).  To prevent this, provide a mask, or make the field N(8).

TimeTimes stored in the same format as the BBx TIM system variable, typically in a B type template field, can also be masked using any of the standard BBx DATE() function formatting options for time.  If not specified, a mask of "%hz:%mz %p" mask is used.  If no mask is specified, CDS037 will assume that a B type numeric field is a TIME if the word TIME is contained in the field name.  To prevent CDS037 from thinking a field name such as TIMES_SOLD is not a TIM field, then either specify a mask, or do not use a B type field.
Options The options field can be used to create a multi-line display or to override the default column width.  Data is always left justified in the column when the B or W option is used.
BIndicates that this data field should display below the previous one, instead of in a separate column to the right of the previous one.  Note that the column width and title of any field using the B option are ignored.  The column width and title are derived from the top most field of the column.
WnIndicates that instead of using he default column width, set the column width to n characters, where n can be from 1 to 253.  Cannot be used on the same field as the B option.  This option can be used to narrow or widen a field from the default column width.  The W option can only be used on the first field in the column.  Any characters in the title or data that exceed the column width will be truncated.  See example below.
WINX can be set to the column where the upper left corner of the window border should be displayed. If not specified, WINX will be assumed to be zero.
WINY
Positive Display window will be placed at column WINX, no higher than row WINY.  The actual row will be computed based on the number of records that are needed to be displayed, and the WINROWS parameter.
Negative Display window will always be placed at column WINX at row -WINY.  This allows you to place the display window at a position you control.
Zero Value of 2 is assumed so that the company name and current selection title, normally displayed on the top two lines, remain visible on the display.
WINROWS can be set to the number of vertical print positions for the window.  If not specified, WINROWS will be computed to the bottom of the display less two lines for the prompt.
WINCOLS

can be set to the number of horizontal print positions for the window, including the window border.  If not specified, WINCOLS will be computed based on the number of positions required to display the data.  If the window width exceeds the physical display, then the display will be shifted into 132 column mode if supported by that display.  If the window width still exceeds the physical display, then WINCOLS will be set to the physical display, either 80 or 132 columns.

By setting WINCOLS to 80, you can force the screen to stay in 80 column mode, even when more than 80 columns are required to display all data.

By setting WINCOLS to 132, you can force the screen to use 132 column mode, even when the data will display in 80 columns or less.

WINTITLE$ can be set to display on the window border.  If not set, then no window title is used.
COLORS$

can be used on color terminals to override the default colors.  By default, the colors used are those specified in Operator Preference Maintenance for Display (F2).  If different colors are preferred, then COLORS$ should contain the zero filled, three 3-digit color numbers corresponding to the window border, window text, and highlighted selected text respectively.  It may also contain a 4th color number which will be used for the column headings and grid lines.  Refer to Operator Preference Maintenance (SMS) for the specific color numbers to use or click hereSee Example 7.

The chart below lists several COLORS$ values that produce good, high-contrast, displays.  See example to view many more COLORS$ values.

COLORS$ Background Color Text Color
005005069 Black Green
007007071 Black Cyan
013013077 Black Yellow
015015079 Black White
021021069 Blue Green
023023071 Blue Cyan
029029077 Blue Yellow
031031079 Blue White
039039071 Green Cyan
045045077 Green Yellow
047047079 Green White
061061077 Cyan Yellow
063063079 Cyan White
071071007 Red Cyan
077077013 Red Yellow
079079015 Red White
087087071 Magenta Cyan
093093077 Magenta Yellow
095095079 Magenta White
111111079 Yellow White
SELRTN$ In some cases, it is desirable to allow the operator to select a record, call an external routine, and then exit back to CDS037 to allow selection of other records.  You invoke this feature by specifying SELRTN$ as the program name to call when a record is selected.  When this option is used, CDS037 will CALL SELRTN$ with Y$,SELREC$,L as parameters.  You may access the current window if desired.  The selected record is at line L.

Alternatively you may print another window, then 'POP' it before exiting back to CDS037.  Effective with versions dated 11/24/04, the default colors are changed to the primary display color once a record is selected.  These colors are typically different than the colors used within CDS037 during record selection.

Note: the 'SP' mnemonic is used to place the display back to 80 column mode, for those cases where CDS037 has displayed in 132 column mode ('CP').  At the end of the routine, you only need to 'POP' the window.  CDS037 will convert the display back to 132 column mode and restore the colors if required.

You may modify SELREC$ within the selection routine and write the modified record back to the disc.  If you do modify the record, CDS037 will re-display the record. See example programs CDX090 and 091.

If you do not change the record, but want CDS037 to redisplay the record, because of related file display, or external programs referenced in DISP$, then return L as 0 to CDS037.

In some cases, you may need to modify more than one record in the file, or even add records to the primary data file.  In this case return L as a negative number to signal CDS037 to restart. This option is useful when the external routine added and/or deleted records. Note that the first record will be highlighted after the restart, just as if calling CDS037 again.

SELRTN$ can also remove records from the primary data file.  If so, then DIM SELREC$:FATTR(SELREC$) before exiting.  This is required in order to keep any temporary work file created by CDS037 to remain synchronized with the primary data file.

CDS037 creates a work file whenever it needs to use SELECT instead of OPEN on the primary data file.  CDS037 will use SELECT instead of OPEN when you pass a non-blank WHERE$, SORTBY$, or MODE$.  If SELRTN$ modifies or deletes a record in the primary data files, then CDS037 will modify or remove the record in the work file.  However it does not add records to the work file that are added by the SELRTN$ nor can it change more than one record.  This means that you should only modify or delete a single record at a time when using WHERE$, SORTBY$, or MODE$.

In most cases, you can do what is necessary within the record selection routine.  There is another option of CDS037 that actually exits CDS037, passing you the SELREC$, but does not pop the display window.  This option is invoked by passing SELRTN$ as "*exit*".  The calling program may modify the selected record and CDS037 will display the revised record if CDS037 is called again.  After processing is completed outside of CDS037, then by calling CDS037 again, the list of records will re-display, the highlighted record will be moved down to the next record.  Note that this option does not offer a method of informing CDS037 that records other than the selected record was changed, nor if any records were added or deleted.

You can also pass SELRTN$ as "CDS279" which will display the selected record with one field per row in a separate window.

When SELRTN$ is not used, and CDS037 is called with a complete ENTER list including SELREC$, then when the user highlights a record and touches the Enter key, CDS037 exits and returns the selected record to the calling program.  It is possible to enable that option even when using SELRTN$.  In that case the user has two options: Touching Enter will exit CDS037 and return the selected record to the calling program, and touching F2 will call the SELRTN$ program.  To enable this option, append a colon (:) and F2 prompt text to SELRTN$.  For example, if SELRTN$="PO150:Display PO Line Items", then the CDS037 prompt will include: Enter=select record, F2=Display PO Line Items, F3=Help, F4=End.  If the user touches the Enter key, then CDS037 will exit and the highlighted record will be returned to the calling program.  If the user touches F2, program PO150 will be called, and when it exits, the CDS037 window will be re-displayed, the highlighted row moves down to the next record, just like when SELRTN is used.  Note that because of the use of a colon as the separator between the program name and the F2 prompt text, you cannot include a colon in the program name.

WHERE$

The following four parameters WHERE$, SORTBY$, MODE$, and LIMIT are used when instructing CDS037 to use a SELECT verb.  When any of these parameters are specified, the KNO and KEYPFX$ parameters are ignored.  When one of these SELECT parameters is specified, CDS037 will create a temporary file in the tmp/ subdirectory, however, on Unix systems, this file will not appear in a disc directory and will be automatically erased when the display is completed or if the process is killed or otherwise aborted.

If there is a KNUM of the data file that can be used to limit the records to be displayed, use the KNO and KEYPFX$ parameters instead of WHERE$.  This will result in faster operation and eliminate the need for the temporary work file.

WHERE$ may be used when only selected records are to be displayed.  The format of WHERE$ is that used for the SELECT verb.  You can refer to the record template string as REC., the file name, i.e, CM01., or leave off the string.  All of the following are equivalent:
POS(REC.STATE$="OHPAWV",2)
POS(CM01.STATE$="OHPAWV",2)
POS(STATE$="OHPAVW",2)

If the WHERE$ parameters is not specified, but one of the other SELECT parameters are specified, then all records in the file will be displayed. 

Note that the WHERE$ cannot include any fields derived from related files or called routines.  Only fields located in the primary file can be used.

SORTBY$

is used when special sorting sequence is desired.  You may use REC., the string based on the file name, i.e., CM01. or leave off the string as explained above for WHERE$.  Unlike the WHERE$ clause, SORTBY$ can contain fields from related files or other called routines.

When sorting by a numeric field, use the functions listed below: For U type fields, use the string version of the field name as in REC.VALUE$.  For all other numeric fields, use ADJN(REC.AMOUNT).

When a segment of a sortby key must be descending, add the NOT() function as shown below.  For string fields, use NOT(REC.FIELD$).  For U type numeric fields, use the string version of the field name as in NOT(REC.VALUE$).  For all other numeric fields, use NOT(ADJN(REC.VALUE)).

S037$ Prior to 4/13/2010, this field only contained MODE$.  Programs passing only MODE$ to CDS037 will continue to work the same.  Use the CDS037 template to pass any of the new parameters to CDS037.
S037.MODE$This optional argument is passed as the MODE= string on the SELECT verb.  The most popular use is for creating a log file describing the optimization logic used by SELECT.  To enable this option, pass MODE$ as "debug=tmp/CDS037.txt", and a text file will be created with optimization data.  You can review the optimization data to determine how BBx chooses the bests KNUM to use.  You have some options to override the default behavior of BBx by passing "opt=nowhere", "opt=nosort", or "opt=none".  Refer to the BBx documentation for the SELECT verb for additional details.
S037.COUNT$Pass as "Y" to cause the record count to display in the window title to the right of WINTITLE$ if present.  This is useful when using WHERE$ to show the number of matching records.
S037.F5$

Pass a non-blank phrase to indicate that the prompt should include F5=[S037.F5$ value].  If the user touches F5, CDS037 will exit to the calling program with CTL=5.  This enables the calling program to do one thing if the user touches enter to select the record, and something else if the user touches F5.

You can also present multiple options using function keys F5, F6, F7, and F8 by including Fx= in S037.F5$, i.e., S037.F5$="Enter search value, F6=Clear, F7=Lookup". Note that there is limited display space for this prompt, so keep this value as short as possible.

S037.JUMP$Pass as "N" to disable option to touch a key to advance to a position in the file. Especially useful when CDS037 is used to select record for entry of data within grid itself.
LIMITVAL is passed to the SELECT verb to limit the number of records displayed.  If not passed to CDS037, or passed as zero, all records meeting the conditions specified in the WHERE$ parameter will be displayed.  It can be set to a number during testing to reduce the time to process all matching records.
SELREC$

Set by CDS037 as the primary file record selected by the operator.  SELREC$ does not need to contain anything when passed to CDS037, but will contain the template based selected record unless the operator touches F4 to exit.  You can disable the message at the bottom of the display that prompts the operator to highlight and select a record by excluding SELREC$ from the variables passed to CDS037.  SELREC$ is typically passed as the actual file name variable as in CM01$, IM01$, etc.

Note that when SELREC$ is passed to CDS037, in addition to setting CTL=4 if the operator touches F4 instead of selecting a record, CDS037 will also set CTL=4 if the file specified in FILENAME$ cannot be opened, or if there are no eligible records to display.  The calling program should not also perform such tests unless it is desirable not to inform the operator.

Using Related Files

There is no limit to the number of related files that can be used.  No error occurs if CDS037 is unable to locate a record in a related file. These fields will be blank or zero.

With DISP$="ORDERNO|CUSTNO|XXUM10.NAME", the field NAME will be displayed from file XXUM10.

The following assumptions are made about the relationship between the main file and the related files.

Note: CDS037 can use fields in related files to access other related files.  For example, consider the files and fields:
File Name Field Names
SO01 - Sales Orders ORDERNO, CUSTNO
CM01 - Customers CUSTNO, NAME
SM01 - Salesmen SLSNO, NAME

DISP$ set to "ORDERNO|CUSTNO|XXCM01.NAME|XXCM01.SLSNO|XXSM01.NAME" will display the salesman name from the salesman file even though the salesman number is not on the order file.  There is no internal limit to the number of files that can be accessed.  In effect, for every related file that is accessed, all fields in that file can be used as keys to access other files.

Using Called Routines

There are many situations where special formatting or access to other files requires a called routine.  CDS037 can call an unlimited number of routines for each record to be displayed.  These routines return a populated string template to CDS037 containing one or more data elements.  The ENTER statement in the called routine should be:

ENTER Y$,REC$,PROG$

Y$ Standard task control variable
REC$ Templated record associated with main file: FILENAME$.  Usually named with last four characters of file name, i.e., VM60$
PROG$ Templated record associated with this called program.  Usually named the same as the program name, i.e., VM601$.

The called program must have a template associated with it.  However, CDS037 can access the template from the Data Dictionary: A template file on the disc is not required.  Refer to CDS041 for template search logic.  CDS037 will retrieve the template for the called routine and pass it in PROG$.  The called routine does not need to initialize the template.

Note: CDS037 will only call each routine once, even if it is referenced in DISP$ multiple times.

In some cases the called routine needs data not specifically contained within REC$.  When operator entries are needed by the called routine, they can be stored in global variables for access within the called routine.

Example 5 uses a called routine to add up each of the 12 months and have CDS037 display the total.

Note: CDS037 cannot compute totals and sub-totals like CDS038 does.  However, you can write a program that does all the computations, stores the data in a file, then calls CDS037 to display the data, including the sub-totals and totals contained within the file.

Example 1
CALL "CDS037","SM91"

Example 2
CALL "CDS037","SM90",0,"","REQID|FAXNO|OPERID"

 
Example 3
This example demonstrates how to display data from a related file.
CALL "CDS037","SM91",0,"","REQID\Req#|ATTEMPT|SM90.FAXNO\Fax#|SM90.OPERID\Operator ID"
Example 4
This example demonstrates use of a key prefix and a display string indicating the fields to be displayed.
CALL "CDS037","SM90",1,BIN(JUL(2007,7,18),3),"QDATE|QTIME|REQID|OPERID"
Example 5
Demonstrates the use of an external program to compute totals in columns.

The Data Dictionary for VM113 includes fields named RCVTOT, RETTOT, INVTOT, and PMTTOT, all template type B.

CALL "CDS037","XXVM60",0,"","VENDNO|YEAR|INVAMT\Mth\-###,##0|VM113.INVTOT\Total"

 

0100 REM "VM113 - 10/25/07 Vendor Inquiry - History Totals
0110 SETERR 8000; SETESC 8000
0120 ENTER Y$,VM60$,VM113$
0130 CALL "CDS041","VM113",VM113$
0200 FOR I=1 TO 12
0202 LET VM113.RCVTOT=VM113.RCVTOT+VM60.RCVAMT[I]
0204 LET VM113.RETTOT=VM113.RETTOT+VM60.RETAMT[I]
0210 LET VM113.INVTOT=VM113.INVTOT+VM60.INVAMT[I]
0220 LET VM113.PMTTOT=VM113.PMTTOT+VM60.PMTAMT[I]
0290 NEXT I
0500 EXIT

8000 REM "Call Error/Escape Routine
8010 CALL "CDS063",STR(TCB(5)),Y$,PGM(-2)
8020 ON Y.ERRSTS GOTO 8030,8040,8050,8060
8030 SETERR 0
8040 RETRY
8050 RETURN
8060 RETRY

Example 6
This example demonstrates use of date and time masks.
CALL "CDS037","SM90",0,"","QDATE\Date\%Ds %Ms %Dz|QTIME\Time\%Hz:%Mz|REQID\Req#\####|OPERID\Opr\XXX"
Example 7
This example demonstrates the use of overriding the default position and size of the window, and the colors of the border, heading row text, regular text, and highlighted row text.
0110 LET FILENAME$="SM90"
0120 LET WINX=10,WINY=4,WINCOLS=58
0130 LET WINTITLE$="Fax Log"
0140 LET COLORS$="015029077023"
0150 CALL "CDS037",FILENAME$,KNO,KEYPFX$,DISP$,WINX,WINY,WINROWS,WINCOLS,WINTITLE$, COLORS$,SELRTN$,WHERE$,SORTBY$,MODE$,LIMITVAL,SELREC$
Multi-Line example using B option
CALL "CDS037","EXIM01",0,"","ITEMNO|DESC1\Description|DESC2\\\B|PCL"
Multi-line example using W option
CALL "CDS037","EXIM01",0,"","ITEMNO\\\W35|DESC1\\\B|DESC2\\\B|PCL"
Example that cycles through many COLORS$ values
0120 FOR COL=1 TO 128
0130 LET BASE=INT((COL-1)/16)
0140 LET TEXT=MOD(COL-1,16)
0150 IF COL=16*BASE+2*(BASE+1) THEN CONTINUE
0160 IF BASE<>4 THEN LET HIGH=4 ELSE LET HIGH=0
0170 LET COLORS$=STR(COL:"000")+STR(COL:"000")+STR(16*HIGH+TEXT+1:"000")
0180 CALL "CDS037","CDDD10",0,"","FILNAM|DESC|TYPE",0,0,0,0,"Colors:"+COLORS$,COLORS$
0190 NEXT COL
Example using the F5 option
CALL "CDS041","CDS037",S037$,"YY"

S037.F5$="Sort by VP#"
CALL "CDS037", FILENAME$, KNO, KEYPFX$, DISP$, WINX, WINY, WINROWS, WINCOLS, WINTITLE$, COLORS$, SELRTN$, WHERE$, SORTBY$, S037$