I have a copybook with the folowing:
(...)
05 ESTGWABC-S-OUT.
10 ESTGWABC-S-COD-NUM PIC 9(003).
10 ESTGWABC-S-DESC-COD PIC X(020).
(...)
10 ESTGWABC-S-VAL-PAY PIC 9(015)V99.
10 ESTGWABC-S-QTD-REG PIC 9(002).
10 ESTGWABC-S-REG-PEOP OCCURS 0 TO 20 TIMES
DEPENDING ON ESTGWABC-S-QTD-REG.
15 ESTGWABC-S-CCONTR PIC 9(009).
15 ESTGWABC-S-VAL-PAY PIC 9(015)V99.
10 ESTGWABC-S-DEPEN PIC 9(005).
(...)
On my program, I'm wanting to initialize it before use it, so I'm doing the following:
INITIALIZE ESTGWABC-S-OUT
REPLACING ALPHANUMERIC BY SPACES
NUMERIC BY ZEROS
But I'm getting an compiling error:
"ESTGWABC-S-OUT" was found in an "INITIALIZE" statement but was variable-length or variably located. The operand was discarded from the "INITIALIZE" statement.
Can anybody give me a clue how can I solve it or what am I doing wrong? Thank you very much.
Can anybody give me a clue how can I solve it or what am I doing wrong?
Do not use INITIALIZE and you are doing nothing wrong.
Basically, standard COBOL sets rules for the organization of data records. It then defines the behavior of the INITIALIZE statement to properly operate on those data records.
The data items after the variable length table are 'variably located'. This does not conform to standard COBOL, which requires that any variable length data item, in this case, ESTGWABC-S-REG-PEOP, be located last in the record description entry. The location of ESTGWABC-S-DEPEN will change depending on the number of entries in the table, ESTGWABC-S-REG-PEOP. When the size of the table changes ESTGWABC-S-DEPEN will no longer be an initialized data item.
To allow the use of INITIALIZE, the 'copybook' must be changed.
Following is an example of how to use INITIALIZE with a standard-conforming variable length record. This was done with a Micro Focus compiler with flags to force COBOL 85 conformance.
$set ans85 flag"ans85" flagas"s"
identification division.
program-id. var-len.
data division.
working-storage section.
01 n pic 9(2).
01 a.
02 fixed-part.
03 b pic x(2).
03 c pic 9(2).
02 variable-part.
03 d occurs 0 to 10 depending c.
04 e pic x(2).
04 f pic 9(2).
procedure division.
begin.
initialize fixed-part
perform varying n from 1 by 1 until n > 10
initialize d (n)
end-perform
stop run
.
end program var-len.
Related
I am not coding neither understand much about it, although have to run an experiment in the laboratory, and have to use HTBasic to receive data from 2 GPIB devices (IEE 488) and one RS232 (this one is a high precision lab scale ).
I am changing/adding to an old script that someone else wrote. It was only to receive data from the 2 GPIB devices.
I must get data only every 15-30 minutes (the experiment will run for a month) and even though I successfully receive data from the lab scale (device interface select code = 12) they only arrive "synchronous" for a loop every e.g. 10ms (milliseconds). If I make it every 1 second the data are "old" e.g. I removed the item from the scale and instead of showing me ZERO "0" it still shows the weight. Imagine what if I ask for a loop every 15 minutes.
It seems that received data arrives in order one by one and displayed with that order. Probably there is an internal buffer or something that stores them. Does any one know how to OPEN and CLOSE the communication with a serial device on DEMAND? e.g. for GPIB devices I am sending a command like TALK (talk) and UNT (untalk) every time the loop takes place, but I can't find out how to do this with the serial device.
I tried the CONTROL 12,100;0 and CONTROL 12,100;1 (XOFF/XON) but it didn't work.
Here is one of the scripts I tried that gives me the correct weighting values, but for loops every 0.01 seconds.
LOOP
ENTER 12 USING "10D";W
PRINT TABXY(70,20),"wEIGHT IS:";W
WAIT 0.01
END LOOP
END
I would suggest trying using handshake control.
You can control the Serial Interface using the HTBASIC CONTROL statement.
For example, you can turn:
CONTROL 9,5;0 ! use DTR and RTS
CONTROL 9,12;0 ! read DSR, CD, and CTS
You should also use Interface handles as such:
ASSIGN #Serial TO 9 ! Opens the Serial Port, and clears buffer
ASSIGN #Serial TO * ! Closes the Serial Port
This should work for 15 Min Cycle (900 Sec):
ON CYCLE 900 GOSUB Get_Serial
LOOP
END LOOP
STOP
Get_serial:!
ASSIGN #Serial TO 12
ENTER #Serial USING "10D";W
RETURN
END
Hi guys and thanks for your answers (they came a bit late though).
Most probably both of your suggestions may work (havent try them ..maybe in the near future)
What I did those days to solve my problem , was basicly something like : LOOP continuusly and print on specific area of the screen (CRT) the serial device values (weight in gramms) , ONDELAY of specific time (eg every 15minutes) go to NEW LOOP (called it LOOOP in the code) which tells program to grab the value of RS232 labscale from the screen (not the device directly) and ofcourse the 2 GPIB devices, and after that repeat the continuus LOOP to show on CRT screen the real/continuus labscale values to prevent bufffer from being full ... and so everything worked smoothly..
I understand that this in not a GOOD way for coding, but as i said i am a rookie in this field ...BUT IT WORKED
So the code i wrote was something like:
[....]
33 ASSIGN #Scale TO 12
52 ENTER #Scale USING "10D";Weight
54 PRINT TABXY(70,20),"Captured LabScaLE Weight=";Weight;" g"
55 A=Weight
90 ON DELAY T GOTO Loooop
92 LOOP
93 ENTER #Scale USING "10D";A
94 A=A
95 PRINT TABXY(65,35);A;TABXY(65,35);
96 !
97 END LOOP
98 !
99 Loooop: GOTO 100 !GRAPSE THN GRAMMH PU AKOLOYTHEI PX 171
100 !
101 !
102 ENTER CRT;A
116 !==============================================START LISTENING FROM RS232 labscale (DISPAY ON CRT CONTINUUS DATA)======
117 !ENTER CRT;Weight
118 Weight=A
119 PRINT TABXY(70,20),"Captured LabScaLE Weight=";Weight;" g"
120 !
121 !==============================================START LISTENING FROM GDS CTRL=======
122 SEND 9;UNL UNT MLA TALK 14 DATA CHR$(255)
123 ENTER 9 USING "#,B,4D,6D";S,Pressurea,Volumea
124 SEND 9;UNT DATA CHR$(255)
128 !=============================================START LISTENING FROM GDS CTRL=======
129 !
130 SEND 8;UNL UNT MLA TALK 13 DATA CHR$(255)
131 ENTER 8 USING "#,B,4D,6D";S,Pressureb,Volumeb
132 SEND 8;UNT DATA CHR$(255)
[.....]
150 GOTO 92 !
I have an old program that has been discontinued which communicates with an SQL database. When I enter certain information in the defunct software, it is encrypted, encoded, or hashed before being entered into the database.
I am creating another application to interact with the same data, and I need to figure out how the end result is being produced.
Here's an example:
I enter 6/18/2017, I get y/7w/iXIE
I enter 6/18/2099, I get y/7w/iXBM
I enter 6/12/2017, I get y/7c/iXIE
I enter 12/11/2018, I get SN/u0/ZmWk
The last one throws me for a loop... what method is being used and how can I replicate this?
It might be format preserving encryption or just substatutions. In all cases the number of characgters in each section delimited by / are the same number of characters. With enough samples, all 12 months, 31 days and years you should be able to match the method.
6/18/2017
y/7w/iXIE
6/18/2099
y/7w/iXBM
6/12/2017
y/7c/iXIE
12/11/2018
SN/u0/ZmWk
months: 6 -> y, 12 -> SN
days: 11 -> u0, 12 -> 7c, 18 -> 7w
years: 2017 -> iXIE, 2018 -> ZmWk, 2099 -> iXBM
i got a problem with simple cobol call - returning test program.
I am using micro focus cobol.
here are my 2 codes.
***************** CALLING PROGRAM
IDENTIFICATION DIVISION.
PROGRAM-ID. callreturning.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 VA PIC S9(8) USAGE DISPLAY.
01 VB PIC S9(8) USAGE DISPLAY.
01 VC PIC 9(4) USAGE DISPLAY value 0.
PROCEDURE DIVISION.
MOVE 1 TO VA.
MOVE 2 TO VB.
move 3 to VC.
CALL "add_two" USING VA VB returning VC.
* DISPLAY VA VB VC.
EXIT PROGRAM.
END PROGRAM callreturning.
*********CALLED PROGRAM
IDENTIFICATION DIVISION.
PROGRAM-ID. add_two.
ENVIRONMENT DIVISION.
DATA DIVISION.
LINKAGE SECTION.
01 PARM_A PIC S9(8) USAGE DISPLAY.
01 PARM_B PIC S9(8) USAGE DISPLAY.
01 PARM_C PIC 9(4) USAGE DISPLAY value 0.
PROCEDURE DIVISION USING PARM_A PARM_B returning PARM_C.
move 3 to PARM_C.
* ADD PARM_A TO PARM_B GIVING PARM_C.
goback.
END PROGRAM add_two.
CALLING program simply calls the second program with using returing value.
But when i compile both program and run, error happens.
error code: 114, pc=0, call=1, seg=0
114 Attempt to access item beyond bounds of memory (Signal 11)
Did i make a wrong code? or other problem? please help me :)
I am testing 'RETURNING' phrase
Your program compiles and works just fine if you get rid of the returning statement.
Background
01 levels defined in the linkage section are more like pointers in a C program. For normal parameters they are set by the calling program. But returning parameters will be unassigned.
The error is probably caused by trying to use an unallocated pointer.
Solution
Do not use returning as it is for working with languages like java.
Allocate storage to the return-value before using it.
See:
Microfocus Manual, Look at the returning example
IBM Manual Look at the Returning Phrase Section
Finally, returning is for working with java. Anything "type" defined on returning should be java compatible (i.e. binary-long and not 9(4)). I strongly suggest not using Returning in Cobol unless you are calling other languages.
Old Question, so i try a short Answer:
First, there is nothing wrong with using returning in MF-COBOL.
So, this is native COBOL (NetExpress as IDE, i assume). To correct ist just change the second Program:
Move PARM_C from the linkage to the working-storage section
The Procedure Division doesn't get the returning Phrase in its opening declaration. Move it instead to the goback phrase:
PROCEDURE DIVISION USING PARM_A PARM_B.
*>...
goback returning PARM_C.
I am studying the Ada-> Cobol interface, and am wondering if there is any way to write the files to cobol default, without having to have a Cobol code written too, because I want to write a file using some rules of COBOL, but would to know how to do this directly in Ada.
For example, to read a file with cobol structure, I can use use that way:
with Interfaces.COBOL;
with COBOL_Sequential_IO; -- Assumed to be supplied by implementation
procedure Test_External_Formats is
112
-- Using data created by a COBOL program
-- Assume that a COBOL program has created a sequential file with
-- the following record structure, and that we need to
-- process the records in an Ada program
-- 01 EMPLOYEE-RECORD
-- 05 NAME PIC X(20).
-- 05 SSN PIC X(9).
-- 05 SALARY PIC 99999V99 USAGE COMP.
-- 05 ADJUST PIC S999V999 SIGN LEADING SEPARATE.
-- The COMP data is binary (32 bits), high-order byte first
113
package COBOL renames Interfaces.COBOL;
114
type Salary_Type is delta 0.01 digits 7;
type Adjustments_Type is delta 0.001 digits 6;
115
type COBOL_Employee_Record_Type is -- External representation
record
Name : COBOL.Alphanumeric(1..20);
SSN : COBOL.Alphanumeric(1..9);
Salary : COBOL.Byte_Array(1..4);
Adjust : COBOL.Numeric(1..7); -- Sign and 6 digits
end record;
pragma Convention (COBOL, COBOL_Employee_Record_Type);
116
package COBOL_Employee_IO is
new COBOL_Sequential_IO(COBOL_Employee_Record_Type);
use COBOL_Employee_IO;
117
COBOL_File : File_Type;
118
type Ada_Employee_Record_Type is -- Internal representation
record
Name : String(1..20);
SSN : String(1..9);
Salary : Salary_Type;
Adjust : Adjustments_Type;
end record;
119
COBOL_Record : COBOL_Employee_Record_Type;
Ada_Record : Ada_Employee_Record_Type;
120
package Salary_Conversions is
new COBOL.Decimal_Conversions(Salary_Type);
use Salary_Conversions;
121
package Adjustments_Conversions is
new COBOL.Decimal_Conversions(Adjustments_Type);
use Adjustments_Conversions;
122
begin
Open (COBOL_File, Name => "Some_File");
123
loop
Read (COBOL_File, COBOL_Record);
124
Ada_Record.Name := To_Ada(COBOL_Record.Name);
Ada_Record.SSN := To_Ada(COBOL_Record.SSN);
Ada_Record.Salary :=
To_Decimal(COBOL_Record.Salary, COBOL.High_Order_First);
Ada_Record.Adjust :=
To_Decimal(COBOL_Record.Adjust, COBOL.Leading_Separate);
... -- Process Ada_Record
end loop;
exception
when End_Error => ...
end Test_External_Formats;
Put, I don't know how to write a File with cobol structure, in the documentation, I not find a way; http://www-users.cs.york.ac.uk/~andy/lrm95/b_04.htm
For example, if I have that struct in Cobol ( based on this sample: http://www.csis.ul.ie/cobol/examples/Sort/MaleSort.htm ; http://www.csis.ul.ie/cobol/examples/SeqIns/STUDENTS.DAT )
FILE SECTION.
FD StudentFile.
01 StudentRec PIC X(30).
88 EndOfFile VALUE HIGH-VALUES.
FD MaleStudentFile.
01 MaleStudentRec PIC X(30).
SD WorkFile.
01 WorkRec.
02 FILLER PIC 9(7).
02 WStudentName PIC X(10).
02 FILLER PIC X(12).
02 WGender PIC X.
88 MaleStudent VALUE "M".
How I can make a program to write this struct, in Ada, using Cobol interfaces ?
Think physically. That is, what is the output file's format? Whether you create that file in Cobol or Ada is NOT an immediate issue when designing a file.
Let's assume that Cobol Workrec describes your file's format. Do you want to write an Ada program that calls a cobol subroutine to physically write the file? or do you want to use a Cobol program to write the file? Or do you want an Ada program that writes a file in the smae format as Workrec?? Your choice depends on your customer's requirements.
Need your help with my COBOL assignment.
data division file section details are below. My question is I do not know how to count the number if characters - RECORD CONTAINS _ CHARACTERS. Could you check and tell me if my count is right. If not what is the correct number and how did u arrive at it.
FD BONUS-REPORT
RECORD CONTAINS 222 CHARACTERS.
01 BONUS-REPORT-RECORD PIC X(222).
WORKING-STORAGE SECTION.
01 LINE-CT PIC 99 VALUE 0.
01 WS-CONSTANTS.
05 TOTAL-LINES PIC 99 VALUE 10.
01 ARE-THERE-MORE-RECORDS PIC X(3) VALUE 'YES'.
88 MORE-RECORDS VALUE 'YES'.
88 NO-MORE-RECORDS VALUE 'NO'.
01 WS-DATE.
05 WS-YEAR PIC 9(4).
05 WS-MONTH PIC 99.
05 WS-DAY PIC 99.
01 HDR-1.
05 PIC X(40).
05 PIC X(12)
VALUE 'BONUS REPORT'.
05 PIC X(8).
05 PIC X(5) VALUE 'PAGE'.
05 PAGE-NO PIC 99 VALUE 0.
05 PIC X(4).
05 DATE-OUT.
10 MONTH-OUT PIC 99.
10 PIC X VALUE '/'.
10 DAY-OUT PIC 99.
10 PIC X VALUE '/'.
10 YEAR-OUT PIC 9(4).
01 HDR-2.
05 PIC X(10).
05 PIC X(13)
VALUE 'TERRITORY --'.
05 TERRITORY-NO-OUT PIC X(2).
01 HDR-5.
05 PIC X(20).
05 PIC X(10)
VALUE 'OFFICE -- '.
05 OFFICE-NO-OUT PIC X(2).
01 HDR-7.
05 PIC X(10).
05 PIC X(14)
VALUE 'EMPLOYEE NAME'.
05 PIC X(8).
05 PIC X(5)
VALUE 'BONUS'.
01 DETAIL-LINE.
05 PIC X(7).
05 EMPLOYEE-NAME-OUT PIC X(24).
05 BONUS-OUT PIC $BZ,ZZZ.99 BLANK WHEN ZERO.
I'm not going to count them all and add them up, but it seems like you might be long.
It's not explicitly stated here, but it looks like your record in your BONUS-REPORT is probably a REDEFINES of the HDR-n and DETAIL-LINE, so the count of the longest of these is the record size (assuming fixed length records).
Count BONUS-OUT as 10. There should not be alignment because everything is USAGE IS DISPLAY by default. The VALUE clauses make no difference in the count.
The answer to your question is to ask the compiler for the answer.
That is, compile the program as-is and check the compiler listing and it should tell you how long each field and record is. Then you can go back into the source code and update as needed.
Depending on which enviroment you are using (mainframe, unix, windows, etc.) there might be certain compiler options that need to be set to tell the compiler create that kind of compiler listing. For me using z/OS on the mainframe with the 4.2 release of the compiler, the options are all documented in the Enterprise COBOL for z/OS Programming Guide at http://pic.dhe.ibm.com/infocenter/pdthelp/v1r1/topic/com.ibm.entcobol.doc_4.2/PGandLR/ref/rpcos390.htm.
Strictly speaking bonus record is 222 bytes because that what you say it is:--
01 BONUS-REPORT-RECORD PIC X(222).
What you probably are asking is what is the length of the various header and detail entries.
Normally these would all be written as separate records -- so the longest record would be HDR-1 at 81 bytes. All the others are shorter.