XYZ_123
XYZ_123

Reputation: 1

Handling Alphanumeric data in cobol

ws-var1 is of pic x(3). ws-var2 is also pic x(3).

I have a field in table ws-var1 = "1 " and i want to move its value to another field ws-var2 which should contain value as " 1". Both ws-var1 and ws-var2 are alphanumeric fields. Please suggest suitable method to achieve this.

Upvotes: 0

Views: 1503

Answers (3)

Bill Woodger
Bill Woodger

Reputation: 13076

You could of course do it with a loop. The thing is, you only have three bytes. With something that is three bytes long, doing anything other than basic stuff is over-the-top as resources beyond what are reasonable are consumed. Where resources are not paid for, and where the propagation of inefficient code across many programs used daily does not worry anyone, there are other ways to do it.

   01  A-MEANINGFUL-NAME. 
       88  AMN-NO-ACTUAL-DATA              VALUE SPACE. 
       05  AMN-FIRST-TWO-BYTES-OF-DATA. 
           10  AMN-FIRST-BYTE              PIC X. 
           10  FILLER                      PIC X. 
               88  AMN-ONE-BYTE-OF-DATA    VALUE SPACE. 
       05  FILLER                          PIC X. 
           88  AMN-TWO-BYTES-OF-DATA       VALUE SPACE. 

   01  B-MEANINGFUL-NAME. 
       05  BMN-FIRST-BYTE                  PIC X. 
       05  BMN-SECOND-TWO-BYTES. 
           10  FILLER                      PIC X. 
           10  BMN-THIRD-BYTE              PIC X. 

       MOVE SPACE                   TO B-MEANINGFUL-NAME 
       EVALUATE TRUE 
         WHEN AMN-NO-ACTUAL-DATA 
           CONTINUE 
         WHEN AMN-ONE-BYTE-OF-DATA 
           MOVE AMN-FIRST-BYTE      TO BMN-THIRD-BYTE 
         WHEN AMN-TWO-BYTES-OF-DATA 
           MOVE AMN-FIRST-TWO-BYTES-OF-DATA 
                                    TO BMN-SECOND-TWO-BYTES
         WHEN OTHER 
           MOVE A-MEANINGFUL-NAME   TO B-MEANINGFUL-NAME 
       END-EVALUATE 

That is an efficient, and clear, way to do it. Probably way too much typing for many people, but those are people who don't consider the need for a program to be understood readily and maintained easily. It can be made more efficient, by only blanking those bytes in the destination which need it, but you can attempt that one yourself.

Won't work "as is" with an embedded space, but can be easily changed to do so.

Plus, it's not really that much typing, as you use the power of your editor.

Or

   01  A-MEANINGFUL-NAME                   PIC XXX. 
   01  B-MEANINGFUL-NAME                   PIC XXX. 
   01  FILLER 
       REDEFINES B-MEANINGFUL-NAME. 
       05  C-MEANINGFUL-NAME               PIC XXX JUST RIGHT.

       UNSTRING A-MEANINGFUL-NAME 
         DELIMITED BY SPACE 
         INTO                       C-MEANINGFUL-NAME

Not so much typing. Less efficient. Still clear.

Won't work with an embedded space, but code can be easily included to make it do so (only use it conditionally).

Or

   01  A-MEANINGFUL-NAME                   PIC XXX. 
   01  B-MEANINGFUL-NAME                   PIC XXX. 

   01  C-MEANINGFUL-NAME 
       REDEFINES B-MEANINGFUL-NAME         PIC ZZ9. 

       COMPUTE C-MEANINGFUL-NAME    = FUNCTION NUMVAL 
                                       ( A-MEANINGFUL-NAME )

Not so much typing, probably further less efficient, perhaps a little less clear and relies on the source being a well-formed numeric.

Won't work with an embedded space, because that would not be a well-formed numeric.

As Edward H's answer has shown, reference-modification can be used. Here's the first example rewritten to do that, as a demonstration of what clarity can be lost through reference-modification:

       MOVE SPACE TO B-MEANINGFUL-NAME 
       EVALUATE TRUE 
         WHEN A-MEANINGFUL-NAME = SPACES
           CONTINUE 
         WHEN A-MEANINGFUL-NAME (2:1) = SPACES
           MOVE A-MEANINGFUL-NAME (1:1) 
             TO B-MEANINGFUL-NAME (3:1) 
         WHEN A-MEANINGFUL-NAME (3:1) = SPACES
           MOVE A-MEANINGFUL-NAME (1:2) 
             TO B-MEANINGFUL-NAME (2:) 
         WHEN OTHER 
           MOVE A-MEANINGFUL-NAME TO B-MEANINGFUL-NAME 
       END-EVALUATE 

The executable code generated for that will be (should be) identical to the original example, so as efficient, but it is hopefully acknowledged to be more difficult to read. (Of course, were I to code that, I'd format it differently, at least make it a little easier to read, but I suspect a "VAR1"-person would even not type more of the blanks).

Upvotes: 0

Magoo
Magoo

Reputation: 80033

01  WS-VAR-1.
    88 FL-VAR1-999         VALUE SPACES.
    03 WS-VAR1-999         PIC 9(03).
01  FILLER 
      REDEFINES WS-VAR-1.
    03 WS-VAR1-99           PIC 9(02).
    03 FILLER               PIC X(01).
       88 FL-VAR1-99        VALUE SPACES.
01  FILLER 
      REDEFINES WS-VAR-1.
    03 WS-VAR1-9            PIC 9(01).
    03 FILLER               PIC X(02).
       88 FL-VAR1-9         VALUE SPACES.

01  WS-VAR-2.
    03 WS-VAR1-ZZ9          PIC Z(02)9(01).



    IF FL-VAR1-999          MOVE ZERO       TO WS-VAR1-ZZ9
      ELSE
      IF FL-VAR1-9          MOVE WS-VAR1-99 TO WS-VAR1-ZZ9
        ELSE
        IF FL-VAR1-99       MOVE WS-VAR1-9  TO WS-VAR1-ZZ9
          ELSE              MOVE WS-VAR1    TO WS-VAR2.

It's all a matter of redefinition...

Upvotes: 0

Edward H
Edward H

Reputation: 586

Assuming you want to generally right-justify a string (which contains no intermediate spaces), you can use:

INSPECT ws-var1 TALLYING num-chars FOR CHARACTERS BEFORE SPACE
MOVE ws-var1 (1:num-chars) TO ws-var2 (3 - num-chars + 1:)

where num-chars is a numeric data item with initial value 0.

(Alternatively, if you're fortunate enough to be using a compiler with the TRIM intrinsic, you could declare ws-var2 as JUSTIFIED RIGHT and simply MOVE FUNCTION TRIM(ws-var1) TO ws-var2.)

Upvotes: 1

Related Questions