Now that you’ve defined your maps, you can think about writing them to a terminal. The terminal to which you write, of course, is the one that sent the input and thereby invoked the transaction. This is the only terminal to which a transaction can write directly.
The EXEC CICS SEND MAP command writes formatted data to a terminal. It looks like this:
EXEC CICS SEND MAP(name
) MAPSET(name
) options ... END-EXEC
The items in this macro are:
This specifies the name of the map you want to send. It is limited to 1–7 characters and it’s required. Put it in quotes if it’s a literal.
This specifies the unsuffixed name (1–7 characters) of the mapset that you want to send. The mapset must reside in the CICS program library. The mapset can be defined either by using RDO or by the autoinstall program when the mapset is first used. If this option is not specified, the name given in the MAP option is assumed to be that of the mapset.
The number of maps per mapset is limited to a maximum of 9998. Put the name in quotes if it’s a literal.
There are a number of options that you can specify; they affect what’s sent and how it is sent. Except where noted, you can use any combination of them. The possibilities are:
This means the same thing in the SEND command as it does in the DFHMSD and DFHMDI macros for the map: it causes the audible alarm to be sounded. The alarm sounds if you specify ALARM in either the map definition or the SEND command.
This can be used in two ways to position the cursor. If you specify a value after CURSOR, it’s the relative position on the screen where the cursor is to be put. Use a single number, such as CURSOR(81) for line 2, column 2 (counting starts at zero and goes across the lines, which on an IBM 3270-system display Model 2 are 80 characters wide). Why column 2? Because the attribute byte goes in column 1, and we want the cursor to appear under the first character of data.
Alternatively, you can specify CURSOR without a value, and use the length subfields in the output map to show which field is to get the cursor; see Positioning the Cursor. In general, we recommend you to position the cursor in this second manner, rather than the first, so that changes in the map layout don’t lead to changes in the program. Both kinds of CURSOR specification override the cursor placement specified in the map.
This is the logical opposite of MAPONLY. You use it to modify the variable data in a display that’s already been created. Only the data from your program is sent to the screen. The constants in the map aren’t sent; so you can use this option only after you’ve sent the same map without using the DATAONLY option. We’ll see an example when we send the results of a name search to the terminal in program NACT01.
This causes the entire screen to be erased before what you’re sending is shown.
This in contrast to ERASE, causes just the unprotected fields on the screen (those with either the UNPROT or NUM attribute) to be erased before your output is placed on the screen. It’s most often used in preparing to read new data from a map that’s already on the screen. Don’t use it at the same time as ERASE; ERASE makes ERASEAUP meaningless.
This turns off the modified data tag in the attribute bytes for all the fields on the screen before what you’re sending is placed there. Once set on, whether by the user or the program, a modified data tag stays on until turned off explicitly, even over several transmissions of the screen. It can be turned off by the program sending a new attribute byte, an FRSET option, or an ERASE, or an ERASEAUP, or by the user pressing the CLEAR key. Like ERASEAUP, the FRSET option is most often used in preparing to read new data from a map already on the screen. It can also reduce the amount of data resent on an error cycle, as we’ll explain in coding our example.
This means the same thing as it does in the map definition: the keyboard is unlocked if you specify FREEKB in either the map or the SEND command.
This specifies that only default data from the map is to be written. In our example application, this option is used when we send the menu map the first time, because there is no information to put into it.
This allows the output of a SEND command to be printed on a printer, just as it does in the map definition. It is in force if specified in either the map or the command.
This causes the printer to restore the paper to the top of the next page before the output is printed. This specification has no effect on maps sent to a display, to printers without the features which allow sensing the top of the form, or to printers for which the formfeed feature is not specified in the CICS Terminal Control Table.
The first time a map is sent to a terminal occurs in program NACT01, the menu screen is displayed. The command we need is:
EXEC CICS SEND MAP('ACCTMNU') MAPSET(WS-LITS-MAPSET) CURSOR(EIBCPOSN) MAPONLY FRSET FREEKB RESP(RESPONSE) RESP2(REASON-CODE) END-EXEC
The option MAPONLY states that only the constants within your map are to be sent, so initializing the screen. NACT01 uses the DATAONLY option when the screen has the constants displayed and only the data fields are to be sent. If either of these options is not set then both the constants and the data are sent. CICS would expect the data to be used for filling in the map to be in a structure whose name is the name (as specified in the MAP option) suffixed with the letter O. So, when we issue the command:
EXEC CICS SEND MAP('ACCTDTL') MAPSET(WS-LITS-MAPSET) ERASE FREEKB CURSOR RESP(RESPONSE) RESP2(REASON-CODE) END-EXEC
CICS expects the data for the map to be in a structure within the program (of exactly the sort generated by the map structure generation) named ACCTDTLO. This structure is usually in your WORKING-STORAGE section, but it might be in a LINKAGE area instead.
There’s an option on the SEND MAP command that lets you specify a data structure other than the one assumed by CICS. We won’t cover it here, but you can find guidance on using it in the CICS Application Programming Guide.
Let’s look at the more common situation in which we’re merging program data into the map. In program NACT01, we’re supposed to build a detail display map for one record and send it to the screen. Since the contents of the screen vary somewhat with the type of request, and we’re using the same screen for all types, this entails the following:
Putting the appropriate title on the map (add, modify, or whatever it happens to be).
Moving the data from the file record to the symbolic map (except for adds).
Adjusting the attribute bytes. The input fields must be protected in a display or delete operation; the verify field must be unprotected for deletes, and the titles at the bottom of the screen must be made nondisplay for adds.
Putting the appropriate user instructions (about what to do next) into the message area.
Putting the cursor in the right place.
Examples Example 11-4 through Example 11-7 show how the necessary code might look for the display of a record.
Example 11-4. Building the Acount Detail Display Map (Part 1)
PERFORM BBAB-MOVE-TO-DETAIL-MAP MOVE -1 TO SNAMEDL MOVE 'PRESS "CLEAR" OR "ENTER" TO RETURN TO THE MENU WHEN FINISHED' TO MSGDO PERFORM BBAC-PROTECT-DETAILS SET CA-DISPLAYING TO TRUE
The need to move the details read from the file to the map area occurs in several places, so it has been placed in a common routine (BBAB-MOVE-TO-DETAIL-MAP). In order to ensure that the cursor is placed at the beginning of the surname field, its Length field is set to the special value of -1. (More about this later.) An explanatory/operational message is also placed in the map for transmission to the user. Finally the details on display are not modifiable, so we need to protect them by setting their attributes to autoskip (ASKIP). This requirement also occurs in several places so it has been placed in a common routine (BBAC-PROTECT-DETAILS).
Example 11-5. Building the Account Detail Display Map (Part 2)
BBAB-MOVE-TO-DETAIL-MAP SECTION. * * This routine populates the detail map from the data obtained. * BBAB-010. MOVE ACCTDO IN NACTREC-DATA TO ACCTDO IN ACCTDTLO MOVE SNAMEDO IN NACTREC-DATA TO SNAMEDO IN ACCTDTLO MOVE FNAMEDO IN NACTREC-DATA TO FNAMEDO IN ACCTDTLO MOVE MIDO IN NACTREC-DATA TO MIDO IN ACCTDTLO MOVE TTLDO IN NACTREC-DATA TO TTLDO IN ACCTDTLO MOVE TELDO IN NACTREC-DATA TO TELDO IN ACCTDTLO MOVE ADDR1DO IN NACTREC-DATA TO ADDR1DO IN ACCTDTLO MOVE ADDR2DO IN NACTREC-DATA TO ADDR2DO IN ACCTDTLO MOVE ADDR3DO IN NACTREC-DATA TO ADDR3DO IN ACCTDTLO MOVE AUTH1DO IN NACTREC-DATA TO AUTH1DO IN ACCTDTLO MOVE AUTH2DO IN NACTREC-DATA TO AUTH2DO IN ACCTDTLO MOVE AUTH3DO IN NACTREC-DATA TO AUTH3DO IN ACCTDTLO MOVE AUTH4DO IN NACTREC-DATA TO AUTH4DO IN ACCTDTLO MOVE CARDSDO IN NACTREC-DATA TO CARDSDO IN ACCTDTLO MOVE IMODO IN NACTREC-DATA TO IMODO IN ACCTDTLO MOVE IDAYDO IN NACTREC-DATA TO IDAYDO IN ACCTDTLO MOVE IYRDO IN NACTREC-DATA TO IYRDO IN ACCTDTLO MOVE RSNDO IN NACTREC-DATA TO RSNDO IN ACCTDTLO MOVE CCODEDO IN NACTREC-DATA TO CCODEDO IN ACCTDTLO MOVE APPRDO IN NACTREC-DATA TO APPRDO IN ACCTDTLO MOVE SCODE1DO IN NACTREC-DATA TO SCODE1DO IN ACCTDTLO MOVE SCODE2DO IN NACTREC-DATA TO SCODE2DO IN ACCTDTLO MOVE SCODE3DO IN NACTREC-DATA TO SCODE3DO IN ACCTDTLO MOVE STATDO IN NACTREC-DATA TO STATDO IN ACCTDTLO MOVE LIMITDO IN NACTREC-DATA TO LIMITDO IN ACCTDTLO * END-BBAB-MOVE-TO-DETAIL-MAP. EXIT.
Each field is moved individually to the map area. This looks a bit tedious when coding, but is something which must be done. With a good block editor, this can be done in just a few minutes.
Example 11-6. Building the Account Detail Display Map (Part 3)
BBAC-PROTECT-DETAILS SECTION. * * This routine protects the detail data fields from modification. * BBAC-010. MOVE DFHBMASK TO SNAMEDA FNAMEDA MIDA TTLDA TELDA ADDR1DA ADDR2DA ADDR3DA AUTH1DA AUTH2DA AUTH3DA AUTH4DA CARDSDA IMODA IDAYDA IYRDA RSNDA CCODEDA APPRDA SCODE1DA SCODE2DA SCODE3DA * END-BBAC-PROTECT-DETAILS. EXIT.
All of the data fields on the screen need to be protected from modification, so the same attribute (DFHBMASK, AUTOSKIP) is set for all of them.
Finally, the SEND MAP command instructs BMS to create and send a data stream to the device by identifying which MAP to use (ACCTDTL) in which MAPSET. Note this latter option references a data name which is included in source code which is copied into the program. The reason for this is to allow flexibility in naming of the objects referenced by the application. The ERASE option is included to ensure residual data on the screen is removed. The FREEKB option ensures that the user is able to continue work without needing to reset the device. The CURSOR option is explained in the following section. The RESP option is used in order to allow the program to deal with an abnormal return in a standard way.
We said earlier how vital it is to put the cursor where the user wants to start entering data on the screen. One small piece of source code from you can save hundreds of users a couple of seconds each and every time they use your application.
In the first SEND MAP, we relied on the cursor position specified in the map definition. This puts the cursor under the first data position of the surname field, which is where we want it. In subsequent uses, however, we don’t necessarily want the cursor where the map definition puts it. Where we’re using the detail map, we want to use the map default (the LNAMED field) for adds and modifies. For display operations, it doesn’t matter much, there are no fields into which the user may key. For deletes, however, the cursor should be under the verify (VFY) field. In the case of user input errors, we want the cursor under the first field where the user entered incorrect information.
As we said, there are two ways to override the position specified by the IC specification in the map definition:
You can specify a screen position, relative to line 1, column 1 (that is, position 0) in the CURSOR option on the SEND MAP command. (This can be used to ensure that the cursor remains in the same position that the user left it by using the EIBCPOSN field as the argument. This field is described along with the others in the special CICS control area called the EXEC Interface Block (EIB) later.)
You can show that you want the cursor placed under a particular field by setting the associated length subfield to minus one (–1) and specifying CURSOR without a value in your SEND MAP command. This causes BMS to place the cursor under the first data position of the field with this length value. If several fields are flagged by this special length subfield value, the cursor is placed under the first one (as opposed to the last one with ATTRB=IC).
The second procedure is called symbolic cursor positioning, and is a very handy method of positioning the cursor for, say, correcting errors. As the program checks the input, it sets the length subfield to –1 for every field found to be in error. Then, when the map is redisplayed for corrections, BMS automatically puts the cursor under the first field that the user has to correct.
To place the cursor under the verify field on a delete, therefore, all we have to do is:
MOVE -1 TO VFYDL
and specify CURSOR in our SEND MAP command.
In addition to the EXEC CICS SEND MAP command, there is another terminal output command called SEND CONTROL. It allows you to send control information to the terminal without sending any data. That is, you can free/unlock the keyboard, erase all the unprotected fields, and so on, without sending a map.
The SEND CONTROL command looks like this:
EXEC CICS SEND CONTROL options ... RESP(RESPONSE) RESP2(REASON-CODE) END-EXEC
The options you can use are the same as on a SEND MAP command: ERASE, ERASEUP, FRSET, ALARM, FREEKB, CURSOR, PRINT, and FORMFEED.
There’s an example of this command in program NACT01. The terminal user has just cleared the screen (of the menu map) to indicate that they want to exit from the control of the online account application. The program is supposed to free/unlock the keyboard before returning control to CICS.
Normally, you would do this when writing a message to the terminal. But since we’re not doing that at this point, we must free/unlock the keyboard by an explicit command, instead. Within the sample application the command is:
BA-SEND-CONTROL SECTION. * * End the pseudo-conversational series of tasks. * Free the user's keyboard and end without saving * any data. * BA-010. EXEC CICS SEND CONTROL FREEKB ERASE RESP(RESPONSE) RESP2(REASON-CODE) END-EXEC
We’ve added the ERASE option to the previous command, so that the user would be ready to start a new transaction. This isn’t strictly necessary if the user has just cleared the screen, but no harm is done to include it.
There are two ways to receive input from a terminal, either from the RECEIVE MAP command or from input from the keyboard.
When you want to receive input from a terminal, you use the RECEIVE MAP command, which looks like this:
EXEC CICS RECEIVE MAP(MAPNAME) MAPSET(MAPSETNAME) RESP(RESPONSE) RESP2(REASON-CODE) END-EXEC.
The MAP and MAPSET parameters have exactly the same meaning as for the SEND MAP command. MAP is required and so is MAPSET, unless it is the same as the map name. Again, it does no harm to include it for documentation purposes.
The form of the RECEIVE MAP command below does not specify where the input data is to be placed. This causes CICS to bring the data into a structure whose name is the map name suffixed with the letter I, which is assumed to be in either your WORKING-STORAGE or LINKAGE area.
For example, program NACT01 requires that we receive the filled-in account detail map. The command to do this is:
* DA-RECEIVE-DETAIL SECTION. * * This routine get the detail input from the user. * DA-010. MOVE LOW-VALUES TO ACCTDTLI * EXEC CICS RECEIVE MAP('ACCTDTL') MAPSET(WS-LITS-MAPSET) RESP(RESPONSE) RESP2(REASON-CODE) END-EXEC
It brings the input data into a data area named ACCTDTLI, which is expected to have exactly the format produced by the map generation structure ACCTDTL.
As soon as the map is read in, we have access to all the data subfields associated with the map fields. For example, we can test whether the user made any entry in the request field of:
IF REQML = 0
Or we could discover if the user erased the field:
IF REQMF = DFHBMEOF ...
Or we could examine the input in that field:
IF REQMI = 'A'
This last case is discouraged. Generally we need to retain the data the user has input in a separate area that we will keep across the pseudo-conversational series of transactions used to perform the business function. We will therefore need to merge the current user input with whatever had been entered (if relevant) in any previous CICS task relevant to this business operation. Thus any validation or logic determination will be performed from this special area rather than the input directly. One of the main reasons for this relates to the fact that the Input and Output map areas are really descriptions of the same storage as mentioned earlier.
Although it generally does not affect your program logic, you should be aware that the first time in a transaction that you use the RECEIVE MAP command, it has a slightly different effect from subsequent times. Since it is input from the terminal that causes a transaction to get started in the first place, CICS has always read the first input by the time the transaction starts to execute. Therefore, on this first RECEIVE MAP command, CICS simply arranges the input it already has into the format dictated by your map, and puts the results in a place accessible to your program.
On subsequent RECEIVE MAP commands in the same task, CICS actually waits for and reads input from the terminal. These subsequent RECEIVE MAP s are what make a task conversational. By contrast, a pseudo-conversational task executes at most one RECEIVE MAP command. This is the technique we use in the sample application.
There is another technique you may wish to use for processing input from a terminal. The 3270 input stream contains an indication of which attention key caused the input to be transmitted (Enter, Clear, or one of the PA or PF keys).
You can use the EXEC Interface Block Attention Identifier (EIBAID) field to change the flow of control in your program based on which of these attention keys was used.
Before we explain how to find out what key was used to send the input, we need to introduce one CICS control block. This is the EXEC Interface Block (EIB), and it is the only one that you need to know anything about for the type of applications described in this book.
You can write programs without using even this one, but it contains information that is very useful and is sometimes really essential.
There is one EIB for each task, and it exists for the duration of the task. Every program that executes as part of the task has access to the same EIB. You can address the fields in it directly in your COBOL program without any preliminaries. You should only read these fields, however, not try to modify them. All of the EIB fields are discussed in detail in the CICS Application Programming Reference, but the ones that are of general use follow.
Contains the attention identifier (AID) associated with the last terminal control (for example, which keyboard key was last pressed) or basic mapping support (BMS) input operation from a display device such as the 3270. It is coded as shown in later AID byte definitions.
Contains the length of the communication area that has been passed to the application program from the last program, using the COMMAREA and LENGTH options. If no communication area is passed, this field contains zeros.
Contains the position of the cursor (the cursor address) at the time of the last input command for 3270-like devices only. This position is expressed as a single number relative to position zero on the screen (row 1, column 1), in the same way that you specify the CURSOR parameter on a SEND MAP command. This field was mentioned earlier (in the section Positioning the Cursor) when indicating that there is a technique for retaining the current position of the cursor on the screen.
Contains the date the task is started; this field is updated by the ASKTIME command. The date is in packed decimal form (0CYYDDD+) where C shows the century with values 0 for the 1900s and 1 for the 2000s. For example, the dates 31 December 1999 and 1 January 2000 have EIBDATE values of 0099365 and 0100001, respectively.
Contains the symbolic identifier of the last data set (file) referred to in a file control request (command), for example, read a record, write a record.
Contains a code that identifies the last CICS command issued by the task in “PIC X(2)” format. The first byte of this two-byte field indicates the type of command. File commands have a code of X’06’, BMS commands are X’18’, and so on. The second byte tells which particular command: X’0602’ means READ, X’0604’ means WRITE, and so on. A list of the codes for the API appears in the CICS Application Programming Reference; a list of the codes for the SPI appears in the CICS System Programming Reference. These books are included on the CD-ROM that comes with this book.
Contains a number corresponding to the RESP condition that has been raised. There is a complete list of symbolic names for these numbers in the CICS Application Programming Reference.
Contains more detailed information that may help explain why the RESP condition has been raised. This field contains meaningful values for specific commands.
The values in the EIBRESP and EIBRESP2 fields of the EIB can also be interrogated using the RESP and RESP2 values on an EXEC CICS command; see Example 11-9.
Contains the symbolic identifier (name) of the resource being accessed by the latest executed command. For file commands, this value is the FILE parameter, so that EIBRSRCE has the same value as EIBDS after such a command. For BMS commands it is the name of the terminal (the four-character name of the input terminal, or EIBTRMID in the context of this book).
Contains the task number assigned to the task by CICS. This number appears in trace table entries generated while the task is in control. CICS assigns a sequential number to each task it executes, and this number is used to identify entries for the task in the Trace Table (if you want to know more about trace and dump refer to the CICS Problem Determination Guide).
Contains the time at which the current task started, also in “PIC S9(7) COMP-3” form, with one leading zero: “0HHMMSS+”. Note that for simpler date processing, we recommend the use of the ASKTIME and FORMATTIME commands.
Contains the name of the terminal (terminal or logical unit) associated with the task.
Contains the symbolic transaction identifier of the task.
Getting back to the attention identifier, we can also tell what key was used to send the input by looking at the EIBAID field, as noted above.
When a transaction is started,EIBAID is set according to the key used to send the input that caused the transaction to get started. It retains this value through the first RECEIVE command, which only formats the input already read, until after a subsequent RECEIVE, at which time it is set to the value used to send that input from the terminal.
EIBAID is one byte long and holds the actual attention identifier value used in the 3270 input stream. As it is hard to remember these values and hard to understand code containing them, it is a good idea to use symbolic rather than absolute values when testing EIBAID. CICS provides you with a precoded set which you simply copy into your COBOL program by writing:
COPY DFHAID.
in your WORKING-STORAGE SECTION. For other languages the data structure gets placed in a library along with similar copy or include statements to add it into your program in the normal way. Example 11-8 shows some of the definitions this brings into your program.
Example 11-8. The Standard Attention Identifier Values
01 DFHAID. 02 DFHNULL PIC X VALUE IS ' '. 02 DFHENTER PIC X VALUE IS ''''. 02 DFHCLEAR PIC X VALUE IS '_'. 02 DFHCLRP PIC X VALUE IS ' '. 02 DFHPEN PIC X VALUE IS '='. 02 DFHOPID PIC X VALUE IS 'W'. 02 DFHMSRE PIC X VALUE IS 'X'. 02 DFHSTRF PIC X VALUE IS ' '. 02 DFHTRIG PIC X VALUE IS '"'. 02 DFHPA1 PIC X VALUE IS '%'. 02 DFHPA2 PIC X VALUE IS '>'. 02 DFHPA3 PIC X VALUE IS ','. 02 DFHPF1 PIC X VALUE IS '1'. 02 DFHPF2 PIC X VALUE IS '2'. . . . . . . 02 DFHPF23 PIC X VALUE IS '.'. 02 DFHPF24 PIC X VALUE IS '<'.
DFHENTER is the Enter key, DFHPA1 is Program Attention (PA) Key 1, DFHPF1 is Program Function (PF) Key 1, and so on. As in the case of the DFHBMSCA macro, any values above that appear to be spaces are not; they correspond to bit patterns for which there is no printable character.
As we cover each group of commands in this book, we’ll discuss what can go wrong. We’ll classify errors according to the categories and suggest how you might want to handle them in your coding.
There is really only one type of error that we can expect to occur in the subset of BMS commands and map options that we’ve covered here. This is known as MAPFAIL. There are other types of failure and they are listed in the CICS Application Programming Reference.
MAPFAIL occurs on a RECEIVE MAP command when there are no fields at all on the screen for BMS to map for you. This happens if you issue a RECEIVE MAP after the user has pressed a Clear or a Program Attention key. These are known as “short-read” keys because the only data that flows from the termial is the keycode, no data from the terminal is passed. It can also occur even if the user does not use a short-read key. If, for example, you send a screen to be filled in (without any fields in which the map or the program turns on the modified-data tag), and the user presses the Enter key or one of the program function keys without keying any data into the screen, you’ll get MAPFAIL.
The reason for the failure is essentially the same in both cases. With the short read, the terminal does not send any screen data; hence no fields. In the other case, there are no fields to send; no modified-data tags have been turned on.
MAPFAIL is almost invariably a user error (and, hence, an expected program condition). It may occur on almost any RECEIVE MAP, and therefore you should handle it explicitly in the program. For instance, Example 11-9 shows the code that the example application contains to deal with a MAPFAIL that occurs when the menu map is received.
Example 11-9. Code to Handle MAPFAIL
BB-MENU-DATA-ENTERED SECTION. * * Obtain the input (if any) from the user. * BB-010. MOVE LOW-VALUES TO ACCTMNUI * EXEC CICS RECEIVE MAP('ACCTMNU') MAPSET(WS-LITS-MAPSET) RESP(RESPONSE) RESP2(REASON-CODE) END-EXEC * IF (RESPONSE NOT = DFHRESP(NORMAL)) AND (RESPONSE NOT = DFHRESP(MAPFAIL)) PERFORM Y-UNEXPECTED-ERROR END-IF
This code is designed to make the occurrence of MAPFAIL somewhat transparent to the program. It is important to realize the difference in what BMS does when there is and there is not data to map. If BMS finds data to map, it clears the target map area to nulls (LOW-VALUES) before setting up the appropriate Length, Flag and Input fields. If BMS finds no data to map, it immediately raises the MAPFAIL condition and leaves the target map area exactly as it was.
In order to ensure the basic logic of the program can proceed regardless of the input, it primes the target map area with LOW-VALUES (nulls) before requesting BMS services. We then detect that the response from BMS is acceptable by the test of the EIBRESP value. Note that the key causing the initiation of the transaction was tested before we reached this part of the program, so we know it isn’t the CLEAR key.
CICS allows one transaction (task) to start another one, as we noted in our discussion about printed output. The usual reason for doing this is the one that arose in our example: the originating task needs access to some facility it does not own, usually a terminal other than the input terminal. In our case, we needed a printer to print the log of account file changes. There are sometimes other reasons as well. You might want a task to be executed at a particular time, or you might want it to run at a different priority from the original task, for instance.
The command to start another task is:
EXEC CICS START TRANSID(name
) TERMID(termid
) FROM(data-area
) LENGTH(data-value
) options END-EXEC
The options for this command are:
Specifies the identifier (1–4 characters) of the transaction that is to be started. This parameter is required. If the identifier is a literal, enclose it in quotes.
Specifies the symbolic identifier (1–4 alphanumeric characters) of the principal facility associated with a transaction to be started as a result of a START command. When this parameter is omitted the started task runs without a principal facility.
Specifies the name of the data area that contains data to be passed to the transaction being started. This parameter is optional.
Specifies the length of the data to be passed for the new task.
Specifies the expiration time as an interval of time that is to elapse from the time at which the START command is issued. The mm and ss are each in the range 0–59. The time specified is added to the current clock time by CICS when the command is executed to calculate the expiration time.
Specifies the time when a new task should be started. When using the C language, you are recommended to use the AFTER/AT HOURS, MINUTES, and SECONDS options, as C does not provide a packed decimal data type. You may use TIME, but if the value specified is not an integer constant, the application is responsible for ensuring that the value passed to CICS is in packed decimal format.
If you don’t specify either INTERVAL or TIME, CICS assumes that you would like INTERVAL(0), which means right away.
If data is passed in the START command, the transaction that gets started uses the EXEC CICS RETRIEVE command to get access to this data. The syntax of the RETRIEVE command looks like this:
EXEC CICS RETRIEVE INTO(data-area)LENGTH(length) END-EXEC
Notice the difference between this RETRIEVE command and the RECEIVE command described in The RECEIVE MAP command. Both commands may be used to get the initial input to a transaction, but they aren’t interchangeable: RECEIVE must be used in transactions that are initiated by input from a terminal, and RETRIEVE must be used in transactions that were started by another transaction. The options for this command are:
Specifies the user data area into which retrieved data is to be written.
Specifies the length of the data area the retrieved data is written into.
In our sample application, program NACT01 uses the START command when a user asks for a record to be printed:
EXEC CICS START TRANSID(PRINT-TRANSID) TERMID(CA-PRINTER) FROM(ACCTDTLO) RESP(RESPONSE) RESP2(REASON-CODE) ENDEXEC
This START command tells CICS to start transaction PRINT-TRANSID as soon as possible after the printer whose name is in data area CA-PRINTER is available to be its terminal.
Program NACT03, running on behalf of this transaction, in turn issues the following RETRIEVE command to retrieve the data passed from program NACT01:
EXEC CICS RETRIEVE INTO(ACCTDTLI) RESP(RESPONSE) RESP2(REASON-CODE) END-EXEC
ACCTDTLO and ACCTDTLI refer to the symbolic map structure, located in WORKING-STORAGE in both programs. The map, of course, contains the data read by transaction NACT. This data is to be printed by transaction NACP.
A number of different problems may arise in connection with the START and RETRIEVE commands that we’ve described. Possible errors are:
Means that the CICS system support for temporary storage, which is required for START commands that specify the FROM option, was not present when a RETRIEVE command was issued. This error is an example of the system/application mismatch (category 4) described in Handling Errors in Chapter 4.
Means an input/output error on the temporary storage data set where the data to be passed is stored on a RETRIEVE or START command.
Occurs when the length of the data retrieved by a RETRIEVE command exceeds the value specified in the LENGTH parameter for the command. LENGERR usually means an error in the program logic.
Means that the requested data could not be found in temporary storage on a RETRIEVE command. If a task issuing a RETRIEVE command was not started by a START command, or if it was started by a START command with no FROM parameter (in other words, no data), this condition will occur. Again, it usually means a programming error.
Occurs when the terminal specified in the TERMID parameter in a START command cannot be found in the Terminal Control Table. During the test phase it usually indicates a problem in the program logic; on a production system, it usually means that something has happened to the terminal.
Means that the transaction identifier specified in a START command cannot be found in the list of installed transaction definitions. Like TERMIDERR, it usually means a programming error during the development of an application, or table damage if it occurs on a production system.