Why is my if statement not determining the correct output in two nested performs?

StackOverflow https://stackoverflow.com/questions/22314650

  •  12-06-2023
  •  | 
  •  

Question

I have this Cobol paragraph that will search one table which at this point in my example would have a table counter of 2 which is what the first INDEX loop does. The variable A represents an Occurs that is defined in a file (include) which has 5 occurrences. I can get to the if statement but it returns false. I read the information out of a ParmCard and store that in the table which is Table-B and the ParmCard is correct.

I did get it to find one value when was changing values around (conditional statements) but I know that both of the values that it is looking for in the ParmCard are in the file and should be found and it should find two results. I would have tried Expeditor but the system was down at work.

Is there something wrong with the index or may be I think that the perform's are working one way but they are really working a different way? This Search paragraph gets executed with every read of the ID file thus it will look in the table as many times as the ID file has an ID and ID symbols are unique.

Question: Why would the IF-STATEMENT not be working?

Code:

  SEARCH-PARAGRAPH.
      PERFORM VARYING SUB FROM 1 BY 1 UNTIL SUB > 2 <--DUPLICATE INDEXER 
        IF A(TAB) = TABLE-B(SUB) THEN
            MOVE 6 TO TAB
            MOVE 'TRUE' TO FOUND-IS
            PERFORM WRITE-FILE THRU X-WF
            PERFORM LOG-RESULT THRU X-LR
         END-IF
     END-PERFORM

  X-SP. EXIT.


  SEARCH-INDEX.
   PERFORM VARYING I FROM 1 BY 1 UNTIL I > 2
    DISPLAY 'INDEX --> ' I
     PERFORM VARYING TAB FROM 1 BY 1 UNTIL TAB > 5
      DISPLAY 'TAB  --> ' TAB   
         PERFORM SEARCH-PARAGRPAH THRU X-SP
     END-PERFORM
   END-PERFORM.
  X-SEARCH-INDEX. EXIT.

Here is the way that it works now and I do get the results I want. It is difficult to past the company code up because you never know who might have a problem.

New Code:

   READ-PROV.                                            
     READ P-FILE                                    
        AT END                                         
          MOVE 'Y' TO EOF2                             
          GO TO X-READ-PROV                            
        NOT AT END                                     
          ADD 1 TO T-REC-READ                          
          MOVE P-RECORD TO TEST-RECORD    
          PERFORM CHECK-MATCH THRU X-CHECK-MATCH       
     END-READ.                                         
 X-READ-PROV. EXIT.                                    

CHECK-MATCH.                                                        
    PERFORM VARYING SUB FROM 1 BY 1 UNTIL SUB > TABLECOUNTER        
      IF PID >= FROM(SUB) AND                      
         PID <= THRU(SUB) THEN                     
         IF TODAY < P-END-DTE THEN                        
            IF TOTAL-PD  = 0 AND                              
               TOTAL-PD  = 0 AND                              
               TOTAL-PD = 0 AND                              
               TOTAL-PD = 0 AND                              
               TOTAL-PD = 0 THEN                             
               IF PBILLIND NOT EQUAL 'Y'                      
                PERFORM VARYING TAB FROM 1 BY 1 UNTIL TAB > 5       
                 IF P-CD(TAB) = TY(SUB) THEN    
                    MOVE 6 TO TAB                                   
                      DISPLAY('***Found***')      
                    ADD 1 TO T-REC-FOUND                            
                 END-IF                 
                END-PERFORM             
               END-IF                   
            END-IF                      
         END-IF                         
      END-IF                            
    END-PERFORM.                        
X-CM. EXIT. 
Was it helpful?

Solution

We can't tell.

There is nothing "wrong" with your nested PERFORM. The IF test is failing simply because it is never true.

We can't get you further with that without seeing your data-definitions, sample input and expected output.

However... my guess would be that the problem is with your data from the PARM in the JCL. That is the most likely area.

It is of course possible that the problem is with the other definition.

A couple of things whilst waiting.

Please always post the actual code, always. We don't want to look for errors in what you have typed here, we want to see the actual code. You have not shown the actual code, because it will not compile, as INDEX is a Reserved Word in COBOL, so you can't use it for a data-name.

Please always bear in mind that what you think may be wrong may not be the problem, so post everything we are likely to need (data-definitions, data you used, actual results you got with the code (including anything you've added for problem-determination), results which were expected).

Some tips.

A paragraph requires a full-stop/period after the paragraph-name and before the next paragraph. If you put that second full-stop/period on a line of its own, and have no full-stops/periods attached to your PROCEDURE code itself, you'll make things look neater and avoid problems when you want to copy some lines which happen to have a full-stop/period to a place where they cause you a mess.

You are using literal values. This is bad. When the number of entries in one of your tables changes, you have to change those literal values. Say the 2 needs to be changed to 5. You have to look at every occurrence of the literal 2 and decide if it needs to be changed. Then change it to 5. Then you get another request, to change the table which originally had five entries so that it will have six. See how difficult/error-prone life can be?

If instead you have unique and well-named data-names for your maximum number of entries, you only have one place to make a change, and you know it can be changed without reference to the rest of the code (assuming someone clever hasn't seen it has a value they want for something, and use it despite its name, of course...).

The content of those fields you can set automatically:

   01  TABLE-1. 
       05  FILLER OCCURS 2 TIMES. 
           10  A PIC X(10). 
   01  TABLE-2. 
       05  FILLER OCCURS 5 TIMES. 
           10  TABLE-B PIC X(10). 
   01  TABLE-1-NO-OF-ENTRIES        COMP   PIC 9(4). 
   01  TABLE-2-NO-OF-ENTRIES        COMP   PIC 9(4). 
   ...
   PROCEDURE DIVISION.
   ... 
       COMPUTE TABLE-1-NO-OF-ENTRIES = LENGTH OF TABLE-1
                                     / LENGTH OF A 
       COMPUTE TABLE-2-NO-OF-ENTRIES = LENGTH OF TABLE-2
                                     / LENGTH OF TABLE-B
       DISPLAY TABLE-1-NO-OF-ENTRIES 
       DISPLAY TABLE-2-NO-OF-ENTRIES 

That gives you the output 2 and 5.

The names I've used are a mixture of yours and some for demonstration purposes only. Make everything meaningful, and by that I don't mean trite, as my example names would be in real life.

If you insist on escaping from within your PERFORM like that (and take note of Bruce Martin's comment), you can calculate your escape value by using new, aptly-named, fields and giving them the value of the above plus one.

To do a nested loop when the outer loop only has two entries is overkill. You don't need to escape out of the loops like you do, if you have a termination condition on the loop.

That'll do for now until we see your definitions, data and results.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top