Reputation: 711
I'm having trouble getting my batch to correctly interpret the values in a file I'm reading.
The values have a separate leading sign and a real decimal, eg:
;+000000123.99;+123456789.99;
But the following just gives me compilation errors:
10 FILLER PIC X(1).
10 VALUE1 PIC S9(9),9(2) SIGN LEADING SEPARATE.
10 FILLER PIC X(1).
10 VALUE2 PIC S9(9),9(2) SIGN LEADING SEPARATE.
10 FILLER PIC X(1).
In this shop, they use DECIMAL POINT IS COMMA
I thought I'd be able to just define a numerical as above and just read the file without any extra work, but can't seem to get it to work.
If I use a implied decimal I don't get an error.
Isn't it possible to mix sign leading separate and real decimal?
Upvotes: 3
Views: 5031
Reputation: 13076
This bit is quite important.
Firstly, I'll show how I do this. I do it this way, because I like to know that everything which should have a particular value does have that particular value.
05 VALUE-TO-DE-EDIT.
10 VTDE-SIGN PIC X.
88 VTDE-SIGN-VALID VALUE "-" "+".
88 VTDE-NEGATIVE VALUE "-".
10 VTDE-INTEGER-PART PIC X(9).
10 VTDE-DEC-POINT PIC X.
88 VTDE-DEC-POINT-VALID VALUE ".".
10 VTDE-DECIMAL-PART PIC XX.
01 THE-NUMBER PIC S9(9)V99.
01 FILLER REDEFINES THE-NUMBER.
05 TN-INTEGER-PART PIC X(9).
* The S in the PICture is required, to get correct sign for a
* positive edited value, unless you do it a different way.
*
05 TN-DECIMAL-PART PIC S99.
And then in the PROCEDURE DIVISION
, the details, of course, can vary, this is only an example keeping it short and minimum:
IF ( VTDE-SIGN-VALID
AND VTDE-DEC-POINT-VALID
AND VTDE-INTEGER-PART NUMERIC
AND VTDE-DECIMAL-PART NUMERIC )
PERFORM DE-EDIT-NUMBER
DISPLAY THE-NUMBER
ELSE
PERFORM BUSTED-NUMBER
END-IF
IF ( VTDE-SIGN-VALID
AND VTDE-DEC-POINT-VALID
AND VTDE-INTEGER-PART NUMERIC
AND VTDE-DECIMAL-PART NUMERIC )
PERFORM DE-EDIT-NUMBER
DISPLAY THE-NUMBER
ELSE
PERFORM BUSTED-NUMBER
END-IF
...
DE-EDIT-NUMBER.
MOVE VTDE-INTEGER-PART TO TN-INTEGER-PART
MOVE VTDE-DECIMAL-PART TO TN-DECIMAL-PART
IF VTDE-NEGATIVE
SUBTRACT THE-NUMBER FROM ZERO
GIVING THE-NUMBER
END-IF
.
BUSTED-NUMBER.
do what you feel
.
OK, why am I showing that now after you Accepted the Answer?
You were attempting your solution with a SEPARATE SIGN
and without validating the data. Without validating the data, the easiest thing to do is to "de-edit" the edited number. The compiler does it all for you, you just code one MOVE. If the sign is "wrong", you'll get a run-time error. If the decimal-point value is "wrong" nothing will happen. If your elements of the number are not numeric, you'll get some slightly-garbled version of them. To do it that way, you have to 100% trust the numbers. Data from external files and from reports I always validate.
OK, you are DECIMAL POINT IS...
Change the S, which is not a sign for a numeric-edited field, to + and drop the SIGN LEADING SEPARATE
. You should be good to go.
Unless you use DECIMAL POINT IS COMMA
COBOL uses a full-stop/period/dot for a decimal-point.
Your data contains what COBOL would produce as a decimal-point, so just change your data-definitions to use .
rather than ,
.
If you want to use the data, you can MOVE the numeric-edited field (that is what you have by having an explicit decimal-point) to a field with an implied decimal place.
Your definition will work as long as the data is in fixed positions. If the "widths" vary within a column, you will have a different problem with a different solution.
Upvotes: 7