As mentioned in yesterday’s blog post about MQEdit V9.2.1, we have focused on improving MQEdit’s support for COBOL described IBM MQ messages. One part of that was the creation of a free utility called MakeFmt, which can convert your COBOL copybook into an MQEdit User Format file. This then makes it possible to be able to view your MQ messages in their full, field by field, format.
This blog post hopes to illustrate some of the capabilities of the MakeFmt utility and we’ll start with a little COBOL structure, created to illustrate several of the features of MakeFmt in as small a space as possible.
Example COBOL copybook CUST.cpy
01 CUST. 10 FULL-NAME PIC X(30). 10 ADDRESS-LINE PIC X(40) OCCURS 4 TIMES. 10 CUSTOMER-NUMBER PIC 9(05) COMP SYNC. 10 NUM-INVOICES PIC 9(05) COMP. 10 INVOICE OCCURS 1 TO 10 TIMES DEPENDING ON NUM-INVOICES. 20 INVOICE-NUMBER PIC 9(10). 20 INVOICE-NUMBER-PARTS REDEFINES INVOICE-NUMBER. 30 DEPT PIC X(04). 88 HARDWARE VALUE '1047'. 88 SOFTWARE VALUE '5729'. 88 SERVICES VALUE '7632'. 30 CUST-ID PIC 9(04). 30 UNIQUE-NUMBER PIC 9(02). 20 INVOICE-DATE PIC S9(7) COMP-3. 20 INVOICE-TYPE PIC X(01). 88 RECUR-ANNUAL VALUE 'A'. 88 RECUR-MONTHLY VALUE 'M'. 88 ONE-OFF VALUE 'O'. 20 PO-NUMBER PIC 9(10). 20 INVOICE-TOTAL PIC S9(5)V9(2) COMP-3. 10 OVERALL-TOTAL PIC S9(7)V9(2) COMP-3.
To show you the result first, here is how MQEdit could display an MQ message of this shape. I’ve just showed the first member of the array of invoices for the sake of brevity.
[ 292 bytes] CUST FULL_NAME :'PAUL CLARKE ' ADDRESS_LINE array [1..4] [1] :'1600 PENNSYLVANIA AVE ' [2] :'WASHINGTON DC ' [3] :'U.S.A. ' [4] :' ' CUSTOMER_NUMBER:12345 NUM_INVOICES :3 INVOICE array [1..3] [ 92 bytes] INVOICE INVOICE_NUMBER:'1047003101' INVOICE_DATE :2020056 25th February 2020 INVOICE_TYPE :'O' ONE_OFF PO_NUMBER :'9776543210' INVOICE_TOTAL :4357.99 End of structure 'INVOICE' (29 bytes)
So how do we get there. Well, very simply, you can take your COBOL copybook, in my example called CUST.cpy, and run it through MakeFmt with the following command.
makefmt -i CUST.cpy
This will create you a file called CUST.fmt with a starting struct
called CUST
and you can add the following to a file that MQEdit uses to find User Formats and you’re off and running.
include "CUST.fmt" queue INVOICES { struct CUST; }
MakeFmt mapping COBOL to MQEdit User Formats
MakeFmt doesn’t do anything you couldn’t have done by hand manually, but with a big copybook, you might prefer to have a program do it for you, since its speeds things up. There are no secrets here though. Let’s take a look at how MakeFmt translates from one to the other. In case you want to see it all at once, here’s the full output CUST.fmt
file.
Generated MQEdit User Format file CUST.fmt
enum DEPT_enum { "1047", "HARDWARE"; "5729", "SOFTWARE"; "7632", "SERVICES"; } enum INVOICE_TYPE_enum { "A", "RECUR_ANNUAL"; "M", "RECUR_MONTHLY"; "O", "ONE_OFF"; } struct INVOICE_NUMBER_PARTS { char DEPT[4](DEPT_enum); char CUST_ID[4]; char UNIQUE_NUMBER[2]; } struct INVOICE { char INVOICE_NUMBER[10]; packed(7) INVOICE_DATE; char INVOICE_TYPE(INVOICE_TYPE_enum); char PO_NUMBER[10]; packed(5.2) INVOICE_TOTAL; } struct CUST { char FULL_NAME[30]; char ADDRESS_LINE[40][4]; align4; uint CUSTOMER_NUMBER; uint NUM_INVOICES; struct INVOICE[NUM_INVOICES]; packed(7.2) OVERALL_TOTAL; }
MakeFmt know COBOL data types
MakeFmt knows how to map various COBOL data types into MQEdit User Format data types. Here are a few examples. A more exhaustive list can be found in the MakeFmt User Guide.
PIC X(n)
maps tochar[n]
PIC S9(n) COMP-3
maps topacked(n)
PIC 9(n) COMP
maps toushort/uint/uint64
(and depending on your minimum binary sizeuint8
)PIC 9(n) COMP-1/2
maps tofloat/double
MakeFmt translates COBOL groups
A COBOL group will become an MQEdit User Format struct
. You can see this illustrated in our example looking at the INVOICE
group. It is mapped to an INVOICE struct
.
MakeFmt creating arrays
The COBOL keyword OCCURS
becomes an MQEdit User Format array. The ADDRESS_LINE
field is an example of a static array.
When we add the COBOL DEPENDING ON
clause, then we get a variable array as the struct INVOICE
shows.
MakeFmt creates value sets as enum
definitions
When you have a number of level 88 statements, these can often to mapped into enumeration definitions. It is only really useful with single value statements, so at the moment MakeFmt ignores any ranges or multiple value statements, and just uses the single values to make up an enum
. Look at INVOICE_TYPE
field to see how this has translated. These enum
definitions also add greatly to the formatted output in MQEdit as you’ll see if you look at the INVOICE_TYPE
field in that output display I showed earlier.
MakeFmt offers you the choice of whether to use REDEFINED fields or not
If, as in our example, you have REDEFINED fields and you’d prefer to use those in your MQEdit User Format, you can tell MakeFmt to create the format using those fields as follows:-
makefmt -i CUST.fmt -r INVOICE-NUMBER-PARTS
This will generate a slightly different output using the REDEFINED field instead of the original field as was done in the first example.
We were very fortunate to be able to seed this project with a substantial COBOL copybook along with some sample MQ messages made using that copybook donated to us from an MQ customer. We would love to receive other challenging sample messages with their copybooks from anyone who is willing or able to supply them to us.
As with all tools, it is likely easier to understand the usage by trying it out yourself. MakeFmt is a free utility so you don’t need a licence for it. To view messages with your created formats you will need MQEdit. If you don’t already have MQEdit, and would like to try it, please send an email to support@mqgem.com and a 1-month trial licence will be sent to you.