-------
The command DMOSUBF will provide a demonstration of a Subfile. The
code provided includes comments for how to modify the source to fit
your specific needs. For a simpler solution, see CRTSFLPGM. The
subfile application provided contains the typical functions of:
- Display a detail record
- Change a record
- Copy a record with a new key
- Rename a record with a new key
- Delete a record (a confirmation display occurs)
- Add mode (adding new records)
- 'Position to' function
- Controlling which record keys exist in the subfile
- Alternate view capability
- Help text
You can try out the function with the command:
DMOSUBF
You will probably better understand this documentation if you have
used the demonstration. You can try it yourself or see the later
section.
The DMOSUBF2 command is also supported. It has an example of a
Subfile with only a display option supported. Most of the functions
are the same between the two commands. DMOSUBF2 is provided to
assist you when you do not need the full range of functions.
The intent of the source is to allow you to build a subfile display
application with a minimum of effort.
All of the screens support help text. The help text shown is
standard for things like function keys and Option entries. Sample
formats are provided for field help text.
Assuming you have:
- Read this documentation
- Used the demonstration to understand the
screens and approach
- Have a typical physical file definition created
- Have worked out your design (see the later section)
and have developed your first application with this approach, you
should be able to produce a basic working subfile for in a couple of
hours. Specific tailoring for such things as specific help
functions, elaborate field input validation, additional options, will
take longer.
***************************************
* *
* Do not use SDA on the Display *
* file source until you are mostly *
* complete. SDA may remove the *
* comments you need to make changes. *
* Use SEU. *
* *
***************************************
A data base file also exists which contains demonstration data for
the tool. The file contains member information about some of the
members from TAATOOL. This data base base file is used by both
commands and is test data (you may change the data or delete it
without harm). You can refresh the data with:
SBMJOB CMD(CALL TAATOOL/TAASTDBC2)
Differences with other DMOSUBF tools
------------------------------------
DMOSUBF3 is a subset of the DMOSUBF tool with the major difference
that array data is used to load the subfile rather than data base
records.
DMOSUBF4 provides the same function as DMOSUBF3, but the data is
displayed in a window on the display.
DMOSUBF5 is like DMOSUBF3 plus a 'Position To' entry.
DMOSUBF6 is like DMOSUBF4 plus a 'Position To' entry.
Copying the source
------------------
You can copy the source provided by use of the DUPSTDSRC TAA Tool
command. It allows a simple copy of each member. For example,
assume you want to copy the DDS code for the display file.
DUPSTDSRC MBR(xxx) SRCTYP(*SUBFDSPF)
TEXT('xxx') SRCFILE(yyy)
You must name the new member name you want to add. You need a
separate DUPSTDSRC command for each source type that you want to
copy.
The following are the source types and the corresponding members:
DMOSUBF (Full Subfile Support)
DUPSTDSRC
Type SRCTYP Member File
------ --------- ------ -------
Command *SUBFCMD TAASTDB QATTCMD
CL Pgm *SUBFCLP TAASTDBC QATTCL
Dsp file *SUBFDSPF TAASTDBD QATTDDS
RPG Pgm *SUBFRPG TAASTDBR QATTRPG
DMOSUBF2 (Display Only Subfile Support)
DUPSTDSRC
Type SRCTYP Member File
------ --------- ------ -------
Command *SUBF2CMD TAASTDC QATTCMD
CL Pgm *SUBF2CLP TAASTDCC QATTCL
Dsp file *SUBF2DSPF TAASTDCD QATTDDS
RPG Pgm *SUBF2RPG TAASTDCR QATTRPG
Subfile display
---------------
When you issue the command DMOSUBF, you will see an initial display
that describes the demonstration and how to refresh the data if
needed. An option exists to allow an alternate view. It defaults to
Y which allows the F11 key to be used.
When the subfile display appears, one or more options can be entered
and rollup may be used. Any options for Display, Change, Copy, or
Rename are handled in the sequence in which they are entered.
Any options for Delete are saved until all other options have been
processed and then a confirmation display appears (a subfile of all
the records selected for deletion). The user is given the choice of
confirming the deletes or cancelling.
If a request is made for 'Add Mode', a prompt occurs after all option
entries have been processed. The user stays in 'Add mode' until F3
or F12 is pressed and then he returns to the subfile.
Two data base files are used:
** A keyed file. This file is 'read only' and is used to fill
the subfile. This can be either a physical or logical file.
The relative record number of each record read is saved in the
subfile as a hidden field. The demonstration file has a
unique key of file and member. It is not required that unique
keys exist.
** An Arrival Sequence access path file over the same physical
file as the keyed file. This can be either a physical or
logical file. This file is used for changes, additions, and
deletions.
Assume your physical file is the keyed file FILEA with the format
FILEAR. The only DDS you need for the Arrival Sequence logical file
is:
A R FILEAR PFILE(FILEA)
You can use the CRTLFSRC TAA Tool also such as:
CRTLFSRC LFFILE(xxxx) PFILE(FILEA) KEYFLD(*NONE)
Both data base files may be logical files based on a physical file
which is not described in the program. Only a single format logical
file may be used for the Arrival Sequence access path file. The same
format should be used for both files. You should not use a single
shared open to cause both files to use the same Open Data Path (the
cursor location of the keyed file is important).
If you are going to be repeatedly using the subfile (e.g. call it,
end it, call it again, etc.), you should consider the use of either
pre-opening the files or the parameter which controls the LR setting
at the end of the program. This subject is discussed later on.
The DMOSUBF command supports the CTLKEY parameter. This will be
discussed later. The rest of this section assumes you are taking the
default of *ANY.
The DMOSUBF command supports the FILE and MBR parameters which both
default to blanks. This causes the first record in the keyed file to
be displayed as the first record in the subfile. Values can be
entered on the command to start the subfile at a different keyed
record. If values are entered on the command, they will appear at
the top of the display in the 'Position to' fields.
If no values are entered, the key fields from the first record are
placed in the 'position to' fields. If you prefer the 'position to'
fields to be blank, instructions exist in the source for how to cause
blanks.
The parameters on the command are the same function as the 'Position
to' prompt at the top of the subfile display and will be described as
the 'position to' option.
The 'position to' option allows the user to start accessing the data
at any point in the file. The demonstration allows the user to enter
values in the 'Position to' fields, that do not match a record in the
data base. If they do not, the first record displayed will be the
record just prior to the values entered. (A SETLL function is used
and if the record does not exist, a READP function is used).
There is an option to control which record keys will exist in the
subfile. See the later discussion.
Once the subfile is displayed, the user may press rollup and the next
page of records will be displayed. This occurs by returning to the
program and reading one page worth of data base records. An
indication of 'More' or 'Bottom' is shown.
Options are not processed during rollup or rolldown. This allows the
user to select multiple options on several pages of the subfile
before any are processed.
If rollup has occurred, the user may rolldown. Rolldown is only
valid to the point of the first record displayed at the 'position to'
point. (Rolldown occurs by using the system subfile support).
Requests to display or change a record, do not cause a refresh
(meaning the subfile is not re-filled). Any changes to fields that
appear in the subfile display will be shown correctly when the
subfile is re-displayed (both the data base record and the subfile
record are updated on any change request). If a display or change
request occurs, the subfile is re-displayed with the page shown that
had the last record for which an option was requested.
Any add, deletes, copies, or renames cause the subfile to be
refreshed. An attempt is made to display the page of the subfile
where the change occurred.
** If a delete occurs, the page where the last record was deleted
from is displayed.
** If an add occurs, the subfile is re-positioned to the added
record if the key that was added is less than the key of the
first record in the subfile. If the key is greater than the
first record in the subfile, the last page on which an option
was entered is displayed or the last page of the subfile.
If you request 'position to' as well as a display, change, or delete
request and then cancel, the subfile is not re-positioned. The
'position to' values remain and would be used when a valid action
occurs. If you request 'position to' and Add Mode, the 'position to'
function is performed when Add Mode is ended.
Pressing the Enter key without selecting an option does not end the
program. This technique is used because the first display may take
some time to appear and inadvertent enter keys would end the program.
The user must press F3 or F12 to end the subfile display.
The 'Detail record display' is a unique DDS format. The 'Change/Add'
functions share a separate format.
The source provides two screens each for the 'Detail record display'
and the 'Change/Add record display'. This allows for the case where
all fields do not fit on a single display. The default is for a
single screen for each function. Instructions exist in the source
for how to activate the second screen.
Your code can control what fields are displayed or changed. You can
provide defaults for certain fields in new records. Instructions in
the program tell you where to do this.
The demonstration assumes that the key fields of an existing record
cannot be changed during Change mode. See the instructions in the
display file and RPG source for how to remove this restriction.
If add mode is entered, it is assumed the user will want to add more
than one record. If the user adds a record, the prompt for a new
record continues to appear until the user presses F3 or F12 to return
to the subfile.
The F18 key is valid during add mode to duplicate the fields entered
from the previous record. F18 is not valid until a record has been
added. The F18 key duplicates the record as it was added (not the
way it exists in the data base when F18 is used).
Alternate View
--------------
The default in the standard code is to provide a single view of the
data (the Demonstration default allows a alternate view).
You may specify an option for an alternate view by scanning the RPG
code for ALTVW and use a SETON instead of a SETOF.
This activates the F11 key to allow a flip/flop between the main and
alternate view. The F11 description is either 'View 1' or 'View 2'.
The RPG ZZCVT subroutine is used for converting both the main and
alternate view fields prior to display if needed.
Fields for the alternate view should be entered in DDS (Scan for
ALTVW) and follow the instructions.
Help Text
---------
Help text is provided for each of the displays by using HLPxxx
keywords and help formats in the same display file.
Each Help format is defined as a window and has room for 10 text
lines of 55 characters. Some help displays say 'More...' at the
bottom of the help window to allow the user to roll for more text.
Function keys are provided at the bottom of each help display.
The help window is displayed using the current cursor position to
locate the window on the display. This allow the user to normally
see what he requested help on plus the window.
There are no RPG statements relative to the display help (it is all
in the display file).
The help text includes standard formats that relate to general
display information, function keys, and options. You may need to
tailor some of the text that is specific to the demonstration to fit
your application.
There is a sample provided to show you how to provide help text for
your fields. The sample is for the MLFILE field ('File' prompt).
The same help text is available from any display that shows the
MLFILE value. For example, you can access the field help text from
the 'Confirm Deletes' display.
The typical solution would be to get the application working first
and then 'fine tune' the help text at a later point.
Another solution would be to provide help text only for the Options,
function keys, and general screen display. Instructions exist for
this also.
If you don't want to provide any help text, there is a discussion in
the display file source of how to get rid of it. See the later
section on modifying help text.
Control key option
------------------
The DMOSUBF command supports the parameter CTLKEY which allows
options to control the records which appear in the subfile. The
parameter is provided on the command so you can better understand how
the options work.
When you duplicate the source, the instructions will tell you to
delete the parameter from the command and use a literal in the RPG
program to specify one of the options (It would be possible to use a
parameter as in the demonstration).
The best way to understand the Control Key function is to try the
DMOSUBF command. See the later discussion.
The options are:
*ANY All records in the file can be displayed (the user is
not restricted to a key range).
If a 'position to' value is passed in, the first
record displayed will be the record with the key that
matches the value or the record that is just prior to
a non-existent key.
Use *ANY when the user should see all of the records
and is not restricted in any way.
*GENERIC Only those records that match the characters keyed for
the high order 'position to' key will be displayed.
For example, if you specified FILE(QATTD) in the
demonstration, only those records that began with a
file name of QATTD would be displayed.
If no records match the value, a blank subfile is
displayed and the user can add records. If the high
order key is blank, it is treated as if *ANY had been
specified.
The user is not restricted from accessing other
records if 'position to' fields exist at the top of
the display. Only those records which match the high
order 'position to' field will be displayed. If you
want to display the high order 'position to' field,
but not allow the user to change it, see the
instructions in the DDS to make the 'position to'
field 'output only'.
Use *GENERIC when you want to reduce the number of
records that the user can see in the subfile.
*FULLEQ The only records displayed are those that match the
full key. If no records match, the program is ended
with the return code parameter set to 'NOTFOUND'.
Most use of *FULLEQ or *FULLEQA will be for files that
do not have unique keys.
You must pass a 'position to' value. You would
normally not display any 'position to' values at the
top of the display as the program will restrict the
user.
You would normally initialize all of the key fields
for any new records and would prevent them from being
changed.
Use *FULLEQ when the 'position to' value(s) you are
passing requires that records exist that match the
full key and you want the user restricted to that set.
*FULLEQA This is the same as *FULLEQ except that if no records
exist for the 'position to' key, the subfile is
displayed and F6 is allowed for the user to enter 'Add
mode'.
Use *FULLEQA when you want to restrict the user to a
set of records, but if there are no records that match
the 'position to' value, the user should be allowed to
add some.
*HIGHEQ The only records displayed are those that match the
high order value of a multiple key access path. If no
records match, the program is ended with the return
code parameter set to 'NOTFOUND'. You must pass a
'position to' value.
For example, the demonstration has a multiple part key
of FILE and MBR. You could restrict the user to the
QATTDDS file records, but allow him to position to any
MBR within that file name.
If you have multiple keys that make up the high order
portion and you want to restrict the user to that set,
see the later discussion of Multiple High Order Keys.
You would normally not display the high order
'position to' value at the top of the display as the
program will restrict the user.
You would normally initialize the high order key
fields for any new records and would prevent them from
being changed.
Use *HIGHEQ when you want to restrict the user to work
on only the records that match the 'position to'
value(s) of the high order key that you pass in. The
user will have access to any low order key.
*HIGHEQA This is the same as *HIGHEQ except that if no records
exist for the high order 'position to' key, the
subfile is displayed and F6 is allowed for the user to
enter 'Add mode'.
Use *HIGHEQA when you want to restrict the user to a
set of records based on the high order key, but if
there are no records that match the 'position to'
value, the user should be allowed to add some.
Record locking considerations
-----------------------------
The records are written to the subfile, by reading the keyed file.
The keyed file is opened for 'input only' so no locking occurs.
If an option is specified for a particular record, the relative
record number file is accessed. This file is opened for update and
additions.
If a record is requested to be displayed, a 'read only' request is
made (The 'N' function is used on the CHAIN operation to prevent
locking the record).
If a record is requested to be changed, the record is accessed for
'read only' and a copy of the record image is stored within the
program. If the user makes changes and presses Enter, the record is
re-accessed (this time for update) and compared against the original
record image. If the two images match, the record is updated.
If the two images do not match, the record is unlocked and a special
display is shown informing the user that the record has been changed
since it was first displayed. All of the proposed changes have been
lost. The current record data is then re-displayed. The user must
re-key.
If a display or change request is made and the record no longer
exists, an appropriate error message will be displayed. This would
occur if another user had deleted a record after it was written to
the subfile.
If the record exists when a change request occurs, it may no longer
exist when the user finally presses Enter to cause an update. If
this occurs, a special display appears informing the user of what
happened and that he cannot change a deleted record.
If a duplicate key error occurs, a special display is shown informing
the user of the error and allowing him to correct the error.
The demonstration uses a unique keyed file and prevents the user from
changing the key fields during a Change request. Therefore, a
duplicate key error can only occur during the demonstration when a
new record is being added.
If your application requires unique keys, but allows the user to
change existing key fields, the duplicate key error can also occur
during a change request. A duplicate key error could also occur if a
separate data base file had specified a unique key access path that
is not the same as the file you are using for the keyed file.
While the code does not lock a record during the users 'think time'
(when the record is displayed for update), it is possible that a
different program could be accessing the data base for update and
'lock out' the user from making an update. If this occurs, a special
display will appear (the work is performed by the TAA Tool LOCKMSG)
informing the user of the condition and allowing the user 4 choices:
- Send a message to the user who has the lock
- Try again
- Send a message to the system operator
- Cancel (return to the subfile display)
If the user requests to delete a record, a confirmation prompt will
appear. The user may cancel the request. If the deletes are
confirmed, the records are re-accessed for update and deleted. If
the lock cannot be achieved when the record is re-accessed, a special
display will appear informing the user of the condition and that the
delete request will be bypassed. If the record has already been
deleted, a special display will appear informing the user of the
condition and that the delete request will be bypassed.
Error handling
--------------
Errors are handled in different methods depending on the type.
** For most errors, standard text exists. If an error occurs, a
single line of text appears at the bottom of the display.
The message text is stored as array entries within the RPG
program. The array data is moved to a field which is
displayed at the bottom of the subfile display or the
Change/Add record display. The keyboard is not locked.
Additional lines of error text can exist. If additional lines
exist, the F23 function key is active and the user may use it
to display the additional text (a separate screen appears).
Up to 16 lines of additional text are provided for.
You may modify the standard text so that the descriptions fit
your application, but you should not modify the internal error
codes (they use the convention Znn). The program has
instructions for how to modify the message text.
** In exceptional error conditions (e.g. attempting to delete a
record that has just been deleted by another user), a special
display format is used. You may modify the text for these
formats if needed.
** Most user applications will have some validity checking of
individual fields for the 'Change/Add' record display. Some
samples are provided. The typical choices would be:
-- Use DDS validity checking such as the VALUES keyword.
-- Use the DDS ERRMSG keyword. There is an example of
this in the sample code provided where the -Number of
records- field cannot be zero. You must set an
indicator in the RPG program to condition the DDS
ERRMSG keyword.
Using ERRMSG causes the field in error to be
highlighted and the keyboard will be locked.
-- Use a user defined message in the RPG program. The
text for these messages would be in the RPG program as
array entries. These are similar to the standard
messages provided.
The 'RPG text' solution does not lock the keyboard. A
conditioning indicator is set on in the RPG program to
cause reverse imaging of the field and positioning of
the cursor.
There is an example of this type of message used for
Add mode to ensure that the user has entered certain
required fields. This is designed to prevent an
inadvertent Enter key from entering a blank record into
the data base. You probably have some similar
requirement.
There is another example of this in the sample code
where the -Type- field has valid values of CMD, PF, or
RPG. Any other type is considered invalid for the
demonstration. This message has additional lines of
text. When the message is displayed, F23 is valid for
the user to access the additional lines.
Follow the instructions in the RPG program for how to
enter message text and cause a similar message to
occur.
** The RPG program specifies the error indicator on several of
the data base operations. If an error occurs, the status code
is checked for expected error conditions. If an unexpected
error occurs, the RPG program will abnormally terminate with
an escape message that will contain the internal error ID.
This same technique is used for other internal errors where
unexpected conditions could occur.
How should the subfile be used
------------------------------
You may use the subfile sample code for several situations (or
combinations of these). There are source members provided by
DUPSTDSRC that make up the DMOSUBF and DMOSUBF2 demonstrations that
can be used for:
- Command definition
- CL program
- Display file
- RPG program
The typical situations where you could use the source include:
** A command interface. You want a subfile display to appear
when you enter a command. This would be similar to the
DMOSUBF command.
** A menu interface. You want a subfile display as an option on
a menu.
** Program call. You want to call the subfile program from a HLL
program. There are several possibilities such as:
-- In your HLL program you want to invoke a subfile
display that is an independent function. The sub
program would not pass back any data.
-- Your HLL program could be a subfile program itself
(e.g. for handling order header records). You add a
special option entry to allow access to the detail
records subfile. This could be implemented by using a
separate program and display (also created from the
sample code).
-- Your HLL program could be a subfile that requires the
user to know the record key (e.g. customer number).
If the user does not know the record key, a Function
key could be added to the sample code to call a sub
program which could also be developed by using the
sample code, but would access the data by means of a
separate access path. The sub program would then
return the record key for use by the main program (See
the later discussion on Adding a 'Specify' option).
Getting familiar with the demonstration
---------------------------------------
Before you try to copy the sample code and create your own
application, you should be familiar with the externals of the
demonstration program. You will be able to more easily tailor the
code if you have a good idea of what is being provided.
Enter the command:
DMOSUBF
Try out the functions:
- Each of the options on the subfile display
- Try multiples and combinations
- The F6 key for 'add mode'
- Enter a record and then use the F18 function
on the next prompt for a new record
- The 'position to' function
- Try a key that exists
- Try a key that does not exist
- Try the command with the FILE and MBR parameters
(A later section discusses the CTLKEY parameter)
- Rollup and rolldown of the subfile
- Try to change an existing record with invalid data
to check the error handling:
- The -Type- field must be PF, CMD, or RPG
- Try the F23 function
- The -Number of records- field cannot be 0
- Try to add a new record without entering any data
- Just press the Enter key after the prompt
- Try to add a duplicate key
- Try some of the cancel options
- Try the help text functions (HELP key or F1)
- Use ROLLUP to roll thru the help text
for the entire display
- Try the help text for the 'File' field
(Active on every display which has 'File')
You can simulate the unique situations where another user is
using the same application and:
- A change occurs while the first user is changing
the same record
- A record is deleted while the first user is
changing the same record
- A record is deleted while the first user
is deleting the same record
Use a different job (e.g. group job or system request) and
the same application. For example, have the first job request
to change a specific record. When the Change display appears,
switch to a different job and change the same record. Then
return to the first job and attempt to make a different
change.
The program also provides for the case where a record is locked while
the user is attempting to delete or change the record. This function
cannot be simulated using the program because the program does not
lock the record during user 'think time'.
A solution to test this problem is to use the TAA Tool LCK1STRCD. It
will lock the first record in the file you name. Specify:
LCK1STRCD FILE(TAASTDBK)
You will see the first record on the keyed access path locked. Note
the file and member name in the record.
While the record is locked, access a different job and use DMOSUBF.
Request to change the same record. Enter a different value in one of
the fields (e.g. change the number of records) and press Enter. You
should timeout after 5 seconds and see the TAA Tool LOCKMSG action
which offers a prompt. You can try the different actions on the
prompt.
Getting familiar with the CTLKEY parameter
------------------------------------------
To understand the DMOSUBF CTLKEY parameter, try the following
examples. If you have deleted many of the records in the file,
refresh it as per the instructions on the first display.
DMOSUBF
The first record displayed is from the QATTCMD file. Roll all the
way through the file so you understand the records that exist.
Enter the following in the 'position to' FILE prompt:
File = QATTD
The first record displayed is the last record for the QATTCMD file.
This occurs because the full 'position to' key (FILE and MBR) does
not match any record so the first previous record is shown.
Blank out the 'member' value and enter the following in the 'position
to' FILE prompt
File = QATTDDS
The same record is displayed. This occurs because the full 'position
to' key (FILE and MBR) where MBR is blank does not match any record
and the first previous record is shown again.
Enter the following in the 'position to' FILE and MBR prompt:
File = QATTDDS Member = TAASPLCP
You should be positioned at the record you requested. Since the
record is equal on the entire 'position to' key, the previous record
is not shown.
Enter the following in the 'position to' FILE and MBR prompt:
File = QATTDDS Member = TAASPLH
Since the record does not exist, you should see the first record
prior to TAASPLJ. Not all QATTDDS records are not shown.
Return to the DMOSUBF command and enter:
DMOSUBF CTLKEY(*GENERIC)
You should see the same display as if you had entered CTLKEY(*ANY).
This is a special case when no 'position to' value is entered.
Enter the following in the 'position to' FILE prompt:
File = QATTD
You should see only those records that begin with a file name of
QATTD.
Enter the following in the 'position to' FILE prompt:
File = QATTDDS
You should see the same display.
Enter the following in the 'position to' FILE and MBR prompt:
File = QATTDDS Member = TAASPLCP
You should see the first record you requested.
Enter the following in the 'position to' FILE prompt (blank out the
member value):
File = QATTE
Since no records match the value, you should see a blank subfile.
Press F6 for add mode. You should see that you can enter both the
FILE and MBR name for a new record.
Return to the DMOSUBF command and enter:
DMOSUBF CTLKEY(*FULLEQ) FILE(QATTDDS) MBR(XXX)
You should see an error message that the full key (FILE and MBR) does
not exist in the file.
Enter the command:
DMOSUBF CTLKEY(*FULLEQ) FILE(QATTDDS) MBR(TAASPLCP)
You should see only a single record in the subfile. Note that the
FILE and MBR 'position to' fields are protected (When *FULLEQ is
used, it does not make sense to have 'position to' fields).
Press F6 for add mode.
You should see that both FILE and MEMBER are initialized and the
fields are protected.
In the demonstration, the file has unique keys. Therefore, you could
not add another record with this key. The use of *FULLEQ does not
make a lot of sense when unique keys exist.
Enter the command:
DMOSUBF CTLKEY(*FULLEQA) FILE(QATTDDS) MBR(XXX)
You should see a blank subfile because the full key does not exist,
but you are allowed to add records.
Press F6 for add mode. You should see that both FILE and MEMBER have
been initialized and cannot be changed. Because the file has unique
keys, you could only add a single record.
Enter the command:
DMOSUBF CTLKEY(*HIGHEQ) FILE(QATTD)
You should see the error message that the high order key does not
exist.
Enter the command:
DMOSUBF CTLKEY(*HIGHEQ) FILE(QATTDDS)
You should see only the QATTDDS records.
Note that you cannot enter a value in the 'position to' field for
FILE (With *HIGHEQ you would normally not display the field).
Enter the following in the 'position to' MBR prompt:
Member = TAASPLCP
You should see the subfile positioned to the record you named.
Press F6 for Add mode.
You should see that the file name is initialized and cannot be
changed, but you can enter any member name.
Enter the command:
DMOSUBF CTLKEY(*HIGHEQA) FILE(QATTD)
You should see a blank subfile, but you are allowed to add records.
Comments in the source
----------------------
The code provided is for a demonstration and includes instructions
for what needs to be modified to fit your needs.
The source contains two kinds of comments.
** Permanent comments intended for permanent documentation.
** Temporary comments intended to describe how to modify the
source. The temporary comments all have +++ in every
statement.
There are two kinds of temporary comments:
-- +++Required. These discuss required changes that you
must make to create a working program.
-- +++Optional. These discuss changes that you may want
to make to tailor the program.
The instructions will tell you to scan for the +++Required
comments. Concentrate on these first. After you have created
a working program, go back and remove or add function based on
your specific requirements.
Each comment section in the source ends with a a statement
such as:
F*+++ Complete = No
The intent is that if you have completed the work for the
comment section, you would change the 'No' to 'Yes' or a value
of your choice. This provides documentation to yourself as to
the changes you have made.
The best solution is normally to leave both forms of temporary
comments in the code until you get the program working. A
special TAA Tool RMVSRCCMT can be used to remove all of the
+++ comments when you are ready to clean up the source.
You would enter the command:
RMVSRCCMT MBR(xxx) SRCFILE(yyy)
This will remove all the temporary comments (those with +++) and
leave the permanent comments.
There are special comments in the source that allow you to scan for
how to make changes to typical functions such as:
- RMVCHG
- RMVDLT
- RMVCPY
- RMVRNM
- RVMADD
- RMVF18
- MULTIHI
- NEWFKEY
- NEWOPT
See some of the later sections for how to make typical changes.
Designing your application and displays
---------------------------------------
You need to spend some time designing what you want to happen before
you start making any changes to the sample source. The instructions
in the source will be much more meaningful if you plan ahead. Here
are the things you need to consider and design before attempting to
modify any source:
1. How will the subfile be accessed? The source can be used to
provide:
- A command interface
- A program which is called as an option from
one of your menus
- A program which is invoked from a main program
- The main program could also be a subfile program
If you invoke the subfile program from a main program, do you
want any data to be passed back?
Determine the naming convention you will use for the source
members. You will have at a minimum the following source
members:
2 Data base files (One keyed and one Arrvl Seq)
1 Display file
1 RPG program
If you have a command interface, you will need source members
for:
1 Command definition
1 CL program
2. Create the data base files (if they do not already exist).
Externally described data is required. You need two files
over the same data.
- Keyed file. It may have a unique key.
- This file will be 'read only'
- Arrival sequence access path file.
- This file will have updates, adds, deletions
If the DMOSUBF2 approach is used, this
file is 'read only'
Either file may be the physical file. Both files could be
logical files over the same physical.
3. Change the WAITRCD parameter of the Arrival Sequence Access
path file to a small value (5 or 10 seconds). The program is
designed to provide descriptive displays for the user if
locked record conditions are found. You normally would not
want the user to wait a long time before the timeout occurred
(e.g. the 60 second default).
4. Determine the setting for the CTLKEY option. In the
demonstration, the value is passed in as a parameter, but you
would normally fix it to one setting in the program.
5. Determine if you want the 'Position to' function at the top of
the subfile display. If you do, what fields will be used.
6. Determine what the format of the subfile will look like. In
most applications, you can't place all the fields from the
record on one line in the subfile display. You need to
determine what fields will be displayed. Do you need to
change any of the fields (such as truncating a text
description) in order to show some information?
You should design the layout of the subfile display and
determine what headings you will use. Scratch paper is
probably adequate. In the code provided, the subfile records
start on line 9. The first field begins in position 7. The
width of each subfile column should be the longer of the field
length or the column heading. You should have at least 2
blank positions between fields.
For example, your scratch paper may look like:
7 18 25 47 ...
. . . .
. . . .
Customer Type Name State
XXXXX X XXXXXXXXXXXXXXXXXXXX XX
With this amount of information, you should be able to enter
the DDS specifications for both the column headings and
fields.
7. You should determine what fields you want on the 'Display of a
record' and the sequence of the fields. Do you need to edit
any date or numeric fields? Do you need to change any of the
values being displayed to make them more descriptive? For
example, you may have a field with a C or D in it and want it
to be displayed as:
C = Credit
D = Debit
8. If you want a 'Display only' type of Subfile (e.g. shown by
DMOSUBF2), you need to access a different set of sample
source. See the later discussion and ignore the points in
this section relative to Change/Add/Delete.
9. You should determine what fields you want on the 'Change/Add
record display' and the sequence of the fields. Do you need
to convert any of the values before they are displayed to the
user? Do you need to convert any of the values after the user
has made changes, but before the data is written to the data
base? For example, you may want the user to key *YES or *NO,
but you may want Y or N in the data base.
10. Will you allow the user to change the key fields of an
existing record?
11. Most applications that add a record will want to ensure that
the user has not pressed an inadvertent Enter key and added a
record with mostly blank fields. You will probably want to
ensure that some critical fields are not blank or zero.
12. You should determine what validity checking (if any) needs to
be performed on the fields that will be entered on the
Change/Add display and the approach that will be used:
- DDS validity keywords (e.g. VALUES)
- RPG code to set an indicator for the
DDS ERRMSG keyword (the text of the
message is in DDS)
- User defined messages kept in the RPG
program array
13. The sample code provides for the options of display, change,
and delete. Do you want all of these options? Are there
other options you will need? See the later section on adding
and removing options.
If your subfile is only going to support 'Display only'
functions, then you should use the DMOSUBF2 approach (see the
later discussion).
14. The sample code provides for F6 to enter 'Add mode' to enter
new records. Do you want this function? If not, there are
instructions in the source for how to remove the function.
The sample code provides for the F18 function in Add mode to
allow duplicating the fields from the prior record. Do you
want this function? If not, there are instructions in the
source for how to prevent the function.
15. Are there other command keys that you want to support or not
support? See the later section on how to do this.
16. The sample code provides for 2 standard parameters to be
passed. Additional parameters may be passed in for the
'position to' function. See the next section which describes
the parameters.
Parameters passed to the RPG program
------------------------------------
When you call the RPG program (either from the optional CL program or
your own program), you must pass a parameter list (It would also be
possible to delete the parameter list and initialize default values
for the parameters).
Two parameters are standard (must be passed) and additional
parameters are optional for the 'position to' function. You can also
have additional parameters for your own unique requirements.
** First parameter ZZLRST - LR status - *CHAR LEN(8)
-- *ON. This sets on LR at the end of the program. The
user ends the program by pressing F3 or F12.
-- *ONIMMED. This sets on LR and ends the program
immediately. The subfile is not displayed. Use
*ONIMMED only if you have used *OFF prior.
-- *OFF. If you are going to be calling the program
frequently and want the program to remain active and
the files open, specify *OFF until you are ready to
end. To end, you would normally use *ONIMMED.
** Second parameter ZZRTNC - Return code - *CHAR LEN(8)
-- The normal returned value is GOOD.
-- If *FULLEQ or *HIGHEQ has been specified for the CTLKEY
value and the 'position to' value does not exist in the
data base file, a value of NOTFOUND is passed back.
The NOTFOUND value lets you handle the exception if you
are calling the program from another HLL program.
** 'Position to' parameters.
-- The 'position to' parameters are optional. They allow
you to pass in values to cause the 'position to'
function to be used. This allows you to control the
first record that appears in the subfile display.
Normally, you would have one parameter per key field.
Tailoring the code
------------------
The instructions will tell you to scan the source for +++Req and read
what to do. It is not necessary that you read the comments that do
not have +++Req at the beginning of them or the actual source code.
You do not need to understand the logic of the program for typical
use.
The +++Req comments are what you should focus on first to get a
working program. This includes:
- The parameters to be passed in
- The setting of the ZZCTLK field
- 'Position to' function
- Fields and headings for the subfile
- Fields and descriptions for the Detail Record display
and the Change/Add record display
After the program is working, you can then begin to tailor it such as
the following:
- Remove the functions you don't need
- Control the record keys which appear
- Add any additional options or function keys
- Add validity checking
- Add help text
See the later sections on how to do these functions. When you
determine what you want, you should be able to scan the source for a
scan value like NEWFKEY to assist you in making changes. The
+++Optional comments will describe what to do.
When you are ready to copy the sample code, perform the following
steps:
1. If you don't want a command interface, skip to step 2.
For a command interface, prompt for DUPSTDSRC as described
earlier.
DUPSTDSRC MBR(xxx) SRCTYP(*SUBFCMD) ...
If you want a 'Display only' subfile, the SRCTYP should be
*SUBF2CMD.
-- Use SEU to display the source that was just generated.
Scan the source for +++Req and follow the instructions
to tailor the command interface.
-- Create the command and specify a name of a CL program
(in the PGM parameter) to be created in the next step.
2. If you don't want a CL program interface, skip to step 3.
-- Duplicate the CL source to your member with:
DUPSTDSRC MBR(xxx) SRCTYP(*SUBFCLP) ...
If you want a 'Display only' subfile, the SRCTYP should be
*SUBF2CLP.
-- Use SEU to display the source that was just generated.
Scan the source for +++Req and follow the instructions
to tailor the CL program.
-- Create the CL program.
3. Duplicate the display file source to your member with:
DUPSTDSRC MBR(xxx) SRCTYP(*SUBFDSPF) ...
If you want a 'Display only' subfile, the SRCTYP should be
*SUBF2DSPF.
4. Use SEU to display the source that was just generated. Scan
the source for +++Req and follow the instructions to tailor
the display file.
It is generally a good idea to work on the help text after you
are satisfied with the function of the application. The help
text provided is in two forms:
-- Standard help text for F keys, options, and general
display help. This will require some tailoring on your
part for the specifics of your application.
-- Field help text. A sample is provided for the MLFILE
field. The same help format is accessible from any
display where the MLFILE field appears. You can use
this as a sample for how to add your own help text.
If you don't want any help text or just the help text for the
standard functions, there are instructions in the source for
what you should delete.
5. Create the display file.
6. Duplicate the RPG source to your member with:
DUPSTDSRC MBR(xxx) SRCTYP(*SUBFRPG) ...
If you want a 'Display only' subfile, the SRCTYP should be
*SUBF2RPG.
7. Use SEU to display the source that was just generated. Scan
the source for +++Req and follow the instructions to tailor
the RPG program. Adding validity checking to ensure that good
data will be placed in the data base can take some time to do
correctly. You may prefer to get a working program before
concentrating on most of the validity checking (when your are
working on the +++Req functions, you can modify the
demonstration code to provide a few specific samples for your
situation).
8. Create the RPG program.
9. Give it a try.
10. After the program is working, you can begin to tailor it as
described in later sections. The display file and program
source contain 'scan values' in the optional sections which
describe how to tailor the program. When you scan, you will
find +++Optional comments that will assist you in making
changes.
11. When the program is complete, you will probably want to remove
all of the +++ comments. Use the RMVSRCCMT TAA Tool to do
this.
Adding or Removing options on the subfile display
-------------------------------------------------
In some applications you may not want the full capability to display,
change, delete, copy, rename, or add. In some cases, you may want to
provide for additional options.
If you are going to provide a 'Display only' subfile (no
Change/Add/Delete) then you want to start with the DMOSUBF2 source as
described in the previous section.
A typical change you might want to make to the Change/Add/Delete
subfile approach would be to remove the delete option. To do this
you should scan the display file source and the RPG source for
RMVDLT. Then follow the instructions. You can leave most of the
code in the objects (e.g. the Confirm Deletes subfile). If you
prevent the option, the associated format cannot be displayed.
You can also remove the Change option. To remove the Change option
you would scan the display file source and the RPG source for RMVCHG.
Then follow the instructions. You can leave most of the code in the
objects (e.g. the Change display). If you remove the Option, the
Change format cannot be displayed.
The same concept exists for the Copy or Rename options. To remove
these options scan for RMVCPY or RMVRNM.
If you have an application where the subfile is being used to assist
in identifying a master record ID (e.g. customer number), you may
want to add a 'Specify' option. This would allow the program to
return some critical fields which identify the selected record. See
the later section.
You can change or add options to the subfile display, by doing the
following:
** Scan the display file source for NEWOPT and follow the
instructions.
** If you add an option, you may need a new DDS format to process
the option. You may need to add new help text formats to
provide help text for the new display.
** Scan the RPG program source for NEWOPT. This is where the
options are checked. A SELEC statement is used for the
options. Use the WHEQ operation and EXSR to a subroutine to
process the option.
Depending on the type of option you need, you may have to
consider the following.
-- An F3 and/or F12 function key to allow the user to
cancel the option.
-- If you are going to call a sub program and receive back
a key field to use for a 'position to' function, see
the later discussion.
Adding or Removing Function keys
--------------------------------
You may want to add or remove function keys.
A typical example would be to prevent 'Add mode'. To do this, scan
the display file source for RMVADD and follow the instructions. You
do not have to remove all of the code associated with adding records
in the display file or RPG program. There are no changes needed to
the RPG program (the code would never be executed).
Another typical change you might want to make is to remove the F18
key function (duplicate from previous record). To do this, scan the
display file source for RMVF18 and follow the instructions. There
are no changes needed to the RPG program (the code would never be
executed).
To add a command key for a specific function (e.g. a search
capability) to the subfile display, scan both the display file and
RPG source for NEWFKEY. The optional comments will assist you in
placing your Function key on the correct screen and providing prompts
and help text.
Adding a 'Specify' option
-------------------------
In some applications, you will want to use a sub-program to assist
the user in identifying the proper record such as a customer number,
a part number etc.
If the user does not know the identifying number, you might provide a
Function key which would call a subfile program. The subfile would
be displayed in some order to assist the search (e.g. customer
name). The user should be allowed 5=Display to assist in determining
the proper record. You would need to decide whether the Change, Add,
or Delete options would be valid. If you want a 'Display only'
subfile, start with the source associated with the DMOSUBF2
demonstration.
When the proper record is determined, the user could enter a value on
the subfile display saying 'This is the one I want'. The term
'Specify option' will be used for this.
Assume you want to add '7=Specify' as a new option on the subfile
display. When the option is selected, the program would return
immediately and pass back identifying fields (e.g. customer number)
to the main program. The first '7' entered would cause this function
(any additional 7s entered would be ignored).
You would need some indication that the user did not select any
record, but is returning based on F3 or F12.
Normally, you would want this type of a 'search' program to remain
open to avoid the overhead of activating the program and opening the
files. See the later section.
To implement a 'Specify option', the typical solution would be:
** Add parameters to be passed to/from the program that would be
used to identify the record that was selected.
** Be sure the identifying fields are in the subfile. You may
need to make them hidden fields.
** Remove any options you don't want or start with the DMOSUBF2
'Display only' type of Subfile.
** Add the 'Specify option' as described in the section on Adding
or Removing Options. The instructions tell you to add a
subroutine to process the option.
You would probably specify something like:
ZZOPT WHEQ '8'
EXSR xxx
GOTO ZZEOP
In your subroutine, if you were going to pass back the MLFILE
and MLNAME fields from the demonstration code, you would
specify:
MOVE MLFILE ZKKEY1
MOVE MLNAME ZKKEY2
GOTO ZZEOP
The branch to ZZEOP is the normal 'end of program' function.
** Scan the RPG program for F3USE. Insert some code to tell the
main program that the user did not specify a record, but
returned with F3 or F12.
For example, you might blank out the identifying fields and
use this as a convention that nothing was specified. If you
were going to pass back blank values for the MLFILE and MLNAME
fields from the demonstration code, you would specify:
MOVE *BLANKS ZKKEY1
MOVE *BLANKS ZKKEY2
Another solution would be to set a special value in the ZZRTNC
parameter which is always passed back.
Pre-Opening and the 'LR Status' function
----------------------------------------
To speed up the processing of the program, you may want to pre-open
the files with the OPNDBF command or use the 'LR status' function in
the first parameter.
** Pre-Opening of shared files.
If you operate from a menu, you could pre-open the data base
files used by the program such as:
OVRDBF FILE(Keyed file) SHARE(*YES)
OVRDBF FILE(Arrival Seq file) SHARE(*YES)
OPNDBF FILE(Keyed file) OPTION(*INP)
OPNDBF FILE(Arrival Seq file) OPTION(*ALL)
Pre-opening a shared file keeps the files open so that the
subfile program would open the same shared open data path.
This would improve the performance of the program if you were
going to invoke it multiple times.
You can use the same open data path (ODP) of the Arrival
Sequence file with any other program within the same job. The
only requirement would be that the other program must position
the file cursor before using it. The subfile program always
positions the cursor by relative record number before any
action is taken.
The keyed file can be shared with another program in the same
job, but not if the other program is called from the subfile
program. The reason for this is that the cursor position is
set when the program begins and is used for rollup.
** Keeping the program active (LR status function)
To keep the program active (files open, fields initialized
etc.) when it is ended, use *OFF as the first parameter (LR
status) until you want to end. This causes a return with LR
off.
If you have a subfile program that will be invoked frequently
from the same job, the best performing solution is to call the
program with the first parameter set to *OFF.
When you want to end the program, use *ONIMMED. This causes
an immediate end of the program with LR on.
There is more job overhead (e.g. larger PAG) associated with
the leaving the program active than the use of pre-opening of
files. If your PAG is not excessively large, it is generally
a good tradeoff to leave the program active.
Multiple High Order Key Fields
------------------------------
The program assumes that for the *HIGHEQ and *HIGHEQA settings that
you want to restrict to a single high order key field.
If you have multiple high order key fields that are part of the
restricted set, scan the program for MULTIHI and follow the
instructions.
Modifying Help Text
-------------------
All of the screens support standard help formats to supply help text.
The help text is provided in windows that will appear over the
display they were invoked from.
The field -File- has sample help text provided. The same help text
is accessible from any display where -File- is available. You can
use it as a sample of how to do help text.
There are also two formats provided (UHDUMY and UHDUMY20) to show how
to write help text when the information is greater than the size of
one window. These formats are in the source, but are not used in the
demonstration.
You can scan for DFNHELP to assist you in entering changes for help
text.
You can move all of the help text formats to a separate file.
Instructions exist to assist you. There is a special TAA Tool to
assist you in doing this. The FIXHLPRCD TAA Tool will update the
source statements for the HLPRCD keyword and allow you to add a file
name or a qualified file name to the existing keywords.
Reducing the size of the objects
--------------------------------
If you are not using all of the function, you can reduce the size of
the objects without a lot of effort. The following are gross things
you can do:
** If you are not using the delete function
Delete the following formats from the display file source:
ZZSFL2C
ZZSFL2
ZZSLF2B
ZZSPC4
ZHSFL2A1
ZHSFL2Z1
Scan the RPG program for ZZDLT and delete all the statements.
You will need to determine where the end of IF groups are.
Delete the entire ZZDLT subroutine.
Scan for ZZSFL2. Delete the File continuation spec.
** If you are not using both Change and Add Mode (No changes or
additions occur).
Delete the following formats from the display file source:
ZZCHG1
ZZCHG2
ZZSPC1
ZZSPC2
ZZSPC3
ZHCHG1A1
ZHCHG1Z1
ZHCHG1Z2
ZHCHG2A1
ZHCHG2Z1
ZHCHG2Z2
Scan the RPG program for the following and delete all the
statements. You will need to determine where the end of IF
groups are.
ZZCOM including the subroutine
ZZCHG including the subroutine
ZZNEW including the subroutine
ZZADD
ZZVAL including both subroutines
91 any reference to indicator 91
96 any reference to indicator 96
Change the F spec for the Arrival sequence file so that Add (A
in position 66) is not requested.
If you also dropped the 4=Deletes function, the Arrival sequence file
will no longer be updated. Change from Update (U in position 15) to
I for Input.
** If you don't need the second display for the Detail Record
display.
Delete the following formats from the display file source:
ZZDSP2
ZHDSP2A1
ZHDSP2Z1
ZHDSP2Z2
Scan the RPG source for ZZDSP2. Just prior to the EXFMT is a
GOTO to ZZCOMZ. You can delete the GOTO and all statements to
the end of the subroutine.
** If you don't need the Copy and Rename options you can delete
some formats and subroutines.
Delete the following formats from the display file source:
ZZCPY1
ZHCPY1A1
ZHCPY1Z1
ZHCPY1Z2
bkp
Delete the code in the following subroutines:
ZZCPYB
ZZCPY
ZZRNM
Restrictions
------------
None.
Selecting records to be placed in the subfile
---------------------------------------------
If your application should not place every record read into the
subfile, the normal solution would be to add selection criteria to
the RPG program. Scan the source for SELRCD for the point to add
your selection criteria.
Note that at this point, the program may attempt to read a record
that will not fit on the page. This is needed to allow proper
positioning of the 'More' and 'Bottom' indication. If the record
will not fit on the page, the same code is executed again after
rollup occurs. If you are placing an indication in an array of what
records you have written to the subfile, you will need to be
sensitive to this double reading of the record.
Another alternative for selecting records would be to use OPNQRYF in
the CL program. OPNQRYF could be a good choice if you are reading by
keys and you can vastly reduce the number of records read by using
the selection capability of OPNQRYF.
Prerequisites
-------------
The following TAA Tools must be on your system:
ADJVAR Adjust variable
FILEFDBCK File feedback
HLRMVMSG HLL Remove message
LOCKMSG Producing a message on a locked record
SNDCOMPMSG Send completion message
SNDESCMSG Send escape message
Implementation
--------------
The demonstration is ready to use. Follow the previous instructions
to copy the source and begin creating your own application version.
Objects used by the tool
------------------------
Object Type Attribute Src member Src file
------ ---- --------- ---------- ----------
DMOSUBF *CMD TAASTDB QATTCMD
DMOSUBF2 *CMD TAASTDC QATTCMD
TAASTDBC *PGM CLP TAASTDBC QATTCL
TAASTDBC2 *PGM CLP TAASTDBC2 QATTCL
TAASTDCC *PGM CLP TAASTDCC QATTCL
TAASTDBR *PGM RPG TAASTDBR QATTRPG
TAASTDBR2 *PGM RPG TAASTDBR2 QATTRPG
TAASTDCR *PGM RPG TAASTDCR QATTRPG
TAASTDBK *FILE PF TAASTDBK QATTDDS
TAASTDBA *FILE LF TAASTDBA QATTDDS
TAASTDBD *FILE DSPF TAASTDBD QATTDDS
TAASTDCD *FILE DSPF TAASTDCD QATTDDS
Structure
---------
DMOSUBF Cmd
TAASTDBC CL pgm
TAASTDBR RPG pgm
TAASTDBD Display file
DMOSUBF2 Cmd
TAASTDCC CL pgm
TAASTDCR RPG Pgm
TAASTDCD Display file
The TAASTDBC2 CL program and TAASTDBR2 RPG program
are used for
refreshing the data used by the two commands.
|