In Micro Focus Native Cobol I have this variable:
01 aCharArray object reference.
It's VT-BSTR. How to move its value to standard Cobol PIC X(n) variable?
I would presume its an instance of a CharacterArray so you can use getValue or getValuewithSize if you want to specify a size.
If you look at the base class library docs in the Net Express help you should find details on these methods.
Related
Simple question that I cannot find an answer to through web-searching.
Is it valid to have a field in a COBOL copybook without a name? i.e. is the following valid?
05 SUMMARY.
07 DETAILS OCCURS 3 TIMES
PIC X(10).
07 PIC X(100).
Is this the same as say using FILLER instead of the name? If not, what is the difference between a blank name and using FILLER?
Is this the same as say using FILLER instead of the name?
Yes it is. The requirement to use FILLER for an unreferenced data item was removed in COBOL85.
Using one or the other is mostly a "style" issue, commonly there will be a "shop/team rule" about what to use.
Note: this is not strictly related to a copybook, it is the same when used in any data description entry in the program's source.
For documentation (I assume you meant an IBM mainframe here) see the appropriate entry in the IBM COBOL Language Reference.
I have been looking around to find information on COBOL directives that come with vanilla PeopleSoft COBOLs.
I can find information for directives during the unicode conversion process but nothing else.
Specifically I am interested in MVSRND, what does it do?
Here's an example use:
MVSRND 01 WK-HPREC.
MVSRND 02 WK-HIGH-PREC PIC S9(12)V9(6) COMP-3.
It looks like "MVSRND" (which in the sequence area), is a tag for MVS RANDOM support.
Which might be related to the use of the function random/CEERAN0 or some other api.
I'm very new to COBOL. I'm following the tutorials that came with Micro Focus and I can't seem to get the example to work right. I'm trying to print -123.45 and I keep getting the following,
I looked up a number of posts on here and they don't address my problem. I'm using Micro Focus' Visual COBOL in Eclipse. Here's my code,
program-id. tictac as "tictac".
environment division.
configuration section.
data division.
working-storage section.
01 WS-NUM3 PIC S9(3)V9(2) VALUE -123.45.
procedure division.
Display WS-NUM3.
goback.
end program tictac.
The V in your picture clause is an implied decimal point. I think you want a field with PIC -999.99, where the . is an explicit decimal point, for its picture clause.
You might think of this as COBOL making a distinction between how a variable is defined and how it is shown. Sort of like a format string in printf is just specifying how to show a variable, not how it is defined. Though in both cases the definition and how it is shown have to match up to a certain extent.
Choosing the right picture clause for a numeric field is important; if you're doing calculations it can have a significant performance impact.
So it's common to have a field with a definition such as...
PIC 9(4)V99 COMP-3
...and a corresponding field for output purposes such as...
PIC ZZZ9.99
...so that computations can be done on the first, and when displaying the field is necessary one uses a MOVE statement to copy the contents of the first to the second.
What is the difference between BY CONTENT and BY VALUE in a CALL statement in COBOL?
BY CONTENT on a CALL will copy the content of the identifier to a compiler-managed area of storage, which will then be passed to the CALLed program "by reference" implicitly.
This means the CALLed program can change the data, but no change made in the CALLed program will affect the original data in the CALLing program.
Any identifier, of any size valid for the compiler, can be used BY CONTENT (subject to any limits, if existing, which are documented for the specific compiler - you never know).
Although you can change the value in a CALLed program, it would seem a bit obscure to do so, at best.
BY VALUE is an entirely different beast. It is very limited, in that the value "passed" can be either an "integer" or a one-byte alphanumeric value. It can also be a literal.
The PROCEDURE DIVISION USING ... has to know, in the case of BY VALUE, that is is so, by specifying it in an equivalent manner to the CALL. BY REFERENCE and BY CONTENT on the CALL are both BY REFERENCE on the PROCEDURE DIVISION USING.
How this is implemented is down to the specific compiler. IBM Enterprise COBOL puts the value itself in the "parameter list".
Passing parameters by content is the same as passing by reference, except that the data is not copied back into the COBOL memory when the call has completed. Meaning that the original variable cannot be edited by the Called unit.
So the difference between BY CONTENT and BY VALUE is that in the case of BY VALUEonly the value gets passed and therefor not all kind of variables can be passed this way while BY CONTENT the pointer of a copied variable gets passed and in this way every type of variable can be passed.
See: http://documentation.microfocus.com/help/index.jsp?topic=%2Fcom.microfocus.eclipse.infocenter.visualcobol.eclipseux%2FGUID-EB09203C-3873-4DBE-9298-0C353BC0701A.html
By Reference:
When a parameter is passed by reference, a copy of the item in the JVM
COBOL is passed to the native code. When the call to the native has
finished, any changes to the information made in the native code are
copied back to the JVM COBOL. However, this does mean that memory is
shared between the JVM and native environments. In fact, what is
actually passed to the native code is a pointer to the copied data.
This is useful if you are calling non-COBOL programs. The implications
of this are very important, particularly in multi-threaded
environments. Any changes to reference parameters are not visible to
the JVM COBOL calling program until the call has completed.
Arbitrarily complex group items (within the memory limitations) can be
passed by reference. The group definition must be identical in the
native and JVM COBOL source code and it must not contain USAGE POINTER
items. Strings (java.lang.Strings) and tables (java.lang.byte arrays)
can be passed by reference. All other objects (types that inherit from
java.lang.Object, including valuetypes) cannot be passed by reference
(or by value - see below).
By Content
Passing parameters by content is the same as passing by reference,
except that the data is not copied back into the JVM COBOL memory when
the call has completed. Any item that can be passed by reference can
be passed by content.
By Value
In JVM COBOL, the only items that can be passed by value are as
follows: binary-long - the recommended type for passing by value pic
x(4) comp-x pic (9)9 comp pic s(9)9 comp pic (9)9 comp-5 pic s(9)9
comp-5
How do I create a table from a copybook in Cobol?
The copybook has several groups in it and only need one of them to be in a table.
Do I need to use the copybook multiple times replacing the start of variables so that the compiler views them as different things?
I can edit the copybook as long as the other programs using it will compile.
It is on an IBM Mainframe.
See my answer below for my final solution. Thanks to #Bruce Martin
You say that you can't change the copybook. Well, the copybook can be changed in such a way that it affects nothing else.
This is an example from the Enterprise COBOL Language Reference:
Example 3
If the following conventions are followed in library text, then parts of names (for
example the prefix portion of data names) can be changed with the REPLACING
phrase.
In this example, the library text PAYLIB consists of the following data division
entries:
01 :TAG:.
02 :TAG:-WEEK PIC S99.
02 :TAG:-GROSS-PAY PIC S9(5)V99.
02 :TAG:-HOURS PIC S999 OCCURS 1 TO 52 TIMES
DEPENDING ON :TAG:-WEEK OF :TAG:.
The programmer can use the COPY statement in the data division of a program as
follows:
COPY PAYLIB REPLACING ==:TAG:== BY ==Payroll==.
Usage Note: It is important to notice in this example the required use of colons or
parentheses as delimiters in the library text. Colons are recommended for clarity
because parentheses can be used for a subscript, for instance in referencing a table
element.
In this program, the library text is copied; the resulting text is treated as if it had
been written as follows:
01 PAYROLL.
02 PAYROLL-WEEK PIC S99.
02 PAYROLL-GROSS-PAY PIC S9(5)V99.
02 PAYROLL-HOURS PIC S999 OCCURS 1 TO 52 TIMES
DEPENDING ON PAYROLL-WEEK OF PAYROLL.
The changes shown are made only for this program. The text, as it appears in the
library, remains unchanged.
So, for that 01 within the existing copybook, you can replace the data definitions after the 01 with a COPY ... REPLACING ... to give the same prefix (assuming the data-names have prefixes....) and then create your new copybook with adjusted level-numbers if needed (for instance, the example show level-numbers 02, which is always silly, but this is probably not the only example of that in the world). The different level numbers will not affect any existing code (as the compiler normalises all level numbers anyway, so the compiler will always treat the lowest level number after the 01 as 02, the second-lowest as 03, etc).
Then you can use your new copybook in your table.
Be aware that you will have to use subscripting to reference any fields in the table.
If you really cannot change the copybook (some odd diktat, happens at times) then perhaps the best bet would be to make a new copybook which is the same, but with different prefixes, and without the 01-level, for flexibility.
We now need the purpose of storing the records.
It seems that you have something like this:
copy reclyout.
01 record-layout-1.
...
01 record-layout-2.
...
01 record-layout-3.
...
And with that, you want to store the record-layout-2 records, only, in a table.
As Bruce Martin asked, knowledge of which compiler and OS you are using would be useful. Some, not all, COBOL compilers support nested copy statements. You could replace the layout of your record in the original copybook with a copy statement for a new copybook which contained the layout.
You'd have a minor issue that you'd need the 01 itself to be outside the copybook, and you'd need to allow a sufficient gap in the level-numbers to allow for your table definition to include the new copybook.
01 The-Table.
05 some-name OCCURS 100 TIMES.
copy newlyout.
The highest-level data definition(s) in the copybook would have to begin with level-numbers greater than 05. This is not much of a problem to achieve. COBOL compilers will "normalise" the level-numbers anyway, and the chance of you making something less flexible by doing this is almost nil. It is your best solution if your compiler supports nested copy statements.
Yes, using COPY with REPLACING would be very useful. It is always ugly to have to use qualification of data-names (or labels).
If not, consider doing the same thing, but removing that particular layout from the existing copybook and simply including the new copybook after the original copy statement(s). Whether you are able to do this will depend on how much the copybook is used elsewhere. Take it to your analyst/boss.
If that is not possible, make a new copybook for the table, and use comments and other documentation available to you to establish a relationship between the two data-definitions. Not ideal, but a common way that it is done.
Another possibility is to simply define areas within the table, and use the record-layout, via a MOVE to the record-layout. This is another common way, which does need documentation and checks for the lengths in the table/record-layout and is an ungainly/inefficient way to do it. Again, you'll come across that way, probably.
If you cough on the compiler/OS there are some other ways as well.
The IBM's mainframe supports nested copybooks, so you can change your copybook to a
nested copybook
Also have a look at
"COPY" statement with "REPLACING" in COBOL
so
01 record-layout-1.
...
01 record-layout-2.
...
01 record-layout-3.
...
can be changed to
01 record-layout-1.
...
01 record-layout-2.
...
01 record-layout-3.
copy newCopy.
...
and in your program you can use the newCopy or what ever you call it. You will probably want to renumber copybook levels while you are at it.
So if the original copybook is
01 record-layout-3.
05 field-1 pic x(4).
05 field-2 ...
you would create the new copybook as
25 field-1 pic x(4).
25 field-2 ...
The actual level numbers are not important, they just need to be > 01 for the copybook. Using 25 will make it easy to embed in your working storage.
A few companies make it a standard- copybooks must not contain 01 levels so that copybooks can also be embedded in Working storage. This is rare though
My final solution.
I actually ended not having to create a table from copybooks but still needed the 01 groups variables to be their own copybooks to create multiple instances of variables with the same structure just with different 01 group names and variable names.
I ended up creating individual copybook books for the 01 groups variables, and then using a Replace block to make the nested copybook look like the original. See below for final result.
REPLACE ==(TAGEIGHT)== BY ==N==.
01 STD-NACHA-FILE-HEADER.
COPY ABRYNAFH.
01 STD-NACHA-BATCH-HEADER.
COPY ABRYNABH.
01 STD-NACHA-DETAIL-TRANS.
COPY ABRYNADT.
01 STD-NACHA-DETAIL-ADDENDA-REC.
COPY ABRYNADA.
01 STD-NACHA-BATCH-TOTAL-REC.
COPY ABRYNABT.
01 STD-NACHA-FILE-TOTAL-REC.
COPY ABRYNAFT.
01 STD-NACHA-FILE-PAD-REC.
COPY ABRYNAFP.
01 STD-NACHA-RETURN-REC.
COPY ABRYNARR.
REPLACE OFF.
I went here for how to use Replace within a copybook.