Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations wOOdy-Soft on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Cobol structure 2

Status
Not open for further replies.

claudeb

Programmer
Nov 23, 2000
140
CA
Could you please help me out with this one. What should I change in Program A to make it work with the new programs . I need to call program B to do few calculations (fund accumulation….).
Porgram A calls program B.
In program A, I have :

1/ OPEN INPUT MY-FILE-DATA-FILE + a close statement
2/ A select statement:
SELECT MY-FILE-DATA-FILE ASSIGN TO SYS024-MY-FILE
ORGANIZATION IS INDEXED
ACCESS IS DYNAMIC
RECORD KEY IS MY-FILE-CODE
FILE STATUS IS MY-FILE-DATA-FILE-STATUS.

3/ An FD statement
FD MY-FILE-DATA-FILE
LABEL RECORDS ARE STANDARD.
4/ A record layout

5/ A procedure that reads MY-FILE-DATA-FILE

PERFORM 1000-READ-MY-FILE
THRU 1000-READ-MY-FILE-X.

1000-READ-MY-FILE.
-----------------------------
IF MY-FILE-CODE = WS-PREV-MY-FILE-KEY
GO TO 1000-READ-MY-FILE-X.

READ MY-FILE-DATA-FILE RECORD KEY IS MY-FILE-CODE.

IF MY-FILE-READ-SUCCESSFUL
ADD 1 TO WS-MY-FILE-READ-CTR
MOVE MY-FILE-CODE TO WS-PREV-MY-FILE-KEY
ELSE
MOVE MY-FILE-CODE TO WS-REPORT-KEY
MOVE MY-FILE-DATA-FILE-STATUS TO WS-REPORT-STATUS
MOVE 'ERROR READ MY-FILE' TO WS-MESSAGE
PERFORM PROCEDURE-ERROR.

1000-READ-MY-FILE-X.
EXIT.
Program B has

1/ The same record layout
2/ Uses MY_FILE
DO-WHAT-EVER.
IF I = 0
MOVE BASIC-PLAN-CODE TO MY-FILE-PLAN-KEY
MOVE BASIC-RATE-SCALE TO MY-FILE-RS-KEY
ELSE
MOVE R-PLAN-CODE (I) TO MY-FILE-PLAN-KEY
MOVE R-RATE-SCALE (I) TO MY-FILE-RS-KEY
IF R-PLAN-LAST-3 (I) EQUAL '001' OR '002'
MOVE ORIGINAL-PLAN-CODE (I) TO MY-FILE-PLAN-KEY.

IF MY-FILE-KEY NOT = MY-FILE-CODE

PERFORM MY-FILE-1000-READ
THRU MY-FILE-1000-READ-X
IF NOT WMY-FILE-IO-OK
MOVE 'CC8045' TO WMSGS-MESSAGE-SOURCE
MOVE '0001' TO WMSGS-MESSAGE-NUMBER
MOVE POLICY-NUMBER TO WMSGS-PARM (1)
MOVE MY-FILE-KEY-PLAN-RS TO WMSGS-PARM (2)
PERFORM MSGS-1000-GENERATE-MESSAGE
THRU MSGS-1000-GENERATE-MESSAGE-X.
DO-WHAT-EVER-X.
EXIT.
MY-FILE-1000-READ.
*---------------------------
MOVE TFCMD-READ-RECORD TO MY-FILE-IO-COMMAND.
PERFORM MY-FILE-1000-LINK
THRU MY-FILE-1000-LINK-X.
MY-FILE-1000-READ-X.
EXIT.
Program B calls Program C (Sorry)
Program C includes
1/ A select statement identical to one in program A
2/ Same FD statement
3/ Same record layout
4/ A procedure to read the file
MY-FILE-1000-READ.
*---------------
IF MY-FILE-COMPANY-REQUIRED
DISPLAY 'MY-FILE-COMPANY-REQUIRED '
MOVE WGLOB-COMPANY-CODE TO MY-FILE-KEY-COMPANY
ELSE
MOVE SPACES TO MY-FILE-KEY-COMPANY.

MOVE MY-FILE-KEY TO MY-FILE-CODE.
MOVE 0 TO WMY-FILE-IO-STATUS.

READ MY-FILE-DATA-FILE
INVALID KEY

MOVE 7 TO WMY-FILE-IO-STATUS
GO TO MY-FILE-1000-READ-X.

IF MY-FILE-DATA-FILE-STATUS NOT = ZERO
PERFORM MY-FILE-HANDLE-ERROR
THRU MY-FILE-HANDLE-ERROR-X.

MY-FILE-1000-READ-X.
EXIT.
In case of error , I need the program to perform what is written in program A and not C.
Program C , is a « BATCH I/O ROUTINE FOR MY-FILE »
 
First, the OPEN statement goes in the Procedure Division, not before the SELECT/ASSIGN statements in the Environment Division. You select, assign, and define your files in the Environment and Data Divisions. You open, read, and close it in the Procedure Division.

So therefore, in Program A, your Procedure Division paragraph 1000-READ-MY-FILE would include OPEN INPUT MY-FILE-DATA-FILE.

Second, avoid GO TO's like the plague whenever possible. The only good use for a GO TO (other than a GO TO the end of a paragraph) is when you need to immediately shut down the program in case of an abend. This would usually happen in CICS (or other online) programming where you need a EXEC CICS RETURN immediately after the CICS error routine.

So the first sentence in 1000-READ-MY-FILE should be:

IF MY-FILE-CODE = WS-PREV-MY-FILE-KEY
PERFORM MY-FILE-1000-READ-X
END-IF. [not necessary but I like them. They help me keep my "ifs" aligned with the correct "end-if"s so that I know when the conditional expression ends.]

Okay, now for your call. You need a CALL [Program B] statement when you want to go to that program. Plus you have to put into linkage any data that you want to pass to Program B for Program B to process. Ditto when Program B makes the call to Program C.

So therefore, you have to say CALL [Program B] USING [Data-Area which is in Linkage]. And your Procedure Division has to be coded PROCEDURE DIVISION USING [Data-Area which is in Linkage].

Actually, I believe that the first calling program in your program chain can have the data being passed coded in Working Storage. In which case, the Procedure Division of Program A would be coded without the USING statement. But Program B's and Program C's data must be kept in the Linkage section of each program and therefore the USING clause must be coded in these programs. Believe me, your compiler will tell you if you aren't using the Linkage Divisions and USING phrases correctly.

And actually, many people like to store any data being passed back and forth in the Linkage Division. That is because if in the future, somebody wants to have Program X call Program A, then Program A doesn't have to be re-coded.

Remember that, after the call, Program B will return to the sentence directly after the CALL statement.

Hope this helps, Nina Too

 
Hi Nina,
Actually , i did all this . The error i get is
*** BATCH ERROR ROLLBACK AND LOG ***


AN ERROR WAS ENCOUNTERED WHILE PROCESSING
A BATCH PROGRAM.

PLEASE COPY DOWN THE FOLLOWING ERROR
NUMBER AND NOTIFY TECHNICAL SUPPORT.

ERROR NUMBER: 00108071128110
ERROR CODE : 92
FILE ID : MY-FILE
ERROR DESC. : READ RECORD

According to my documentation
Error 92: The record has been locked by another user (record unavailable)
So, i tried
PERFORM MY-FILE-3000-UNLOCK THRU
MY-FILE-3000-UNLOCK-X
...etc...
PERFORM MY-FILE-1000-READ THRU
MY-FILE-1000-READ-X
call program B
MY-FILE-3000-UNLOCK.
*-----------------
MOVE LOW-VALUES TO MY-FILE-CODE.
MOVE ZERO TO WMY-FILE-IO-STATUS.

MY-FILE-3000-UNLOCK-X.
EXIT.
 
Yep! If the record is locked, that will do it every time! I found that out one day while working on VSAM files.

When you do a VSAM READ for updating, this automatically locks the file (so that you can do your update). When you update, then it unlocks automatically. But if for some reason, you don't update, then you have to specifically unlock the file so that someone else can use it.

Glad it's working now. Nina Too
 
Hi Nina, Claude,

Just a few minor comments about Nina's tips. The data area passed to pgmb should be in WS not LS. If pgma was passed data thru the EXEC stmt PARM then that data could be passed to pgmb via LS. In both cases the data defs that match the calling pgm's data must be coded in pgmb's LS.

If I'm not mistaken, neither recs or files are locked when a read for update is performed; the control interval (CI) in which the updated rec resides is locked/unlocked. The distinction is important because a group of records may be locked as a result of the update of one rec. This is my recollection, anyway.

Hope this clarified rather than obfuscated.

Regards, Jack.
 
A couple of problems.
1. You cannot have a duplicate primary key if you are reading sequentially or dynamically. Testing for a dupe is a waste of time. Unless....
2. The lock may be the result of trying to read the same record in the main record and a subprogram; the unlock would then be necessary. However in this case, if you have matching keys, you would bypass the second read...
3. If you are processing the file you read in the first program, why are you reading the file again in another program. Is there data on a DIFFERENT record that you need?

Stephen J Spiro
Member, J4 COBOL Standards Committee
check it out at

stephenjspiro at hotmail.com
 
Hello ,
Thanks to all. I think that the problem i have is specific to program B. It is used often, i can't change it.
Just to let you know, i removed the select and FD statements in program A.
I tried to read then unlock my file in program A, but still, i have the same error. I see that the parameters sent to program C are empty ! It may be the souce of my problem. Thanks again. (on top of that, my computer crashed at home)
 
Hi, Slade, you wrote:
---------------
"Just a few minor comments about Nina's tips. The data area passed to pgmb should be in WS not LS. If pgma was passed data thru the EXEC stmt PARM then that data could be passed to pgmb via LS. In both cases the data defs that match the calling pgm's data must be coded in pgmb's LS."
---------------
I think I see what you are saying here. This is true for a batch program where you have parms being passed from the first program via the first job step of the JCL to the next program being executed on the 2nd step of the JCL. The parms are coded in the Linkage Section and should match the parms coded on your JCL's EXEC statement.

However, for online CICS applications (where there is no JCL), frequently you have long chains of IF [condition X] CALL PROGRAM B ELSE [condition Y] CALL PROGRAM C. And assuming the calling program here is PROGRAM A, sometimes it's the first program in the chain, but other times, it's being called by let's say PROGRAM M. In many of these cases, these programs are reusable modules, strung together according to the particular application.

So in these cases, where a program may or may not be a calling program and/or may or may not be a called program, you want the passed data to be in the Linkage Section and each program's procedure division to be coded PROCEDURE DIVISION USING [Linkage-Data-Area].

And actually, in CICS, IBM has it set up so that some necessary data fields are automatically coded in each CICS program's Linkage Section. And the programmer can simply write in PROCEDURE DIVISION in the source code, and the IBM CICS compiler will add on 'USING DFHBLK, DFHCOMMAREA' (the IBM names for these data areas) automatically.

Nina Too
 
Hi All,

It seems, on further examination, that an unlock s/b unnecessary (and inappropriate) since this is a batch pgm.

I scanned the code provided and I don't see any updates. If so, define the file disp as shr, or whatever the VSE equiv is.

Also, it's hard to determine, but it looks like pgma should not read my-file, but pass the key of the desired rec to pgmb. I'd guess that another file s/b used by pgma to get the desired key and pass it to pgmb. That's the usual sequence when you're using a generalized I/O module. As Stephen pointed out, It makes no sense to read the same rec twice.

Claude, what params does pgmb expect from the caller?

Thanx, Jack.
 
I am the one who should thank you for taking the time to read my post.
Program A has to read MY-FILE for certain policies.
For the policy that cancels the job, program A does not read MY-FILE (no need for it). For this policy, program B is called.
These are the different parameters that are passed
From program A :
CALL 'programB' USING WGLOB-GLOBAL-AREA
PARM-LINK-AREA
CSV-SPECIFIC-PARM-AREA
PO-DATA-REC
PO-COV-AREA.
In program B
PROCEDURE DIVISION USING WGLOB-GLOBAL-AREA
PARM-LINK-AREA
CSV-SPECIFIC-PARM-AREA
PO-DATA-REC
PO-COV-AREA.

From program B :
CALL 'programC' USING WGLOB-GLOBAL-AREA
PH-IO-WORK-AREA
PH-DATA-REC.

In program C :
PROCEDURE DIVISION USING WGLOB-GLOBAL-AREA
PH-IO-WORK-AREA
WPH-LINK-RECORD.
 
Hi Claude,

Your first explaination of how the 3 pgms interact was a good start. The problem is that you didn't explain what was being passedand how the passed data was being used by the receiving pgm, e.g.:
You mention that a passes to b:
WGLOB-GLOBAL-AREA
PARM-LINK-AREA
CSV-SPECIFIC-PARM-AREA
PO-DATA-REC
PO-COV-AREA

What are they? Is po-data-rec the my-file-rec? ( I picked this because of all of thoes above, I have SOME understanding of what it is). If not, where did it come from? What is it? How is it used? If you said something like the following, we might get a better idea:

Pgma passes the my-file rec to b. B uses the Key(acct# + tran date) to whatever. I was going to say B re-reads the rec. But as Stephen said, why, you've passed it to B. That leads me to believe that po-data-rec is not a my-file rec. Then what is it? There's no mention of it in your narrative?

Another example: WGLOB-GLOBAL-AREA is probably one of those catch-all fields that can be populated by the caller to suit its needs. We have to know what sub fields are to be used by the callee. And again, not the names but the decription of the fields and their relevance to the problem at hand.

Well anyway, you get the idea. We need more info to help you. P.S. I've decided to drop the "I guesses", "I thinks" and "perhapses", etc. Also any language to soften my comments. They take too many keystrokes, so just assume they're there and that I mean them.

Regards, Jack.
 
just a stupid question. Do i need to remove the SELECT and FD statements from program A ?
Thanks
 
Claude,

Guess you ignored my plea. The ans to your ques: yes or no, depending on what you're trying to do.
 
Hi Slade,
I was off for 3 weeks , and i am back with my old problem.
I hope you all had nice vacation or will have a nice one.

I think that i see where the problem lies but don't know how to fix it. After many displays, i realized that in program A, PH-IO-WORK-AREA and PH-DATA-REC are never empty when a read is performed. The read is done by program C.
But in program B, they are both empty when the link copybook is called. This copybook calls (static) program C.
PH-DATA-REC is my file layout.
MY-FILE is in fact the " PLAN HEADER FILE"

REMARKS: FILE SELECT STATEMENT
PLAN HEADER FILE
SELECT PH-DATA-FILE ASSIGN TO SYS024-ORDUPH
ORGANIZATION IS INDEXED
ACCESS IS DYNAMIC
RECORD KEY IS PH-CODE
FILE STATUS IS PH-DATA-FILE-STATUS.

** MEMBER : CCFRPH
** REMARKS: RECORD LAYOUT
** PLAN HEADER FILE
** LENGTH : 660
01 PH-DATA-REC.
*GROUP ITEM LENGTH 8 BYTES
05 PH-CODE.
10 PH-CODE-COMPANY PIC X(02).
10 PH-PLAN-CODE PIC X(05).
10 PH-RATE-SCALE PIC X(01).
....etc..
PH-CODE witch is the key is known before program B is called. Program B is supposed to perform a read statement , via program C, and come back to program A.
I don't understand why program C doesn't get the information it needs.
Thanks for your help.
 
Hi again,
Programs B and C are DOS/VS COBOL , program A is COBOL FOR VSE/ESA 1.1.0.
I am wondering about above and bellow the line stuff (witch i don't understand at all). register 15 is not 0.
Thanks again
 
Hi again,
Programs B and C are DOS/VS COBOL , program A is COBOL FOR VSE/ESA 1.1.0.
I am wondering about above and below the line stuff (witch i don't understand at all). register 15 is not 0.
Thanks again
 
hello.
i tought you would like to know what happened after all.
i compiled program a as cobol I, and every thing worked fine.
i sincerely hope that noone was hurt during the crash of the 2 towers in new york city yesterday (among people of this community).
i hope that peace will come back to everyone and everywhere.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top