How do I identify the level of a field in copybook

2019-03-04 16:18发布

I am trying to read a EBCDIC file and convert it to ASCII format in Java, with a help of copybook. I am using JRecord to read the copybook. So now, how do I get the field level from the copybook using JRecord?

Edit 1:

Kindly excuse me for a vague question. I have no experience in mainframe or cobol. I am adding few more details if it could help.

My source file contains multiple transaction details. The copybook contains the information on the transaction and the fields relating to that particular transaction.

I have to split the each transaction and its fields to a separate file(containing one transaction and respective fields).

CopyBook

In attached copybook, the field in line 1 can have values from line 2 to line 4. If the EXTRA-TYPE is 01, then I have to read fields in line 6 to line 11. Similarly, if the EXTRA-TYPE is 02, then I have to read fields in line 12 to line 16. I am trying to split the Transaction type and its respective fields dynamically. (I need to get the start and end position of the fields with respect to the transaction type in line 1)How do I achieve this in Java?

I appreciate your help.

2条回答
姐就是有狂的资本
2楼-- · 2019-03-04 17:15

Have a read of http://www.catb.org/~esr/faqs/smart-questions.html or https://www.mikeash.com/getting_answers.html about asking questions

But any way:

Using the Code Generation

enter image description here

  • Enter the Cobol Copybook, Sample cobol file (if you hava one). You will probably be able to use the Split Copybook On Redefines option

enter image description here

  • On the Records panel, enter DA147-EXTRA-TYPE in the Record Type field

enter image description here

  • Press the Generate Code button. On the next screen you can select the template. The Standard template is a good starting point

enter image description here

  • Press the Generate code button, The program should generate some sample code like:

        ICobolIOBuilder iob = JRecordInterface1.COBOL
                                   .newIOBuilder(copybookName)
                                       .setFileOrganization(Constants.IO_BIN_TEXT)
                                       .setSplitCopybook(CopybookLoader.SPLIT_REDEFINE)
                                   ;  
    
    
        FieldNamesAmspodownloadRedef1.RecordPoHeaderRecord rPoHeaderRecord = FieldNamesAmspodownloadRedef1.RECORD_PO_HEADER_RECORD;
        FieldNamesAmspodownloadRedef1.RecordProductRecord rProductRecord = FieldNamesAmspodownloadRedef1.RECORD_PRODUCT_RECORD;
        FieldNamesAmspodownloadRedef1.RecordLocationRecord rLocationRecord = FieldNamesAmspodownloadRedef1.RECORD_LOCATION_RECORD;
        AbstractLineReader reader = iob.newReader(dataFile);
        while ((line = reader.read()) != null) {
            lineNum += 1;
            if (
               "H1".equals(line.getFieldValue(rPoHeaderRecord.recordType).asString())
            )  {
    
               System.out.println(
                          line.getFieldValue(rPoHeaderRecord.recordType).asString()
                  + " " + line.getFieldValue(rPoHeaderRecord.sequenceNumber).asString()
                  + " " + line.getFieldValue(rPoHeaderRecord.vendor).asString()
                  + " " + line.getFieldValue(rPoHeaderRecord.po).asString()
                    ....
                  + " " + line.getFieldValue(rPoHeaderRecord.cancelByDate).asString()
                  + " " + line.getFieldValue(rPoHeaderRecord.ediType).asString()
               );
            }
            if (
               "D1".equals(line.getFieldValue(rProductRecord.recordType).asString())
            )  {
    
               System.out.println(
                          line.getFieldValue(rProductRecord.recordType).asString()
                  + " " + line.getFieldValue(rProductRecord.packQty).asString()
                  + " " + line.getFieldValue(rProductRecord.packCost).asString()
                  + " " + line.getFieldValue(rProductRecord.apn).asString()
                  + " " + 
                      .....
                  + " " + line.getFieldValue(rProductRecord.productName).asString()
               );
            }
            if (
               "S1".equals(line.getFieldValue(rLocationRecord.recordType).asString())
            )  {
    
               System.out.println(
                          line.getFieldValue(rLocationRecord.recordType).asString()
                  + " " + line.getFieldValue(rLocationRecord.dcNumbe.get(0)).asString()
                  + " " + line.getFieldValue(rLocationRecord.packQuantit.get(0)).asString()
               );
            }
    
查看更多
时光不老,我们不散
3楼-- · 2019-03-04 17:22

Why do you need to get the Field Level ???. To convert a file to ascii you do not need the Field Level.


Utility Conversion Program

To Convert a Cobol File to ascii you can use one of the utility programs:

  • Cobol2Csv sub-project - converts a Cobol data file to a Csv file
  • Cobol2Xml sub-project - converts a Cobol data file to a Xml file
  • Cobol2Json json utiltiy

Java processing of a Cobol file

If you want to do some processing on the File, you can use the Generate function of the RecordEditor to generate sample JRecord code from the Cobol copybook.

Code generated with standard template

If you use the standard template, the RecordEditor will generate code like:

    AbstractLine line;
    int lineNum = 0;

    try {
        ICobolIOBuilder iob = JRecordInterface1.COBOL
                                   .newIOBuilder(copybookName)
                                       .setFont("cp037")
                                       .setFileOrganization(Constants.IO_FIXED_LENGTH)
                                       .setSplitCopybook(CopybookLoader.SPLIT_NONE)
                                   ;  


        FieldNamesDtar020.RecordDtar020 rDtar020 = FieldNamesDtar020.RECORD_DTAR020;
        AbstractLineReader reader = iob.newReader(dataFile);
        while ((line = reader.read()) != null) {
            lineNum += 1;
            System.out.println(
                          line.getFieldValue(rDtar020.keycodeNo).asString()
                  + " " + line.getFieldValue(rDtar020.storeNo).asString()
                  + " " + line.getFieldValue(rDtar020.date).asString()
                  + " " + line.getFieldValue(rDtar020.deptNo).asString()
                  + " " + line.getFieldValue(rDtar020.qtySold).asString()
                  + " " + line.getFieldValue(rDtar020.salePrice).asString()
               );
        }

        reader.close();
    } catch (Exception e) {
        System.out.println("~~> " + lineNum + " " + e);
        System.out.println();

        e.printStackTrace();
    }

Code generated with lineWrapper template

  AbstractLine line;
    int lineNum = 0;

    try {
        ICobolIOBuilder iob = JRecordInterface1.COBOL
                                   .newIOBuilder(copybookName)
                                       .setFont("cp037")
                                       .setFileOrganization(Constants.IO_FIXED_LENGTH)
                                       .setSplitCopybook(CopybookLoader.SPLIT_NONE)
                                   ;  


       LineDtar020JR lineDtar020JR = new LineDtar020JR();


       AbstractLineReader reader = iob.newReader(dataFile);
       while ((line = reader.read()) != null) {
           lineNum += 1;
           lineDtar020JR.setLine(line);
           System.out.println(
                          lineDtar020JR.getKeycodeNo() 
                  + " " + lineDtar020JR.getStoreNo() 
                  + " " + lineDtar020JR.getDate() 
                  + " " + lineDtar020JR.getDeptNo() 
                  + " " + lineDtar020JR.getQtySold() 
                  + " " + lineDtar020JR.getSalePrice() 
               );
        }

        reader.close();
    } catch (Exception e) {
        System.out.println("~~> " + lineNum + " " + e);
        System.out.println();

        e.printStackTrace();
    }

Generic Cobol processing

If you want to do more generic processing you can use a fieldIterator:

FieldIterator fieldIterator = line.getFieldIterator("Record-Name");

JRecord Examples

In the latest release of JRecord 0.81.4 there are examples in the Source/JRecord_IO_Builder_Examples/src directory


Tree processing

If you need to access level numbers with JRecord, use CobolSchemaReader.newCobolSchemaReader(...) interface.

Also you could look at the code for Cobol2Xml sub-project. It does tree processing by extending CobolSchemaReader

查看更多
登录 后发表回答