COBOL Reference Modification
Working-Storage for Examples 1, 2, and 3000340 01 CAT-TYPE PIC X(15) VALUE 'CALICO'.
000350 01 DOG-TYPE PIC X(15) VALUE 'SCHNAUZER'.
000360 01 CAT-ABBREV PIC X(5).
000370 01 DOG-END PIC X(10).
Reference Modification Example Number 1- From position 1 For 5 positions.004310
004320 MOVE CAT-TYPE(1:5) TO CAT-ABREV.
This will move "CALIC" to CAT-ABBREV. (The letters from position 1 of CAT-TYPE for 5 positions.)
Reference Modification Example Number 2 - From position 2 For 4 Bytes.004310
004320 MOVE CAT-TYPE(2:4) TO CAT-ABREV.
This will move "ALIC" to CAT-ABBREV. (The letters from position 2 of CAT-TYPE for 4 positions.) Reference Modification Example Number 3 - From position number 5 to the end of the field.004310
004320 MOVE DOG-TYPE(5 TO DOG-END.
This will move "AUZER" to DOG-END. (The letters from position 5 of DOG-TYPE to the end of DOG-TYPE.) ...And Bob wites in with this piece on RM. Thanks Bob!I expect you know all about address modification? That's where you can reference some piece of a field that doesn't have a field name of its own. If you were using a copybook that came from somewhere that you didn't have control over, and therefore couldn't conveniently change, address modification would be one way to get at part of a larger field. 05 FLDX PIC X(35). <----- here is the 'larger field'
77 SOMEWHERE PIC 9999 COMP.
77 WHICH-LINE PIC 9999 COMP.
77 HOW-LONG PIC 9999 COMP.
IF FLDX(3:5) = '27154' ...
That says "starting at position 3 for a total of 5 characters of FLDX". It's atrocious from the stand-point of on-going maintenance, because the code doesn't give you a clue as to what positions 3 thru 7 of FLDX might be. So, use only if necessary, or put in enough comments so when you come back to it six months later, you'll remember what you did wrong.
Ok, let's say you wanted to move something INTO a piece of FLDX, you could do the same as above as far as syntax is concerned. MOVE '27154' TO FLDX(3:5).
Still pretty straight-forward. However, let's assume that the contents of FLDX is the City and State part of someone's address, and the '27154' is a Zip Code that you want to put on the same line when the address is printed. Obviously addresses are different lengths, so where you want to put the zip code will vary from address to address, but will be somewhere on 'the last line'.
First, you'd have to find out where there was a convenient "hole" in that line of address information where you could put the zip code. Let's say you do that by whatever means comes to mind, and you end up with a pointer to the first character of that hole in the field SOMEWHERE. You could then do: MOVE '27154' TO FLDX(SOMEWHERE:5)
and that will certainly get it there. However, you'll end up with this: DALLAS, TEXAS27154
So the post office may tell you it's the wrong zip code, but that's another issue entirely. Obviously you need a space or two between the state and the zip code. So address modification let's you do something like this: MOVE '27154' TO FLDX(SOMEWHERE + 1:5)
The value "SOMEWHERE + 1" will be calculated as the "target" before the instruction is executed. The only thing with that is that you have to make sure you've got at least six spaces available in that line of the address, or you'll be overlaying something.
We all know of course that addresses usually consist of several lines of text, and you never know how many, other than that your code will provide some maximum number, probably four or five. And since the number of lines varies, you won't know in advance WHICH line of the address you want to add the zip code to. We'll assume that you also find a means of discovering which is the last line of the address data (i.e. the one with which you will merge the zip-code), and that it could be any of the four or five lines, and that for convenience, you end up with a pointer to the correct line in a field called WHICH-LINE. That field can serve as a convenient subscript (assuming that you have the addresses in an "occurs" area. The final syntax then for moving the zip code to somewhere in some line of the address is: MOVE '27154' TO FLDX(WHICH-LINE)(SOMEWHERE + 1:5)
And as we all know, zip-codes used to be 5 characters, but are now up to 9 in the U.S. (10 if you include a hyphen), and longer in many foreign countries. So it's entirely possible that the length of the zip-code you want to insert will vary from situation to situation. The COBOL compiler also lets you account for that by making the byte-count a variable name. So if you have a variable length zip-code, you could put the length of the 'current' version in a field called HOW-LONG, and then write the move as: MOVE ZIP-CODE(1:HOW-LONG) TO
FLDX(WHICH-LINE)(SOMEWHERE + 1:HOW-LONG)
And that's as far as we'll go with the exposition of syntax for address modification. This isn't provided as a recommendation, merely to let you know what is possible. It could save you many many lines of code in which there is a good chance of making an error shuffling a byte at a time from one field to another.
to add the first comment for COBOL Reference Modification.
To access specific characters within a string you can use a reference modifier.
The start position is the nth character of the STRING-ITEM. For MicroFocus compilers at least, the length can be omitted if you want all characters to the end of the string. e.g.
01 STRING-1 PIC X(10) VALUE 'ABCDEFGHIJ'.
01 STRING-2 PIC X(10) VALUE SPACES.
01 STRING-3 PIC X(10) VALUE SPACES.
01 STRING-4 PIC X(10) VALUE SPACES.
01 STRING-5 PIC X(10) VALUE SPACES.
01 STRING-6 PIC X(10) VALUE SPACES.
in procedure division:
MOVE STRING-1(2:6) TO STRING-2
MOVE STRING-1(1:9) TO STRING-3
MOVE STRING-1(6) TO STRING-4
MOVE STRING-1(5:1) TO STRING-5
MOVE STRING-1(3:3) TO STRING-6
STRING-2 will contain characters 2 to 6, i.e. : "BCDEFG "
STRING-3 will contain characters 1 to 9, i.e. : "ABCDEFGHI "
STRING-4 will contain characters 6 to the end of STRING-1, i.e. : "FGHIJ "
STRING-5 will contain character 5 only, i.e. : "E "
STRING-6 will contain characters 3 to 5, i.e. : "CDE