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 gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to store in Decimal format, but display number showing the decimal 1

Status
Not open for further replies.

SiouxCityElvis

Programmer
Jun 6, 2003
228
US
I am confused on how to read in raw data decimal values store them, and then retrieve them in a different program and send them to output back with the decimal showing.

Raw Data: 166.00
When I store this Data: WS-DECI-NBR PIC S9(6)V9(2)

So, right now when I do a test read on the data I've stored and output that to a Sequential File, I see the above number in this format:
1669000}

But, the problem is I want to send it out so it looks like:
166.00
That way when the Java guy picks it up, it makes sense to him.

Thanks in advance.
-David
 
working-storage
01 WS-DECI-NBR-EDITED PIC -(7).9(2).

procedure

read file
move WS-DECI-NBR to WS-DECI-NBR-EDITED

write out-record from WS-DECI-NBR-EDITED

Hope the above is clear
 
I am using RMCOBOL-85 version 8, and the above did not seem to have any effect.


 
David,

I think we went through this once before, in the middle of thread209-533708.

Since the number value that is coming from external storage is already edited, you must de-edit it before storing in a COBOL numeric (not numeric edited) data item. This is what I described in the middle of thread209-533708.

Please, show us the code, and the sample data. I think that you want to do the following:[ul]
[li]read the external data into an item defined (or redefined) as a numeric edited item;[/li][li]MOVE the numeric edited item to a numeric item, where it may be used by COBOL as a number; and then[/li][li]MOVE from the numeric item to a numeric edited item before writing the (perhaps changed?) number to external storage.[/li][/ul]


Tom Morrison
 
Tom,

I have one program that takes raw data out of a comma delimted file, in which a few of the fields are decimal such as field1, field2,..,..,166.00,...,...

One of my cobol programs reads in this data and stores in a DB with the following as its field definition. I have "this" labelled to the left of the field that is holding the 166.00 data brought in by csv file above. CUSTDB-FILE is an indexed file.
This is in Program "MAKECUSTDB"

FD CUSTDB-FILE.

01 CUST-RECORD.
02 CUST-PRIME-KEY PIC 9(11).
02 CUST-FIELDS.
03 CUST-LASTNAME PIC X(30).
03 CUST-FIRSTNAME PIC X(30).
03 CUST-MIDDLE-INITL PIC X(1).
03 CUST-PIN PIC 9(4).
03 CUST-BIRTHDATE PIC X(10).
03 CUST-SSN PIC 9(9).
03 CUST-ADDRESS1 PIC X(30).
03 CUST-ADDRESS2 PIC X(30).
03 CUST-CITY PIC X(30).
03 CUST-STATE PIC X(2).
03 CUST-ZIP PIC X(10).
03 CUST-PHONE PIC X(12).
03 CUST-LICENSE PIC X(14).
03 CUST-LICENSE-ST PIC X(2).
03 CUST-LICENSE-EXP PIC X(10).
03 CUST-GENDER PIC X(1).
03 CUST-RACE PIC X(15).
03 CUST-HAIR PIC X(3).
03 CUST-EYES PIC X(3).
03 CUST-HEIGHT PIC X(4).
03 CUST-WEIGHT PIC 9(3).
03 CUST-MAIDEN-NAME PIC X(30).
03 CUST-SPOUSE-NAME PIC X(30).
03 CUST-LIMIT PIC 9(6).
03 CUST-CASH-CK-SW PIC X(1).
03 CUST-STORE-ID PIC X(6).
03 CUST-OPEN-DATE PIC 9(8).
03 CUST-DATE-LAST PIC 9(8).
03 CUST-CHECK-TYPE PIC X(4).
03 CUST-WAIVE-CHRG-SW PIC X(1).
03 CUST-REQUIRE-APPR-SW PIC X(1).
this 03 CUST-AVGCHK-SIZE PIC S9(6)V9(2).
03 CUST-NBRCHK-CSHED PIC 9(7).
&this 03 CUST-AVGCHK-SIZE-P PIC S9(6)V9(2).
03 CUST-NBRCHK-CSHED-P PIC 9(7).
03 CUST-HISTORY-ID PIC 9(11).
03 CUST-FIELD-CHNG-SEC PIC X(30).
02 FILLER PIC X(200).

Then, in one of my many other cobol programs that will use these fields, possibly performing math calcs on them, possibly just reading them. For now, the following program is the one where I'm simply trying to read it, and spit the record out to a sequential file --> this is where I get a good read, except the field is showing up as 1669000{
I want it to show as 166.00 so that it is formatted well for my Java programmer when he reads this out of a named pipe eventually.

This is in Program "READCUSTDB"
FD CUSTDB-FILE.

01 CUST-RECORD.
02 CUST-PRIME-KEY PIC 9(11).
02 CUST-FIELDS.
...

.. this is the file layout of the file described above which I want to read from and then spit out into a sequential file... Defined exactly as above in the 1st program.

..
03 CUST-LASTNAME PIC X(30).
02 FILLER PIC X(200).


WORKING-STORAGE SECTION.

01 WS-CUST-RECORD.
02 WS-CUST-PRIME-KEY PIC 9(11).
02 WS-CUST-FIELDS.
03 WS-CUST-LASTNAME PIC X(30).
03 WS-CUST-FIRSTNAME PIC X(30).
03 WS-CUST-MIDDLE-INITL PIC X(1).
newwww 03 WS-CUST-PIN PIC 9(4).
03 WS-CUST-BIRTHDATE PIC X(10).
03 WS-CUST-SSN PIC 9(9).
03 WS-CUST-ADDRESS1 PIC X(30).
03 WS-CUST-ADDRESS2 PIC X(30).
03 WS-CUST-CITY PIC X(30).
03 WS-CUST-STATE PIC X(2).
03 WS-CUST-ZIP PIC X(10).
03 WS-CUST-PHONE PIC X(12).
03 WS-CUST-LICENSE PIC X(14).
03 WS-CUST-LICENSE-ST PIC X(2).
03 WS-CUST-LICENSE-EXP PIC X(10).
03 WS-CUST-GENDER PIC X(1).
03 WS-CUST-RACE PIC X(15).
03 WS-CUST-HAIR PIC X(3).
03 WS-CUST-EYES PIC X(3).
03 WS-CUST-HEIGHT PIC X(4).
03 WS-CUST-WEIGHT PIC 9(3).
03 WS-CUST-MAIDEN-NAME PIC X(30).
03 WS-CUST-SPOUSE-NAME PIC X(30).
03 WS-CUST-LIMIT PIC 9(6).
03 WS-CUST-CASH-CK-SW PIC X(1).
03 WS-CUST-STORE-ID PIC X(6).
03 WS-CUST-OPEN-DATE PIC 9(8).
03 WS-CUST-DATE-LAST PIC 9(8).
03 WS-CUST-CHECK-TYPE PIC X(4).
03 WS-CUST-WAIVE-CHRG-SW PIC X(1).
03 WS-CUST-REQUIRE-APPR-SW PIC X(1).
Deebug** 03 WS-CUST-AVGCHK-SIZE PIC S9(6)V9(2).
newwww 03 WS-DECI-NBR-EDITED PIC -(7).9(2).
ne 03 WS-DECI-NBR-EDITED PIC X(8).
03 WS-CUST-NBRCHK-CSHED PIC 9(7).
03 WS-CUST-AVGCHK-SIZE-P PIC S9(6)V9(2).
03 WS-CUST-NBRCHK-CSHED-P PIC 9(7).
03 WS-CUST-HISTORY-ID PIC 9(11).
03 WS-CUST-FIELD-CHNG-SEC PIC X(30).
02 WS-FILLER PIC X(200).

ne 01 WS-DECI-NBR-EDITED PIC -(7).9(2).


MAIN-PROGRAM.

PERFORM A-100-INITIALIZATION.
MOVE 0 TO CUST-CTR.
PERFORM B-100-PROCESS-FILES UNTIL EOF-CUST.
PERFORM C-100-WRAP-UP.
STOP RUN.

A-100-INITIALIZATION.

OPEN INPUT CUSTDB-FILE.

OPEN OUTPUT TEST-CUST.

* FILE PROCRESSING CONTROL

B-100-PROCESS-FILES.

MOVE NEG TO SW-EOF-CUST.
READ CUSTDB-FILE NEXT RECORD
AT END MOVE YES TO SW-EOF-CUST
debug ** DISPLAY "AT END"
debug ** DISPLAY OFAC-ENT-NBR
NOT AT END PERFORM B-200-PROCESS-RECORD
END-READ.

******************************************************************
B-200-PROCESS-RECORD.

MOVE CUST-PRIME-KEY TO WS-CUST-PRIME-KEY.
MOVE CUST-FIELDS TO WS-CUST-FIELDS.
Deebug** DISPLAY WS-CUST-AVGCHK-SIZE LINE 1 POSITION 1.
debug ** DISPLAY WS-DECI-NBR-EDITED LINE 1 POSITION 1.
debug ** DISPLAY WS-DECI-NBR-EDITED LINE 1 POSITION 1.
debug ACCEPT MENU-PROMPT LINE 22 POSITION 1.

coment*****None of the above work!!!!All show as 1669000{

WRITE TEST-CUST-REC FROM WS-CUST-RECORD
debug ** INVALID KEY DISPLAY "FAILED!!!!!"
debug ** MOVE YES TO SW-EOF-CUST
END-WRITE.

******************************************************************
C-100-WRAP-UP.

CLOSE CUSTDB-FILE.
CLOSE TEST-CUST.

Forgive me on the horrible formatting of this - I copied this over and noticed some skewing..
-Thanks.
-David
 
David,

The following move does NOT de-edit the fields, as it is a group move without the "corresponding" phrase.

For you to get the correct value you need to
1- move field by field (which is what I mentioned initially
e.g.
MOVE CUST-AVGCHK-SIZE TO WS-CUST-AVGCHK-SIZE

2- have the same names in both the FD and the working storage variable e.g.

FD
01 CUST-RECORD.
02 CUST-PRIME-KEY PIC 9(11).
02 CUST-FIELDS.
03 CUST-LASTNAME PIC X(30).
(snip)
this 03 CUST-AVGCHK-SIZE PIC S9(6)V9(2).
03 CUST-NBRCHK-CSHED PIC 9(7).
&this 03 CUST-AVGCHK-SIZE-P PIC S9(6)V9(2).

Working storage
01 WS-CUST-RECORD.
02 CUST-PRIME-KEY PIC 9(11).
02 CUST-FIELDS.
03 CUST-LASTNAME PIC X(30).
(snip)
this 03 CUST-AVGCHK-SIZE PIC S9(6)V9(2).
03 CUST-NBRCHK-CSHED PIC 9(7).
&this 03 CUST-AVGCHK-SIZE-P PIC S9(6)V9(2).

And then the read
move CORRESPONDING CUST-RECORD TO WS-CUST-RECORD.

The above is bound to work if the values in the file CUSTDB-FILE are correct.

I would create a small program just with the read, the move of one of the numeric fields to the edited field, and a display of the edited field, and go from there.

Use of move corresponding has a few problems and I tend to avoid it, though it can be useful sometimes.

IF the above does not work I would look at the program that read the CSV file and I would see if the move of the "edited" field was done correctly to the NON edited field. (look at what Tom said, as it is how you need to do if not doing it yet)
If needed please post that program also for us to see.

Regards

Frederico

 
Hi Elvis,

You said:

I have one program that takes raw data out of a comma delimted file...

Please show the definition of the field that the pgm puts the "raw data" to (i.e., what is its PIC?). Is that receiving field the field that you want to move to your database record?

Regards, Jack.
 
The last note may have IMPLIED what some of us "think" is the problem.

If your data actually LOOKS like "123.45" - then your piture MUST look like

Pic 999.99
and NOT like
Pic 999V99

"V" is an IMPLIED decimal point and not an actual (in storage) decimal point.

Bottom-Line:
When you READ your data, your PICTURE must match the way the data is coming in.


Bill Klein
 
David,

Good advice from Frederico and Bill. A group move is not a bunch of individual moves of elementary items--that comes only if you use MOVE CORRESPONDING or actually code individual MOVEs.

You also said, "Forgive me on the horrible formatting of this..." The key to formatting code in tek-tips is using the [tt][[/tt][tt]code][/tt] TGML tags. That's how we get all those 'nice looking' code segments. Look near the bottom of the reply box below and you will see a link (beside a checkbox) called "Process TGML"; click on the link and look for the [tt][[/tt][tt]code][/tt] entry. TGML is the source of a lot of formatting tricks here, including color, italics and bold. Happy formatting! [smile]



Tom Morrison
 
Still confused...

I need to know how to:

Read data in. Raw data has 125.87
Put in VAR-A

Later on, I'm going to adding this value to other values of other numeric fields.
VAR-B 232.76
Example:
ADD VAR-A TO VAR-B
Sum: 358.63

In the same program that adds the two fields I will then need to output VAR-B so that it shows up as 0000035863

So, what would be the steps I need to take to get 0000035863?

I have seen code out there for numeric fields that have PIC S9(8)V9(2).

Tom, you mentioned that the UNSTRING statement for bringing in the data is part of the problem. Is there a better way to bring it in so that I don't have to do more job steps to get rid of my decimal?

What page of the RMCOBOL-85 Reference Manual addresses this type of issue? I never seem to get any decent examples out of the hundreds of pages in that manual.

This seems like such an elementary problem, yet the solutions presented seem complex :(
-David

 
If you have input data with an explicit decimal point, then you need an "." in your picture clause. Therefore, what you probably want is something like:

05 Var-A-In Pic 999.99.
05 Var-A-Numeric Pic 999V99.
05 VAr-B-Numeric Pic 999V99.
05 Var-B-Out Pic ZZ9.99.

Then,
"read" into VAR-A-In
Move Var-A-In to Var-A-Numeric
Add Var-A-Numeric to Var-B-Numeric
Move Var-B-Numeric to Var-B-Out
Display Var-B-Out
(or move VAR-B-Out to your output)

All of this ASSUMES that you do not have the intrinsic function NumVal but do have an '85 Standard compiler for "de-editing" of Var-A-In via a MOVE.

Bill Klein
 
Ok. I did ask you to post the program that reads the CSV file and creates the indexed one.

Lets assume that all numeric fields ara always in the same relative position on the CSV file (e.g they are always the same field number.
lets also assume only 3 fields.
and assume a record like
John Brown, 123.22,Salesman


Step 1 "reading the data"
File section
FD
01 inx-record.
05 inx-field1 pic x(10).
05 inx-field2 pic S9(8)V999.
05 inx-field3 pic x(10).
Working
01 record-a pic x(500).
01 var-1 pic x(10).
01 var-2 pic x(10).
01 var-2N redefines var-2 pic Z(10).
01 var-3 pic x(10).
01 output-sequential pic 9(8).999.
Procedure

Read CSV-file into record-a
unstring record-a delimited by ","
into var-1 var-2 var-3
-> At this stage the fields will have the following value
var-1 = "John Brown"
var-2 = "123.22 "
var-3 = "Salesman "

Now we need to populate the indexed file fields.
move var-1 to inx-field1
move var-2N to inx-field2
move var-3 to inx-field3

-> note the use of the numeric edited field var-2N instead of the alphanumeric one var-2.

At this stage we have a group of fields (inx-xx) with correct values (e.g. no crap data on the numeric field).

You can now perform any type of numeric operation with field inx-field2.

Step 3
You wish to output to another edited field.

move inx-field3 to output-sequential
display output-sequential

This display will show
00000123.220

---------
As for the manuals, the information is there but not an example.
See pages 6-114 and 6-115 of the Reference Language Version 8.

And the solutions are not complex at all. You just did not understand them well.
Try and do the simple programs as I mentioned, and go from there. Do not try to do a program to handle all the variables at one go, just one at the time, and add more to it once you know what you are doing.
 
Tom, Fredericofonseca, and others:

Both of you are right on the money - my head is just not screwed on tight today. Using your suggestions below with populating my field using UNSTRING into the var-2 field works. I can then move the var-2N field to my destination field after my UNSTRING has been completed and I get the proper results.

01 var-2 pic x(10).
01 var-2N redefines var-2 pic Z(10).

The field I'm moving my var-2N to is a PIC S9(8)V9(2).
Basically, 125.87 will show up as 1258{ if I DISPLAY it.
I was also able to get more testing results by adding this field to another numeric edited field.

Thanks for everything.
-David
 
David -

Unfortunately, if you adhere to the COBOL standards, the solutions are fairly complex (at least for what seems to most to be a simple problem). At the heart of the issue is that COBOL is(was) designed to work very well with fixed format data. If you go back to the 1960s, all data came in on cards in a fixed format (e.g. the number is in card colums 10-16 with the decimal point assumed between columns 14 and 15 and an 11-zone overpunch in column 16 if the number is negative - S99999V99). This was quite acceptable for the kinds of business data that COBOL processed at the time.

An attempt to fix the problem was made in 1990 with the addition of the NUMVAL intrinsic. However, it has some shortcomings (e.g. works in floating-point rather than fixed-point, doesn't return zero when fed spaces, can't be used in a MOVE but can be in a COMPUTE).

I think most of us old-timers simply manhandle our way through it. I have an app I'm working on now that deals with a restricted case (ANSI X12 numbers which are left justified, can be leading negative signed, and include a decimal point only when necessary). The code to "input" those numbers into something I can compute with is about 60 lines long and sort of does the following:
[ol]
[li]If it's blank, return zero.[/li]
[li]If position 1 is '-' set negative switch.[/li]
[li]Go through the string moving each digit to a working display field noting where in the string the decimal point occurs.[/li]
[li]Move the output display field to a zeroed display field aligning the decimal point (monster EVALUATE).[/li]
[li]Change the sign of the output field if negative switch set.[/li]
[/ol]

It's ugly, but it works. This approach can likely be adapted for your environment if necessary.

Many (most?) compiler writers have recognized this as a problem and there are some platform-specific approaches to solving this problem. I also think the new standard addresses most, if not all, of the limitations of NUMVAL, so there is light at the end of the tunnel at least on that front.

Regards.

Glenn
 
Glenn,

If using RM-COBOL (as David is) you don't need to do it "your way".

RM-COBOL has a extended de-edit functioning that allows for any numeric value placed in a pic Z(x) to be properlly de-edit when moved to a numeric (non edited) field
e.g.

if I move " -3,123.33" to field var-2 on the example above and if then I move it to inx-field2 it will do the correct de-editing, and the value in inx-field2 will be a proper non-edited field

Other COBOL vendors may also have something similar to this, so check them if not using RM.

 
One last question:

On some of my fields not only do some end with "{" but some end with "F" or "E"
example: in a PIC S9(8)V9(2) field I have 3873.95, and when I output it, it shows up as:

000038739E

Why does it hide the "5" with "E" at the end? How can I get it to display 0000387395

Basically, I'm working on out putting to an ACH file and it needs to be in there without the decimal point so I want it to show up as 0000387395
The recipients of these files have the defined layouts of these files, so they know that 95 is the part of the number to the right of the decimal(implied decimal).

Thanks.
-David
 
Sorry I should have said

Please do look at the examples WE post properly.

as I am writing this again here's the complete example

01 n9 PIC S9(10)V9(3) VALUE -123.45.
01 z9 PIC S9(10)V9(3) sign leading separate.

move n9 to z9
display z9

it shows -0000000123450



Regards

Frederico Fonseca
SysSoft Integrated Ltd
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top