Programming alternatives, Part 2

The Background:
In 2010 I posted a question about alternatives to Easytrieve in this thread. Now there has been a disaster. My computer crashed at the end of August. This has led to many frustrations with the new Access 2010 program and other things. I was running Easytrieve on my computer, and the reinstallation is an older version than the one I was using. It’s run up against a licensing issue. At first I was just getting an error window letting me know there’s a licensing error. Today I got a pop-up window when I tried to start the program that said I don’t have a license and I can’t use the software. In 2010 I received this message from Computer Associates, the maker of Easytrieve:

Here’s the thing: Even though we have a license, they will not tell me how to fix the error because we let our maintenance contract expire in 2014. So now I’m dead in the water, and I don’t know what my employer will do. I need to revisit alternatives to Easytrieve.

The Recap:

I need to:
[ul][li]Reformat the file (There are many different formats, depending on things, and there are usually two or three output files of the same data in different formats);[/li][li]Add fields;[/li][li]Compare the current file with the previous file and use data from the previous file when there is a match on the key field;[/li][li]Add numeric fields together to create a new field (or to replace two or more fields with one);[/li][li]Add numeric fields together and compare them to the Total field. If they don’t match within set parameters, then the record is written to a different file;[/li][li]Display a summary of the number of records that meet various parameters;[/li][li]Write two output files, plus one or more files (non-matching totals, rejects, etc.);[/li][li]Scan fields to remove and/or replace characters;[/li][li]Sort files;[/li][li]Other things as needed.[/ul][/li]
Easytrieve reads fixed-position text files, so Excel spreadsheets are imported into Access and then exported as fixed-position text files. Software that can read an Excell or .csv file directly would be nice. Note, however, that not all fields are populated.

In the other thread, the consensus seems to be that I should use Perl or Python, with Python seeming to have the lead. I think it was last year that I tried to find a community college class to learn Python, and wasn’t turning up anything useful. Given that I have a specific set of things I need to do with the data, is Python still the way to go? How the hell do I go about learning it? (FWIW, I learned Easytrieve 20-some years ago by starting with programs that already did what I wanted to do, and modified them for other data.)

I want to show the type of thing I’m going. This is the third of a three-part process. The first part sorts two files by account number. The second part compares the new file to the previous file and, if the a/r numbers match, use the names and addresses from the previous file to put into the output file. New records that do not exist in the previous file are written to a different output file, where they are incorporated into the ‘clean’ file. This third part reads the ‘cleaned’ file, does some calculations, and writes to two different formats in two different output files. I’ll have to break this up into multiple posts for SDMB character limits.


*********************************************************************
*********************************************************************
**  802861 [Company name] Ltd                                      **
**  10/23/13 -- [Johnny L.A.]                                      **
*********************************************************************
*********************************************************************   

FILE FILEA V(1000) SEQUENTIAL +
SYSNAME 'H:\EZ_Text_Files\802861_Input.txt'
AR-NUM                      6   12  A  
NAME                       18   40  A   
NAME2                      58   40  A
ADDR1                      98   30  A
ADDR2                     128   30  A
CITY                      158   20  A
STATE                     178    2  A
ZIP                       198    5  A
*ZIP-4                     204    4  A
ZIP-4                     203    4  A
ZIP-9                     198    9  A  
BALANCE                   208   12  A 
BALANCE-NUM               208   12  N 0 
BALANCE-BYTE-IN1      BALANCE    1  A INDEX SUB1 
BALANCE-DOLLARS           208   10  N
BALANCE-CENTS             218    2  N
CURRENT                   220   12  A    
CURRENT-NUM               220   12  N 0
CURRENT-BYTE-IN1      CURRENT    1  A INDEX SUB1     
CURRENT-DOLLARS           220   10  N
CURRENT-CENTS             230    2  N
01-30                     232   12  A  
01-30-BYTE-IN1          01-30    1  A INDEX SUB1  
01-30-DOLLARS             232   10  N
01-30-CENTS               242    2  N
31-60                     244   12  A 
31-60-BYTE-IN1          31-60    1  A INDEX SUB1    
31-60-DOLLARS             244   10  N
31-60-CENTS               254    2  N
61-90                     256   12  A 
61-90-BYTE-IN1          61-90    1  A INDEX SUB1 
61-90-DOLLARS             256   10  N
61-90-CENTS               266    2  N       
OVER-90                   268   12  A 
OVER-90-BYTE-IN1      OVER-90    1  A INDEX SUB1
OVER-90-NUM               268   12  N 0
OVER-90-DOLLARS           268   10  N
OVER-90-CENTS             278    2  N
OVER-120                  280   12  A 
OVER-120-BYTE-IN1    OVER-120    1  A INDEX SUB1
OVER-120-NUM              280   12  N 0
OVER-120-DOLLARS          290   10  N
OVER-120-CENTS            290    2  N
PHONE-AREA                292    3  A
PHONE-PRE                 295    3  A
PHONE-REST                298    4  A  

FILE FILEB V SEQUENTIAL CREATE RESET +
SYSNAME 'G:\Auto Data\802861_BIS.txt'
*SYSNAME 'H:\EZ_Text_Files\802861_BIS.txt'
*BIS-format output file
CDR-OUT-REC                  1 350  A
CDR-REC-CD                   1   1  A
CDR-CONTRIB#                 2   6  A
CDR-BUS-CAT                  8   4  A
CDR-ACCT-NAME               12  40  A
CDR-ADDL-NAME               52  40  A
CDR-ADDR1                   92  30  A
CDR-ADDL-ADDR              122  30  A
CDR-SIC-CODE               152   4  A
CDR-CITY-ST-CD             157   1  A
CDR-CTY                    158  20  A   
CDR-ST                     178  20  A
CDR-ZIP                    198   5  A
CDR-ST-ABBREVIATION        203   2  A  
CDR-EXTDT                  208   6  A
CDR-EXTDT-MM               208   2  A
CDR-EXTDT-DD               210   2  A
CDR-EXTDT-YY               212   2  A   
CDR-ARNUM                  214  12  A
CDR-CUS-SIC-CODE           226   4  A
CDR-PHONE                  230  10  A
CDR-PHONE-AREA             230   3  A  
CDR-PHONE-PREFIX           233   3  A
CDR-PHONE-REST             236   4  A
CDR-YRS-CUST-CD            248   1  A
CDR-YRS-CUST               249   2  N 0
CDR-DOLS-MM                251   2  A
CDR-DOLS-YY                253   2  A 
CDR-DOLS-MM-NUM            251   2  N 0
CDR-DOLS-YY-NUM            253   2  N 0
CDR-TERMS                  255   7  A  
CDR-RHC-CODE               262   1  A
CDR-RHC                    263   8  N
CDR-BAL-CODE               271   1  A
CDR-BALANCE                272   8  N 0
CDR-BAL-SIGN               280   1  A
CDR-CURRENT                281   7  N 0
CDR-CUR-SIGN               288   1  A
CDR-01-30                  289   7  N 0
CDR-01-30-SIGN             296   1  A  
CDR-31-60                  297   7  N 0
CDR-31-60-SIGN             304   1  A 
CDR-61-90                  305   7  N 0
CDR-61-90-SIGN             312   1  A 
CDR-OVER-90                313   7  N 0
CDR-OVER-90-SIGN           320   1  A 
CDR-COMMENT-CD             321   2  A
CDR-ZERO-FILL              323   4  A
CDR-OPTIONAL-ZIP5          329   5  A 
CDR-OPTIONAL-ZIP4          334   4  A
CDR-OPTIONAL-ZIP9          329   9  A
A-REC                        1 350  A
A-REC-CODE                   1   1  A
A-CONTUM                     2   6  A 
A-VERSION                    8   6  A     
A-DATE                     171   6  A
A-MM                       171   2  A     
A-DD                       173   2  A
A-YY                       175   2  A
A-DESCRIPTION              177  25  A  
A-TEMP-DATE                232   8  A   
A-TEMP-MM                  232   2  A 
A-TEMP-DD                  235   2  A 
A-TEMP-YY                  238   2  A
A-TEMP-YY-N                238   2  N  
Z-REC                        1 350  A
Z-REC-CODE                   1   1  A
Z-REC-COUNT                  2   7  N
Z-RHC                        9  10  N 0
Z-BALANCE                   19  10  N 0
Z-CURRENT                   29  10  N 0
Z-01-30                     39  10  N 0
Z-31-60                     49  10  N 0
Z-61-90                     59  10  N 0
Z-OVER-90                   69  10  N 0
FILE FILEC V SEQUENTIAL CREATE RESET +
SYSNAME 'G:\Auto Data\802861_CPEG.txt'
*SYSNAME 'H:\EZ_Text_Files\802861_CPEG.txt'
*CPEG-format output file
*CPEG header record
CPEG-RECORD                       1   1430  A  
CPEG-A-REC                        1    183  A
CPEG-A-REC-CODE                   1      2  A
CPEG-A-VERSION                    3      8  A
CPEG-A-CONTUM                    11      6  A 
CPEG-A-EQUIFAX                   17     10  A
CPEG-A-DANDB                     27      9  A
CPEG-A-CONT-NAME                 36    120  A
CPEG-A-CREATE-DATE              156      8  A
CPEG-A-CREATE-MM                156      2  A     
CPEG-A-CREATE-DD                158      2  A
CPEG-A-CREATE-CC                160      2  A
CPEG-A-CREATE-YY                162      2  A
CPEG-A-EXT-DATE                 164      8  A
CPEG-A-EXT-MM                   164      2  A     
CPEG-A-EXT-DD                   166      2  A
CPEG-A-EXT-CC                   168      2  A
CPEG-A-EXT-YY                   170      2  A  
CPEG-A-TEMP-DATE                276      8  A   
CPEG-A-TEMP-MM                  276      2  A 
CPEG-A-TEMP-DD                  279      2  A
CPEG-A-TEMP-YY                  282      2  A

*CPEG data record
CPEG-OUT-REC                  1   1430  A
CPEG-REC-CD                   1      2  A
CPEG-CONTRIB#                 3      6  A
CPEG-BUS-CAT                  9      4  A
CPEG-EXTDT                   13      8  A
CPEG-EXTDT-MM                13      2  A
CPEG-EXTDT-DD                15      2  A
CPEG-EXTDT-CC                17      2  A
CPEG-EXTDT-YY                19      2  A
CPEG-EXTDT-YY-N              19      2  N 0
CPEG-SUB-CODE                21      7  A
CPEG-EQUIFAX-CONTNUM         28     10  A
CPEG-DANDB-CONTNUM           38      9  A
CPEG-NAME-DISPLAY            47      1  A 
CPEG-ACCT-NAME               48    120  A
CPEG-NAME-TYPE              168      3  A
CPEG-EXP-BIN                171     10  A
CPEG-DUNS                   181     10  A
CPEG-EQUIFAX-ID             191     10  A
CPEG-CUST-SIC               201      8  A
CPEG-NAICS                  209      6  A
CPEG-TAX-ID                 215     11  A
CPEG-TAX-ID-TYPE            226      1  A
CPEG-OWNER-CHANGE           227      1  A
CPEG-NAME-CHANGE            228      1  A
CPEG-ADDR1                  229     50  A
CPEG-ADDL-ADDR              279     50  A
CPEG-CTY                    329     32  A
CPEG-ST-ABBREVIATION        361      2  A
CPEG-PROVINCE               363     25  A   
CPEG-ZIP                    388      9  A
CPEG-COUNTRY                397      3  A
CPEG-CUST-LOC-TYPE          400      2  A
CPEG-CUST-ADDR-TYPE         402      1  A
CPEG-PHONE-CONTRY           403      5  A
CPEG-PHONE-AREA             408      3  A  
CPEG-PHONE-PREFIX           411      3  A
CPEG-PHONE-REST             414      4  A
CPEG-CUST-URL               422     75  A
CPEG-CUST-EMAIL             497     75  A 
CPEG-ADDL-NAME              572    120  A
CPEG-ADDL-NAME-TYPE         692      3  A
CPEG-ADDR2                  695     50  A
CPEG-ADDL-ADDR2             745     50  A
CPEG-ADDL-CITY              795     32  A
CPEG-ADDL-ST                827      2  A
CPEG-ADDL-PROVINCE          829     25  A
CPEG-ADDL-ZIP               854      9  A
CPEG-OPTIONAL-ZIP5          854      5  A 
CPEG-OPTIONAL-ZIP4          859      4  A
CPEG-ADDL-COUNTRY           863      3  A
CPEG-ADDL-LOC-TYPE          866      2  A
CPEG-ADDL-ADDR-TYPE         868      1  A
CPEG-ADDL-PHONE-COUNTRY     869      5  A
CPEG-ADDL-PHONE             874     14  A
CPEG-ADDL-PHONE-AREA        874      3  A  
CPEG-ADDL-PHONE-PREFIX      877      3  A
CPEG-ADDL-PHONE-REST        880      4  A
CPEG-LEGAL-ENTITY-TYPE      888      1  A
CPEG-FRANCHISE-IND          889      1  A
CPEG-ARNUM                  890     40  A
CPEG-DATE-ACQUIRED          930      8  A
CPEG-ACCOUNT-TYPE           938      3  A
CPEG-START-DATE             941      8  A
CPEG-START-MM               941      2  A
CPEG-START-DD               943      2  A
CPEG-START-CC               945      2  A
CPEG-START-YY               947      2  A
CPEG-START-CCYY             945      4  A
CPEG-CLOSE-DATE             949      8  A
CPEG-CLOSE-MM               949      2  A
CPEG-CLOSE-DD               951      2  A
CPEG-CLOSE-CC               953      2  A
CPEG-CLOSE-YY               955      2  A
CPEG-CLOSE-CCYY             953      4  A
CPEG-REASON-CLOSED          957      2  A 
CPEG-DOLS-MM                959      2  A
CPEG-DOLS-YY                961      2  A 
CPEG-DOLS-MM-NUM            959      2  N 0
CPEG-DOLS-YY-NUM            961      2  N 0
CPEG-LAST-ACT-TYPE          967      1  A
CPEG-PAYMENT-TYPE           968      2  A
CPEG-PAY-FREQ               970      1  A
CPEG-TERMS-DURATION         971      4  A
CPEG-TERMS-DUR-1            974      1  A
CPEG-TERMS-DUR-2            973      2  A
CPEG-TERMS-DUR-3            972      3  A
CPEG-TERMS                  975     15  A
CPEG-STATUS-CODE            990      2  A
CPEG-ACTIVITY-FLAG          992      1  A
CPEG-NUM-OWNERS             993      2  A
CPEG-NUM-GUARANTORS         995      2  A
CPEG-GOVT-GUAR              997      3  A
CPEG-PERCENT-GUAR          1000      3  A
CPEG-SECURED               1003      1  A
CPEG-LEASE-CAT             1004      2  A
CPEG-MATURE-DATE           1006      8  A
CPEG-MATURE-MM             1006      2  A
CPEG-MATURE-DD             1008      2  A
CPEG-MATURE-CC             1010      2  A
CPEG-MATURE-YY             1012      2  A
CPEG-MATURE-CCYY           1010      4  A
CPEG-COLLATERAL            1014      2  A
CPEG-CREDIT-LIMIT          1016     11  N
CPEG-RHC-CODE              1027      1  A           
CPEG-RHC                   1028     11  N
CPEG-ORIG-LOAN-AMT         1039     11  N
CPEG-CUR-LOAN-AMT          1050     11  N
CPEG-SCHED-PAY             1061     11  N
CPEG-ACTUAL-PAY            1072     11  N
CPEG-STATEMENT-DATE        1083      8  A
CPEG-STATEMENT-MM          1083      2  A
CPEG-STATEMENT-DD          1085      2  A
CPEG-STATEMENT-CC          1087      2  A
CPEG-STATEMENT-YY          1089      2  A
CPEG-STATEMENT-CCYY        1087      4  A
CPEG-DUE-DATE              1091      8  A
CPEG-DUE-MM                1091      2  A
CPEG-DUE-DD                1093      2  A
CPEG-DUE-CC                1095      2  A
CPEG-DUE-YY                1097      2  A
CPEG-DUE-CCYY              1095      4  A
CPEG-DOLP-DATE             1099      8  A
CPEG-DOLP-MM               1099      2  A
CPEG-DOLP-DD               1101      2  A
CPEG-DOLP-CC               1103      2  A
CPEG-DOLP-YY               1105      2  A
CPEG-DOLP-CCYY             1103      4  A
CPEG-BALLOON-AMT           1107     11  A
CPEG-BALLOON-DATE          1118      8  A
CPEG-BALLOON-MM            1118      2  A
CPEG-BALLOON-DD            1120      2  A
CPEG-BALLOON-CC            1122      2  A
CPEG-BALLOON-YY            1124      2  A
CPEG-BALLOON-CCYY          1122      4  A
CPEG-BAL-CODE              1126      1  A
CPEG-BALANCE               1127     11  N 0
CPEG-BAL-SIGN              1127      1  A
CPEG-CURRENT               1138     11  N 0
CPEG-CUR-SIGN              1138      1  A
CPEG-01-30                 1149     11  N 0
CPEG-01-30-SIGN            1149      1  A  
CPEG-31-60                 1160     11  N 0
CPEG-31-60-SIGN            1160      1  A 
CPEG-61-90                 1171     11  N 0
CPEG-61-90-SIGN            1171      1  A 
CPEG-91-120                1182     11  N 0
CPEG-91-120-SIGN           1182      1  A
CPEG-121-150               1193     11  N 0
CPEG-121-150-SIGN          1193      1  A
CPEG-151-180               1204     11  N 0
CPEG-151-180-SIGN          1204      1  A
CPEG-OVER-180              1215     11  N 0
CPEG-OVER-180-SIGN         1215      1  A
CPEG-TOTAL-PAST-DUE        1226     11  N 0
CPEG-TOTAL-PAST-DUE-SIGN   1226      1  A
CPEG-1ST-DEL-DATE          1237      8  A
CPEG-1ST-DEL-MM            1237      2  A
CPEG-1ST-DEL-DD            1239      2  A
CPEG-1ST-DEL-CC            1241      2  A
CPEG-1ST-DEL-YY            1243      2  A
CPEG-1ST-DEL-CCYY          1241      4  A
CPEG-CHARGE-OFF            1245     11  N 0
CPEG-CHARGE-OFF-SIGN       1245      1  A
CPEG-CHARGE-DATE           1256      8  A
CPEG-CHARGE-MM             1256      2  A
CPEG-CHARGE-DD             1258      2  A
CPEG-CHARGE-CC             1260      2  A
CPEG-CHARGE-YY             1262      2  A
CPEG-CHARGE-CCYY           1260      4  A
CPEG-COLLECTION-FLAG       1264      1  A
CPEG-COLLECT-AMT           1265     11  N 0
CPEG-COLECT-SIGN           1265      1  A
CPEG-PMT-AMT               1276     11  N 0
CPEG-PMT-SIGN              1276      1  A
CPEG-PMT-HIST              1287     24  A
CPEG-COMMENT               1311      3  A
CPEG-COMMENT2              1314      3  A
CPEG-COMMENT3              1317      3  A
CPEG-COMMENT-TEXT          1320     70  A
CPEG-USER-TRACKING         1390     40  A
CPEG-SCORE-FLAG            1430      1  A
*Trailer record  

FILE FILED V SEQUENTIAL CREATE RESET +
SYSNAME 'H:\EZ_Text_Files\802861_Crossfoot_Errors.txt'
ERROR-OUT-REC                  1 350  A
       
FILE STSAUTO V SEQUENTIAL CREATE RESET +
     SYSNAME 'G:\Experian Auto Data\S000.BC.C802861.STSAUTO.txt'
*     SYSNAME 'H:\EZ_Text_Files\S000.BC.C802861.STSAUTO.txt'
AUTO-RECORD                       1   1430  A        

*********************************************************************
**   WORKING STORAGE                                               **
*********************************************************************   

WS-RHC-A-IN                  W  12  A
  RHC-BYTE-IN1B    WS-RHC-A-IN   1 A INDEX SUB1B   

WS-BALANCE-A-IN              W  12  A
  BALANCE-BYTE-IN1B  WS-BALANCE-A-IN 1 A INDEX SUB1B        

WS-CURRENT-A-IN              W  12  A
  CURRENT-BYTE-IN1B  WS-CURRENT-A-IN 1 A INDEX SUB1B

WS-01-30-A-IN                W  12  A
  01-30-BYTE-IN1B    WS-01-30-A-IN   1 A INDEX SUB1B

WS-31-60-A-IN                W  12  A
  31-60-BYTE-IN1B    WS-31-60-A-IN   1 A INDEX SUB1B           

WS-61-90-A-IN                W  12  A
  61-90-BYTE-IN1B    WS-61-90-A-IN   1 A INDEX SUB1B 

WS-OVER-90-A-IN              W  12  A
  OVER-90-BYTE-IN1B  WS-OVER-90-A-IN   1 A INDEX SUB1B 

WS-OVER-120-A-IN             W  12  A
  OVER-120-BYTE-IN1B WS-OVER-120-A-IN   1 A INDEX SUB1B

WS-MM                        W   2  A    
WS-DD                        W   2  A
WS-YY                        W   2  A   
WS-DATE                      W   8  A   
WS-DOLS-FLAG                 W   1  A 
WS-YRS-CUST                  W   3  N 0
WS-Z-REC-COUNT               W   7  N
WS-Z-RHC                     W  10  N 0
WS-Z-BALANCE                 W  10  N 0
WS-Z-CURRENT                 W  10  N 0
WS-Z-01-30                   W  10  N 0
WS-Z-31-60                   W  10  N 0
WS-Z-61-90                   W  10  N 0
WS-Z-OVER-90                 W  10  N 0
                             
WS-PAST01                    W  11  N 0
WS-PAST30                    W  11  N 0
WS-PAST60                    W  11  N 0
WS-PAST90                    W  11  N 0
WS-PAST120                   W  11  N 0
WS-PAST150                   W  11  N 0
WS-PAST180                   W  11  N 0

WS-BALANCE                   W   8  N 0
WS-CDR-BALANCE               W   8  N 0
WS-CDR-CURRENT               W   7  N 0
WS-CDR-01-30                 W   7  N 0
WS-CDR-31-60                 W   7  N 0
WS-CDR-61-90                 W   7  N 0
WS-CDR-OVER-90               W   7  N 0   
WS-CROSSFOOT                 W   7  N 0
WS-CROSS-COUNTER             W   7  N  
WS-TOTAL-RECORDS             W   7  N     
WS-PERCENT                   W   3  N 2

WS-OVER-90                   W   7  N 0
WS-120-SIGN                  W   1  A    

WS-DISPLAY-COUNTER           W   4  N


*********************************************************************
JOB INPUT(FILEA) START(A-REC) FINISH(Z-REC)  
*********************************************************************

*********************************************************************
**  Wrie BIS-format output file                                    **
*********************************************************************
IF NAME = 'NAME' 'Name' 'COMPANY NAME'  ' ' 'Customer Name' + 
   'CUSTOMER NAME' 'Customer Name' 'NAME1' 'Name1' 'NAME2 ' 'Name2' +
    'cust' 'CustomerName' 'CUSTOMERNAME' 'ADDRESS LINE 1'
   GOTO JOB
END-IF
   WS-TOTAL-RECORDS       = WS-TOTAL-RECORDS + 1
   CDR-ARNUM              = AR-NUM   
   CDR-OUT-REC            = ' '   
   CDR-REC-CD             = 'C'
   CDR-CONTRIB#           = '802861' 
   CDR-BUS-CAT            = '6000'
   CDR-ACCT-NAME          = NAME
   CDR-ADDL-NAME          = NAME2
   CDR-ADDR1              = ADDR1
   CDR-ADDL-ADDR          = ADDR2
   CDR-SIC-CODE           = '4424'
   CDR-CITY-ST-CD         = '2'
   CDR-CTY                = CITY 
   CDR-ST                 = STATE   
   CDR-ZIP                = ZIP
   CDR-ST-ABBREVIATION    = STATE  
   CDR-EXTDT              = WS-DATE

*CDR-EXTDT = '063018'
*   CDR-EXTDT-MM           = EXTDT-MM
*   CDR-EXTDT-DD           = EXTDT-DD
*   CDR-EXTDT-YY           = EXTDT-YY   
PERFORM NUMFIX  
   CDR-CUS-SIC-CODE       = '0000'  
   CDR-ARNUM              = AR-NUM   
   CDR-PHONE-AREA         = PHONE-AREA
   CDR-PHONE-PREFIX       = PHONE-PRE
   CDR-PHONE-REST         = PHONE-REST
IF CDR-PHONE = '' '0'
   CDR-PHONE = '0000000000'
END-IF 
   CDR-TERMS              = 'NET 30 '
   CDR-RHC-CODE           = '0'  
   CDR-RHC                = 0   
   CDR-ZERO-FILL          = '0000'
IF ZIP NOT NUMERIC
   CDR-OPTIONAL-ZIP9      = ZIP-9
ELSE
   CDR-OPTIONAL-ZIP5      = ZIP
   CDR-OPTIONAL-ZIP4      = ZIP-4
END-IF   
*IF DOLS-MM NOT NUMERIC
*   DOLS-MM                = 0
*   DOLS-YY                = 0
*END-IF
   CDR-DOLS-MM            = '00'
   CDR-DOLS-YY            = '00' 
   CDR-YRS-CUST           = 0
*IF CDR-YRS-CUST LT 0
*   CDR-YRS-CUST = CDR-YRS-CUST + 100
*END-IF 
   CDR-COMMENT-CD = '00'
*   CDR-COMMENT-CD = COMMENT

*********************************************************************
** Check for crossfoot errors                                      **
********************************************************************* 
   IF CDR-BAL-SIGN        = '1'
      WS-CDR-BALANCE      = CDR-BALANCE * (-1)
   ELSE
      WS-CDR-BALANCE      = CDR-BALANCE
   END-IF  
   IF CDR-CUR-SIGN        = '1'
      WS-CDR-CURRENT      = CDR-CURRENT * (-1)
   ELSE
      WS-CDR-CURRENT      = CDR-CURRENT
   END-IF 
   IF CDR-01-30-SIGN        = '1'
      WS-CDR-01-30        = CDR-01-30 * (-1)
   ELSE
      WS-CDR-01-30        = CDR-01-30
   END-IF 
   IF CDR-31-60-SIGN        = '1'
      WS-CDR-31-60        = CDR-31-60 * (-1)
   ELSE
      WS-CDR-31-60        = CDR-31-60
   END-IF 
   IF CDR-61-90-SIGN        = '1'
      WS-CDR-61-90        = CDR-61-90 * (-1)
   ELSE
      WS-CDR-61-90        = CDR-61-90
   END-IF 
   IF CDR-OVER-90-SIGN        = '1'
      WS-CDR-OVER-90      = CDR-OVER-90 * (-1)
   ELSE
      WS-CDR-OVER-90      = CDR-OVER-90
   END-IF              
   WS-BALANCE = WS-CDR-CURRENT + +
                WS-CDR-01-30 +   +
                WS-CDR-31-60 +   +
                WS-CDR-61-90 +   +
                WS-CDR-OVER-90
   IF WS-BALANCE         LT 0
      WS-BALANCE          = WS-BALANCE * (-1)
   END-IF 
   WS-CROSSFOOT           = CDR-BALANCE - WS-BALANCE
   IF WS-CROSSFOOT       LT 0
      WS-CROSSFOOT        = WS-CROSSFOOT * (-1)
   END-IF  
   IF WS-CROSSFOOT       GT 5 
      ERROR-OUT-REC       = CDR-OUT-REC        
      WS-CROSS-COUNTER    = WS-CROSS-COUNTER + 1  
      PUT FILED 
      ELSE    
      WS-Z-REC-COUNT         = WS-Z-REC-COUNT + 1  
      PUT FILEB     
   END-IF   

*********************************************************************
**  Write CPEG-format output file                                  **
*********************************************************************     
CPEG-OUT-REC              = ' '
CPEG-REC-CD               = 'C '
CPEG-CONTRIB#             = '802861'
CPEG-BUS-CAT              = '6000'
CPEG-EXTDT                = CPEG-A-EXT-DATE
CPEG-EXTDT                = WS-DATE
CPEG-EXTDT-MM               = WS-MM
CPEG-EXTDT-DD               = WS-DD
CPEG-EXTDT-CC               = '20'
CPEG-EXTDT-YY               = WS-YY

*CPEG-EXTDT = '06302018'

*CPEG-EXTDT-MM               = EXTDT-MM
*CPEG-EXTDT-DD               = EXTDT-DD
*CPEG-EXTDT-CC               = '20'
*CPEG-EXTDT-YY               = EXTDT-YY
CPEG-SUB-CODE               = '0000000'
CPEG-EQUIFAX-CONTNUM        = ' '
CPEG-DANDB-CONTNUM          = ' '
CPEG-NAME-DISPLAY           = 'Y'
CPEG-ACCT-NAME              = NAME
CPEG-NAME-TYPE              = 'PN'
CPEG-EXP-BIN                = ' '
CPEG-DUNS                   = ' '
CPEG-EQUIFAX-ID             = ' '
CPEG-CUST-SIC               = ' '
CPEG-NAICS                  = ' '
CPEG-TAX-ID                 = ' '
CPEG-TAX-ID-TYPE            = ' '
CPEG-OWNER-CHANGE           = 'N'
CPEG-NAME-CHANGE            = 'N'
CPEG-ADDR1                  = ADDR1
CPEG-ADDL-ADDR              = ADDR2
CPEG-CTY                    = CITY
CPEG-ST-ABBREVIATION        = CDR-ST-ABBREVIATION
CPEG-PROVINCE               = ' ' 
CPEG-ZIP                    = CDR-OPTIONAL-ZIP9
CPEG-COUNTRY                = ' '
CPEG-CUST-LOC-TYPE          = '99'
CPEG-CUST-ADDR-TYPE         = 'B'
CPEG-PHONE-CONTRY           = ' '
CPEG-PHONE-AREA             = PHONE-AREA
CPEG-PHONE-PREFIX           = PHONE-PRE
CPEG-PHONE-REST             = PHONE-REST
CPEG-CUST-URL               = ' '
CPEG-CUST-EMAIL             = ' '
CPEG-ADDL-NAME              = NAME2
CPEG-ADDL-NAME-TYPE         = 'DBA'
CPEG-ADDR2                  = ADDR1
CPEG-ADDL-ADDR2             = ADDR2
CPEG-ADDL-CITY              = CITY
CPEG-ADDL-ST                = CDR-ST-ABBREVIATION
CPEG-ADDL-PROVINCE          = ' '
CPEG-ADDL-ZIP               = CDR-OPTIONAL-ZIP9
*CPEG-OPTIONAL-ZIP5          = ZIP 
*CPEG-OPTIONAL-ZIP4          = ZIP-4
CPEG-ADDL-COUNTRY           = ' '
CPEG-ADDL-LOC-TYPE          = ' '
CPEG-ADDL-ADDR-TYPE         = '99'
CPEG-ADDL-PHONE-COUNTRY     = '00000'
CPEG-ADDL-PHONE             = ' '
CPEG-ADDL-PHONE-AREA        = '000'  
CPEG-ADDL-PHONE-PREFIX      = '000'
CPEG-ADDL-PHONE-REST        = '0000'
CPEG-LEGAL-ENTITY-TYPE      = '9'
CPEG-FRANCHISE-IND          = ' '
CPEG-ARNUM                  = AR-NUM
CPEG-DATE-ACQUIRED          = ' '
CPEG-ACCOUNT-TYPE           = '150'
CPEG-START-DATE             = ' '
CPEG-START-MM               = ''
CPEG-START-DD               = ''
CPEG-START-CC               = ''
CPEG-START-YY               = ''
*CPEG-START-CCYY             = 0
CPEG-CLOSE-DATE             = ' '
CPEG-CLOSE-MM               = ' '
CPEG-CLOSE-DD               = ' '
CPEG-CLOSE-CC               = ' '
CPEG-CLOSE-YY               = ' '
CPEG-CLOSE-CCYY             = ' '
CPEG-REASON-CLOSED          = ' '
CPEG-DOLS-MM                = ' '
CPEG-DOLS-YY                = ' ' 
*CPEG-DOLS-MM-NUM            = 0
*CPEG-DOLS-YY-NUM            = 0
CPEG-LAST-ACT-TYPE          = 'U'
CPEG-PAYMENT-TYPE           = '01'
CPEG-PAY-FREQ               = 'U'
CPEG-TERMS-DURATION         = 'AR'
*CPEG-TERMS-DUR-1            = '0'
*CPEG-TERMS-DUR-2            = '00'
*CPEG-TERMS-DUR-3            = '000'
CPEG-TERMS                  = CDR-TERMS
CPEG-STATUS-CODE            = ' '
CPEG-ACTIVITY-FLAG          = ' '
CPEG-NUM-OWNERS             = ' '
CPEG-NUM-GUARANTORS         = '00'
CPEG-GOVT-GUAR              = ' '
CPEG-PERCENT-GUAR           = ' '
CPEG-SECURED                = ' '
CPEG-LEASE-CAT              = ' '
CPEG-MATURE-DATE            = ' '
CPEG-MATURE-MM              = ' '
CPEG-MATURE-DD              = ' '
CPEG-MATURE-CC              = ' '
CPEG-MATURE-YY              = ' '
CPEG-MATURE-CCYY            = ' '
CPEG-COLLATERAL             = ' '
CPEG-CREDIT-LIMIT           = 0
CPEG-RHC-CODE               = '1'  
CPEG-RHC                    = CDR-RHC
CPEG-ORIG-LOAN-AMT          = 0
CPEG-CUR-LOAN-AMT           = 0
CPEG-SCHED-PAY              = 0
CPEG-ACTUAL-PAY             = 0
CPEG-STATEMENT-DATE         = ' '
CPEG-STATEMENT-MM           = ' '
CPEG-STATEMENT-DD           = ' '
CPEG-STATEMENT-CC           = ' '
CPEG-STATEMENT-YY           = ' '
CPEG-STATEMENT-CCYY         = ' '
CPEG-DUE-DATE               = ' '
CPEG-DUE-MM                 = ' '
CPEG-DUE-DD                 = ' '
CPEG-DUE-CC                 = ' '
CPEG-DUE-YY                 = ' '
CPEG-DUE-CCYY               = ' '
CPEG-DOLP-DATE              = ' '
CPEG-DOLP-MM                = ' '
CPEG-DOLP-DD                = ' '
CPEG-DOLP-CC                = ' '
CPEG-DOLP-YY                = ' '
CPEG-DOLP-CCYY              = ' '
CPEG-BALLOON-AMT            = ' '
CPEG-BALLOON-DATE           = ' '
CPEG-BALLOON-MM             = ' '
CPEG-BALLOON-DD             = ' '
CPEG-BALLOON-CC             = ' '
CPEG-BALLOON-YY             = ' '
CPEG-BALLOON-CCYY           = ' '
CPEG-BAL-CODE               = '0'
CPEG-BALANCE                = CDR-BALANCE
IF CDR-BAL-SIGN             = '1'
CPEG-BAL-SIGN               = '-'
ELSE
CPEG-BAL-SIGN               = '0'
END-IF
CPEG-CURRENT                = CDR-CURRENT
IF CDR-CUR-SIGN             = '1'
CPEG-CUR-SIGN               = '-'
ELSE    
CPEG-CUR-SIGN               = '0'
END-IF
CPEG-01-30                  = CDR-01-30
IF CDR-01-30-SIGN           = '1'
CPEG-01-30-SIGN             = '-'
ELSE
CPEG-01-30-SIGN             = '0'
END-IF
CPEG-31-60                  = CDR-31-60
IF CDR-31-60-SIGN           = '1'
CPEG-31-60-SIGN             = '-'
ELSE
   CPEG-31-60-SIGN          = '0'
END-IF
CPEG-61-90                  = CDR-61-90
IF CDR-61-90-SIGN             = '1'
   CPEG-61-90-SIGN          = '-'
ELSE
   CPEG-61-90-SIGN          = '0'
END-IF
CPEG-91-120                 = CDR-OVER-90
IF CDR-OVER-90-SIGN          = '1'
   CPEG-91-120-SIGN         = '-'
ELSE
   CPEG-91-120-SIGN         = '0'
END-IF
CPEG-121-150                = 0
CPEG-121-150-SIGN           = '0'
CPEG-151-180                = 0
CPEG-151-180-SIGN           = '0'
CPEG-OVER-180               = 0
CPEG-OVER-180-SIGN          = '0'
WS-PAST01                   = CDR-01-30
WS-PAST30                   = CDR-31-60
WS-PAST60                   = CDR-61-90
WS-PAST90                   = CDR-OVER-90
WS-PAST120                  = 0
WS-PAST150                  = 0
WS-PAST180                  = 0
IF CDR-01-30-SIGN           = '1'
   WS-PAST01                = WS-PAST01 * (-1)
END-IF
IF CDR-31-60-SIGN           = '1'
   WS-PAST30                = WS-PAST30 * (-1)
END-IF
IF CDR-61-90-SIGN           = '1'
   WS-PAST60                = WS-PAST60 * (-1)
END-IF
IF CDR-OVER-90-SIGN         = '1'
    WS-PAST90                = WS-PAST90 * (-1)
END-IF
CPEG-TOTAL-PAST-DUE         = WS-PAST01 + WS-PAST30 + WS-PAST60 + +
     WS-PAST90 + WS-PAST120 + WS-PAST150 + WS-PAST180
IF CPEG-TOTAL-PAST-DUE     LT 0
   CPEG-TOTAL-PAST-DUE      = CPEG-TOTAL-PAST-DUE * (-1)
   CPEG-TOTAL-PAST-DUE-SIGN = '-'
END-IF
CPEG-1ST-DEL-DATE          = ' '
CPEG-1ST-DEL-MM            = ' '
CPEG-1ST-DEL-DD            = ' '
CPEG-1ST-DEL-CC            = ' '
CPEG-1ST-DEL-YY            = ' '
CPEG-1ST-DEL-CCYY          = ' '
CPEG-CHARGE-OFF            = 0
CPEG-CHARGE-OFF-SIGN       = '0'
CPEG-CHARGE-DATE           = ' '
CPEG-CHARGE-MM             = ' '
CPEG-CHARGE-DD             = ' '
CPEG-CHARGE-CC             = ' '
CPEG-CHARGE-YY             = ' '
CPEG-CHARGE-CCYY           = ' '
CPEG-COLLECTION-FLAG       = 'N'
CPEG-COLLECT-AMT           =  0
CPEG-COLECT-SIGN           = '0'
CPEG-PMT-AMT               = 0
CPEG-PMT-SIGN              = '0'
CPEG-PMT-HIST              = ''
PERFORM COMMENT
CPEG-COMMENT2              = ' '
CPEG-COMMENT3              = ' '
CPEG-USER-TRACKING         = ' '
CPEG-SCORE-FLAG            = ' '
PUT FILEC
AUTO-RECORD                = CPEG-RECORD
PUT STSAUTO


*********************************************************************
** NUMFIX right-justifies and zero-fills numeric fields 
*********************************************************************
NUMFIX. PROC  
WS-BALANCE-A-IN = '000000000000'
SUB1         = 11
SUB1B        = 11 
CDR-BAL-SIGN = ' '
DO WHILE SUB1 GE 0
   IF BALANCE-BYTE-IN1 NUMERIC
      BALANCE-BYTE-IN1B = BALANCE-BYTE-IN1
      SUB1  = SUB1 - 1
      SUB1B = SUB1B - 1
   ELSE       
      IF BALANCE-BYTE-IN1 = '-'
         CDR-BAL-SIGN     = '1' 
      END-IF
      SUB1  = SUB1 - 1
   END-IF
END-DO  
MOVE WS-BALANCE-A-IN TO BALANCE     
IF BALANCE-CENTS GE 50
   BALANCE-DOLLARS = BALANCE-DOLLARS + 1
END-IF
CDR-BALANCE     = BALANCE-DOLLARS  
IF CDR-BAL-SIGN = '1'
   WS-Z-BALANCE = WS-Z-BALANCE - CDR-BALANCE
ELSE
   WS-Z-BALANCE = WS-Z-BALANCE + CDR-BALANCE
END-IF
         
WS-CURRENT-A-IN = '000000000000'
SUB1            = 11
SUB1B           = 11
CDR-CUR-SIGN    = ' '
DO WHILE SUB1   GE 0
   IF CURRENT-BYTE-IN1    NUMERIC
      CURRENT-BYTE-IN1B = CURRENT-BYTE-IN1
      SUB1      = SUB1 - 1
      SUB1B     = SUB1B - 1
   ELSE 
      IF CURRENT-BYTE-IN1 = '-'
         CDR-CUR-SIGN     = '1' 
      END-IF
      SUB1      = SUB1 - 1
   END-IF
END-DO
MOVE WS-CURRENT-A-IN TO CURRENT     
IF CURRENT-CENTS   GE 50
   CURRENT-DOLLARS = CURRENT-DOLLARS + 1
END-IF
CDR-CURRENT        = CURRENT-DOLLARS  
IF CDR-CUR-SIGN    = '1'
   WS-Z-CURRENT    = WS-Z-CURRENT - CDR-CURRENT
ELSE
   WS-Z-CURRENT    = WS-Z-CURRENT + CDR-CURRENT
END-IF

WS-01-30-A-IN = '000000000000'
SUB1         = 11
SUB1B        = 11 
CDR-01-30-SIGN = ' '
DO WHILE SUB1 GE 0
   IF 01-30-BYTE-IN1 NUMERIC
      01-30-BYTE-IN1B = 01-30-BYTE-IN1
      SUB1  = SUB1 - 1
      SUB1B = SUB1B - 1
   ELSE 
      IF 01-30-BYTE-IN1 = '-'
         CDR-01-30-SIGN     = '1' 
      END-IF
      SUB1  = SUB1 - 1
   END-IF
END-DO
MOVE WS-01-30-A-IN TO 01-30     
IF 01-30-CENTS   GE 50
   01-30-DOLLARS = 01-30-DOLLARS + 1
END-IF
CDR-01-30        = 01-30-DOLLARS  
IF CDR-01-30-SIGN = '1'
   WS-Z-01-30 = WS-Z-01-30 - CDR-01-30
ELSE
   WS-Z-01-30 = WS-Z-01-30 + CDR-01-30
END-IF       

WS-31-60-A-IN = '000000000000'
SUB1         = 11
SUB1B        = 11 
CDR-31-60-SIGN = ' '
DO WHILE SUB1 GE 0
   IF 31-60-BYTE-IN1 NUMERIC
      31-60-BYTE-IN1B = 31-60-BYTE-IN1
      SUB1  = SUB1 - 1
      SUB1B = SUB1B - 1
   ELSE 
      IF 31-60-BYTE-IN1 = '-'
         CDR-31-60-SIGN     = '1' 
      END-IF
      SUB1  = SUB1 - 1
   END-IF
END-DO
MOVE WS-31-60-A-IN TO 31-60     
IF 31-60-CENTS   GE 50
   31-60-DOLLARS = 31-60-DOLLARS + 1
END-IF
CDR-31-60        = 31-60-DOLLARS   
IF CDR-31-60-SIGN = '1'
   WS-Z-31-60 = WS-Z-31-60 - CDR-31-60
ELSE
   WS-Z-31-60 = WS-Z-31-60 + CDR-31-60
END-IF     

WS-61-90-A-IN = '000000000000'
SUB1         = 11
SUB1B        = 11 
CDR-61-90-SIGN = ' '
DO WHILE SUB1 GE 0
   IF 61-90-BYTE-IN1 NUMERIC
      61-90-BYTE-IN1B = 61-90-BYTE-IN1
      SUB1  = SUB1 - 1
      SUB1B = SUB1B - 1
   ELSE 
      IF 61-90-BYTE-IN1 = '-'
         CDR-61-90-SIGN     = '1' 
      END-IF
      SUB1  = SUB1 - 1
   END-IF
END-DO
MOVE WS-61-90-A-IN TO 61-90     
IF 61-90-CENTS   GE 50
   61-90-DOLLARS = 61-90-DOLLARS + 1
END-IF
CDR-61-90        = 61-90-DOLLARS     
IF CDR-61-90-SIGN = '1'
   WS-Z-61-90 = WS-Z-61-90 - CDR-61-90
ELSE
   WS-Z-61-90 = WS-Z-61-90 + CDR-61-90
END-IF    

WS-OVER-90-A-IN = '000000000000'
SUB1         = 11
SUB1B        = 11 
CDR-OVER-90-SIGN = ' '
DO WHILE SUB1 GE 0
   IF OVER-90-BYTE-IN1 NUMERIC
      OVER-90-BYTE-IN1B = OVER-90-BYTE-IN1
      SUB1  = SUB1 - 1
      SUB1B = SUB1B - 1
   ELSE     
      IF OVER-90-BYTE-IN1 = '-'
         CDR-OVER-90-SIGN     = '1' 
      END-IF
      SUB1  = SUB1 - 1
   END-IF
END-DO
MOVE WS-OVER-90-A-IN TO OVER-90-NUM     
IF OVER-90-CENTS  GE 50
   IF OVER-90-NUM GE 0
      OVER-90-NUM  = OVER-90-NUM + 100
   ELSE
      OVER-90-NUM  = OVER-90-NUM - 100
   END-IF
END-IF
IF OVER-90-CENTS  LT 50
   IF OVER-90-NUM LT 0
      OVER-90-NUM  = OVER-90-NUM - 100
   END-IF
END-IF  
OVER-90-NUM     = OVER-90-NUM / 100
WS-OVER-90      = OVER-90-NUM
IF CDR-OVER-90-SIGN = '1'
   WS-OVER-90   = WS-OVER-90 * (-1)  
END-IF
*CDR-OVER-90     = OVER-90-NUM

WS-OVER-120-A-IN = '000000000000'

IF AR-NUM = '104993'
DISPLAY AR-NUM OVER-120 WS-OVER-120-A-IN
END-IF

SUB1         = 11
SUB1B        = 11 
WS-120-SIGN = ' '
DO WHILE SUB1 GE 0
   IF OVER-120-BYTE-IN1 NUMERIC
      OVER-120-BYTE-IN1B = OVER-120-BYTE-IN1
      SUB1  = SUB1 - 1
      SUB1B = SUB1B - 1
   ELSE     
      IF OVER-120-BYTE-IN1 = '-'
         WS-120-SIGN     = '1'
      END-IF
      SUB1  = SUB1 - 1
   END-IF
END-DO
MOVE WS-OVER-120-A-IN TO OVER-120-NUM

IF AR-NUM = '104993'
DISPLAY AR-NUM OVER-120-NUM
END-IF  
   
IF OVER-120-CENTS  GE 50
   IF OVER-120-NUM GE 0
      OVER-120-NUM  = OVER-120-NUM + 100
   ELSE
      OVER-120-NUM  = OVER-120-NUM - 100
   END-IF

IF AR-NUM = '104993'
DISPLAY AR-NUM OVER-120-NUM OVER-120-CENTS
END-IF
  
END-IF
IF OVER-120-CENTS  LE 50
   IF OVER-120-NUM LT 0
      OVER-120-NUM  = OVER-120-NUM - 100
   END-IF
END-IF    
OVER-120-NUM     = OVER-120-NUM / 100
IF WS-120-SIGN   = '1'
   WS-OVER-90       = WS-OVER-90 - OVER-120-NUM
ELSE
   WS-OVER-90       = WS-OVER-90 + OVER-120-NUM
END-IF  
OVER-90 = WS-OVER-90
IF WS-OVER-90 LT 0
   CDR-OVER-90-SIGN = '1'
ELSE
   CDR-OVER-90-SIGN = ' '
END-IF
CDR-OVER-90     = OVER-90-NUM
END-PROC

*********************************************************************
** COMMENT converts Trade-format comment codes to CPEG format
*********************************************************************
COMMENT. PROC
IF CDR-COMMENT-CD          = '97'
   CPEG-COMMENT            = '354'
   CPEG-COMMENT-TEXT       = 'BANKRUPTCY'
ELSE
IF CDR-COMMENT-CD          = '88'
   CPEG-COMMENT            = '353'
   CPEG-COMMENT-TEXT       = 'LEGAL INVOLVEMENT'
ELSE
IF CDR-COMMENT-CD          = '82'
   CPEG-COMMENT            = '355'
   CPEG-COMMENT-TEXT       = 'FORECLOSURE'
ELSE
IF CDR-COMMENT-CD          = '65'
   CPEG-COMMENT            = '150'
   CPEG-COMMENT-TEXT       = 'PAID COLLECTION'
ELSE
IF CDR-COMMENT-CD          = '76'
   CPEG-COMMENT            = '170'
   CPEG-COMMENT-TEXT       = 'COLLECTION'
ELSE
IF CDR-COMMENT-CD          = '83'
   CPEG-COMMENT            = '151'
   CPEG-COMMENT-TEXT       = 'UNPAID COLLECTION'
ELSE
IF CDR-COMMENT-CD          = '80'
   CPEG-COMMENT            = '163'
   CPEG-COMMENT-TEXT       = 'WRITE-OFF'
ELSE
IF CDR-COMMENT-CD          = '84'
   CPEG-COMMENT            = '500'
   CPEG-COMMENT-TEXT       = 'SKIP ACCOUNT - CANNOT LOCATE'
ELSE
IF CDR-COMMENT-CD          = '87'
   CPEG-COMMENT            = '311'
   CPEG-COMMENT-TEXT       = 'SERVICES DISCONNECTED'
ELSE
IF CDR-COMMENT-CD          = '89'
   CPEG-COMMENT            = '312'
   CPEG-COMMENT-TEXT       = 'SERVICES SUSPENDED'
ELSE
IF CDR-COMMENT-CD          = '62'
   CPEG-COMMENT            = '473'
   CPEG-COMMENT-TEXT       = 'NSF'
ELSE
IF CDR-COMMENT-CD          = '43'
   CPEG-COMMENT            = '474'
   CPEG-COMMENT-TEXT       = 'RETURNED CHECKS'
ELSE
IF CDR-COMMENT-CD          = '74'
   CPEG-COMMENT            = '352'
   CPEG-COMMENT-TEXT       = 'LIENS'
ELSE
IF CDR-COMMENT-CD          = '75'
   CPEG-COMMENT            = '534'
   CPEG-COMMENT-TEXT       = 'REFUSED FURTHER CREDIT'
ELSE
IF CDR-COMMENT-CD          = '73'
   CPEG-COMMENT            = '169'
   CPEG-COMMENT-TEXT       = 'ADJUSTMENT BUREAU'
ELSE
IF CDR-COMMENT-CD          = '59' '61'
   CPEG-COMMENT            = '531'
   CPEG-COMMENT-TEXT   = 'CREDIT PRIVLEDGES WITHDRAWN - SELL ONLY COD'
ELSE
IF CDR-COMMENT-CD          = '79'
   CPEG-COMMENT            = '533'
   CPEG-COMMENT-TEXT       = 'CREDIT WITHDRAWN'
ELSE
IF CDR-COMMENT-CD          = '53'
   CPEG-COMMENT            = '468'
   CPEG-COMMENT-TEXT       = '90 DAYS SLOW'
ELSE
IF CDR-COMMENT-CD          = '54'
   CPEG-COMMENT            = '467'
   CPEG-COMMENT-TEXT       = '60 DAYS SLOW'
ELSE
IF CDR-COMMENT-CD          = '55'
   CPEG-COMMENT            = '466'
   CPEG-COMMENT-TEXT       = '30 DAYS SLOW'
ELSE
IF CDR-COMMENT-CD          = '57'
   CPEG-COMMENT            = '465'
   CPEG-COMMENT-TEXT       = '15 DAYS SLOW'
ELSE
IF CDR-COMMENT-CD          = '21'
   CPEG-COMMENT            = '469'
   CPEG-COMMENT-TEXT       = '7 DAYS LATE'
ELSE
IF CDR-COMMENT-CD          = '22'
   CPEG-COMMENT            = '470'
   CPEG-COMMENT-TEXT       = '14 DAYS LATE'
ELSE
IF CDR-COMMENT-CD          = '23'
   CPEG-COMMENT            = '471'
   CPEG-COMMENT-TEXT       = '21 DAYS LATE'
ELSE
IF CDR-COMMENT-CD          = '56'
   CPEG-COMMENT            = '458'
   CPEG-COMMENT-TEXT       = 'PAYS SLOWLY'
ELSE
IF CDR-COMMENT-CD          = '35'
   CPEG-COMMENT            = '461'
   CPEG-COMMENT-TEXT       = 'PAYING DELINQUENT'
ELSE
IF CDR-COMMENT-CD          = '70'
   CPEG-COMMENT            = '536'
   CPEG-COMMENT-TEXT       = 'CASH IN ADVANCE - REQUESTED'
ELSE
IF CDR-COMMENT-CD          = '68'
   CPEG-COMMENT            = '535'
   CPEG-COMMENT-TEXT       = 'CASH IN ADVANCE'
ELSE
IF CDR-COMMENT-CD          = '51'
   CPEG-COMMENT            = '532'
   CPEG-COMMENT-TEXT       = 'DEPOSIT REQUIRED'
ELSE
IF CDR-COMMENT-CD          = '69'
   CPEG-COMMENT            = '152'
   CPEG-COMMENT-TEXT       = 'COLLECTION RELEASE'
ELSE
IF CDR-COMMENT-CD          = '64'
   CPEG-COMMENT            = '528'
   CPEG-COMMENT-TEXT       = 'CASH ON DELIVERY'
ELSE
IF CDR-COMMENT-CD          = '41'
   CPEG-COMMENT            = '159'
   CPEG-COMMENT-TEXT       = 'LEASE DEFAULTS'
ELSE
IF CDR-COMMENT-CD          = '91'
   CPEG-COMMENT            = '156'
   CPEG-COMMENT-TEXT       = 'BOND DEFAULT'
ELSE
IF CDR-COMMENT-CD          = '81'
   CPEG-COMMENT            = '165'
   CPEG-COMMENT-TEXT       = 'REDEEMED POSSESSION'
ELSE
IF CDR-COMMENT-CD          = '78'
   CPEG-COMMENT            = '164'
   CPEG-COMMENT-TEXT       = 'REPOSSESSION'
ELSE
IF CDR-COMMENT-CD          = '60'
   CPEG-COMMENT            = '472'
   CPEG-COMMENT-TEXT       = 'ADVERSE TREND'
ELSE
IF CDR-COMMENT-CD          = '40'
   CPEG-COMMENT            = '401'
   CPEG-COMMENT-TEXT       = 'HOLDING ORDERS'
ELSE
IF CDR-COMMENT-CD          = '72'
   CPEG-COMMENT            = '314'
   CPEG-COMMENT-TEXT       = 'SECURED ACCOUNT'
ELSE
IF CDR-COMMENT-CD          = '71'
   CPEG-COMMENT            = '460'
   CPEG-COMMENT-TEXT       = 'NOT PAYING AS AGREED'
ELSE
IF CDR-COMMENT-CD          = '77'
   CPEG-COMMENT            = '454'
   CPEG-COMMENT-TEXT       = 'IMPROVING'
ELSE
IF CDR-COMMENT-CD          = '67'
   CPEG-COMMENT            = '464'
   CPEG-COMMENT-TEXT       = 'WAS A PROBLEM'
ELSE
IF CDR-COMMENT-CD          = '30'
   CPEG-COMMENT            = '455'
   CPEG-COMMENT-TEXT       = 'REFUSE FINANCE CHARGE'
ELSE
IF CDR-COMMENT-CD          = '28'
   CPEG-COMMENT            = '200'
   CPEG-COMMENT-TEXT       = 'UNEARNED DISCOUNT'
ELSE
IF CDR-COMMENT-CD          = '52'
   CPEG-COMMENT            = '475'
   CPEG-COMMENT-TEXT       = 'UNAUTHORIZED DEDUCTION'
ELSE
IF CDR-COMMENT-CD          = '63'
   CPEG-COMMENT            = '313'
   CPEG-COMMENT-TEXT       = 'REFINANCED LOAN'
ELSE
IF CDR-COMMENT-CD          = '29'
   CPEG-COMMENT            = '317'
   CPEG-COMMENT-TEXT       = 'ACCOUNT CLOSED'
ELSE
IF CDR-COMMENT-CD          = '66'
   CPEG-COMMENT            = '463'
   CPEG-COMMENT-TEXT       = 'WAS PAST DUE'
ELSE
IF CDR-COMMENT-CD          = '20'
   CPEG-COMMENT            = '202'
   CPEG-COMMENT-TEXT       = 'EXCESSIVE DISCOUNT'
ELSE
IF CDR-COMMENT-CD          = '32'
   CPEG-COMMENT            = '225'
   CPEG-COMMENT-TEXT       = 'DISPUTED OR CONTESTED ACCOUNT OR INVOICE'
ELSE
IF CDR-COMMENT-CD          = '46'
   CPEG-COMMENT            = '   '
   CPEG-COMMENT-TEXT       = 'CONSOLIDATION NOTE'
ELSE
IF CDR-COMMENT-CD          = '44'
   CPEG-COMMENT            = '452'
   CPEG-COMMENT-TEXT       = 'PAYS BY NOTE'
ELSE
IF CDR-COMMENT-CD          = '42'
   CPEG-COMMENT            = '402'
   CPEG-COMMENT-TEXT       = 'RETURNED MERCHANDISE'
ELSE
IF CDR-COMMENT-CD          = '58'
   CPEG-COMMENT            = '426'
   CPEG-COMMENT-TEXT       = 'RECENT OWNER CHANGE'
ELSE
IF CDR-COMMENT-CD          = '24'
   CPEG-COMMENT            = '100'
   CPEG-COMMENT-TEXT       = 'FIRST SALE'
ELSE
IF CDR-COMMENT-CD          = '07'
   CPEG-COMMENT            = '310'
   CPEG-COMMENT-TEXT       = 'LIMITED EXPERIENCE'
ELSE
IF CDR-COMMENT-CD          = '47'
   CPEG-COMMENT            = '530'
   CPEG-COMMENT-TEXT  = 'SELLING COD - ADDITIONAL GOES TO AMOUNT OWING'
ELSE
IF CDR-COMMENT-CD          = '45'
   CPEG-COMMENT            = '529'
   CPEG-COMMENT-TEXT       = 'COD CUSTOMER REQUEST'
ELSE
IF CDR-COMMENT-CD          = '18'
   CPEG-COMMENT            = '537'
   CPEG-COMMENT-TEXT       = 'FLOOR PLAN ACCOUNT'
ELSE
IF CDR-COMMENT-CD          = '19'
   CPEG-COMMENT            = '405'
   CPEG-COMMENT-TEXT       = 'JOB COMPLETE'
ELSE
IF CDR-COMMENT-CD          = '50'
   CPEG-COMMENT            = '403'
   CPEG-COMMENT-TEXT       = 'PRODUCT COMPLAINT'
ELSE
IF CDR-COMMENT-CD          = '17'
   CPEG-COMMENT            = '527'
   CPEG-COMMENT-TEXT       = 'SPECIAL TERMS'
ELSE
IF CDR-COMMENT-CD          = '08'
   CPEG-COMMENT            = '201'
   CPEG-COMMENT-TEXT       = 'EARNED DISCOUNT'
ELSE
IF CDR-COMMENT-CD          = '13'
   CPEG-COMMENT            = '203'
   CPEG-COMMENT-TEXT       = 'GIVES DISCOUNT'
ELSE
IF CDR-COMMENT-CD          = '36'
   CPEG-COMMENT            = '400'
   CPEG-COMMENT-TEXT       = 'UNFILLED ORDERS'
ELSE
IF CDR-COMMENT-CD          = '31'
   CPEG-COMMENT            = '538'
   CPEG-COMMENT-TEXT       = 'CREDIT MEMO PENDING'
ELSE
IF CDR-COMMENT-CD          = '14'
   CPEG-COMMENT            = '526'
   CPEG-COMMENT-TEXT       = 'INSTALLMENT ACCOUNT'
ELSE
IF CDR-COMMENT-CD          = '15'
   CPEG-COMMENT            = '301'
   CPEG-COMMENT-TEXT       = 'MULTIPLE LOCATIONS'
ELSE
IF CDR-COMMENT-CD          = '10'
   CPEG-COMMENT            = '525'
   CPEG-COMMENT-TEXT       = 'SELL ON CONSIGNMENT'
ELSE
IF CDR-COMMENT-CD          = '48'
   CPEG-COMMENT            = '404'
   CPEG-COMMENT-TEXT       = 'TRADE ACCEPTED'
ELSE
IF CDR-COMMENT-CD          = '11'
   CPEG-COMMENT            = '300'
   CPEG-COMMENT-TEXT       = 'SEASONAL ACCOUNT'
ELSE
IF CDR-COMMENT-CD          = '06'
   CPEG-COMMENT            = '309'
   CPEG-COMMENT-TEXT       = 'RETENTION'
ELSE
IF CDR-COMMENT-CD          = '09'
   CPEG-COMMENT            = '451'
   CPEG-COMMENT-TEXT       = 'BONDING SATISFACTORY'
ELSE
IF CDR-COMMENT-CD          = '16'
   CPEG-COMMENT            = '453'
   CPEG-COMMENT-TEXT       = 'SATISFACTORY'
ELSE
IF CDR-COMMENT-CD          = '12'
   CPEG-COMMENT            = '457'
   CPEG-COMMENT-TEXT       = 'PAYS PROMPT'
ELSE
IF CDR-COMMENT-CD          = '25'
   CPEG-COMMENT            = '450'
   CPEG-COMMENT-TEXT       = 'EXCELLENT ACCOUNT'
ELSE
IF CDR-COMMENT-CD          = '01'
   CPEG-COMMENT            = '102'
   CPEG-COMMENT-TEXT       = 'CUSTOMER LESS THAN ONE YEAR'
ELSE
IF CDR-COMMENT-CD          = '05'
   CPEG-COMMENT            = '101'
   CPEG-COMMENT-TEXT       = 'NEW ACCOUNT'
ELSE
IF CDR-COMMENT-CD          = '02'
   CPEG-COMMENT            = '103'
   CPEG-COMMENT-TEXT       = 'CUSTOMER 1-5 YEARS'
ELSE
IF CDR-COMMENT-CD          = '03'
   CPEG-COMMENT            = '104'
   CPEG-COMMENT-TEXT       = 'CUSTOMER 5-10 YEARS'
ELSE
IF CDR-COMMENT-CD          = '04'
   CPEG-COMMENT            = '105'
   CPEG-COMMENT-TEXT       = 'CUSTOMER GREATER THAN 10 YEARS'
ELSE
IF CDR-COMMENT-CD          = '00' '  '
   CPEG-COMMENT            = '   '
   CPEG-COMMENT-TEXT       = 'NO COMMENT'
ELSE
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF

END-PROC 
      
*********************************************************************
** A_REC creates the A-record
*********************************************************************
A-REC. PROC    
A-REC         = ' ' 
A-REC-CODE    = 'A'           
A-CONTUM      = '802861'
A-VERSION     = 'C75001' 
A-TEMP-DATE   = SYSDATE 
A-MM          = A-TEMP-MM
A-DD          = A-TEMP-DD
A-YY          = A-TEMP-YY
WS-MM         = A-TEMP-MM
WS-DD         = A-TEMP-DD
WS-YY         = A-TEMP-YY  
A-TEMP-DATE   = ' '
WS-DATE       = A-DATE  
A-DESCRIPTION = 'EXPERIAN CONTRIBUTOR FILE'  
PUT FILEB
WS-YRS-CUST   = A-TEMP-YY-N
DISPLAY WS-YRS-CUST

CPEG-A-REC                = ' '
CPEG-A-REC-CODE           = 'A '   
CPEG-A-VERSION            = 'CPEG1.00'
CPEG-A-CONTUM             = '802861'
CPEG-A-EQUIFAX            = ' '
CPEG-A-DANDB              = ' '
CPEG-A-CONT-NAME          = '[company name] LTD'
*CPEG-A-CREATE-DATE        = 
CPEG-A-CREATE-MM          = A-MM     
CPEG-A-CREATE-DD          = A-DD
CPEG-A-CREATE-CC          = '20'
CPEG-A-CREATE-YY          = A-YY
*CPEG-A-EXT-DATE           = 
CPEG-A-EXT-MM             = WS-MM
CPEG-A-EXT-DD             = WS-DD
CPEG-A-EXT-CC             = '20'
CPEG-A-EXT-YY             = WS-YY
*CPEG-A-TEMP-DATE          = 
CPEG-A-TEMP-MM            = WS-MM
CPEG-A-TEMP-DD            = WS-DD
CPEG-A-TEMP-YY            = WS-YY
PUT FILEC   
AUTO-RECORD                = CPEG-RECORD
PUT STSAUTO

END-PROC
  
*********************************************************************
** Z_REC creates the Z-record
*********************************************************************           
Z-REC. PROC
Z-REC         = ' '
Z-REC-CODE    = 'Z'
Z-REC-COUNT   = WS-Z-REC-COUNT     
Z-RHC         = WS-Z-RHC
Z-BALANCE     = WS-Z-BALANCE
Z-CURRENT     = WS-Z-CURRENT
Z-01-30       = WS-Z-01-30
Z-31-60       = WS-Z-31-60
Z-61-90       = WS-Z-61-90
Z-OVER-90     = WS-Z-OVER-90     
PUT FILEB
WS-PERCENT    = (WS-CROSS-COUNTER / WS-TOTAL-RECORDS) * 100
DISPLAY 'Total Records:    ' WS-TOTAL-RECORDS
DISPLAY 'Records written:  ' WS-Z-REC-COUNT
DISPLAY 'Crossfoot Errors: ' WS-CROSS-COUNTER ' = ' +
        WS-PERCENT '% of file'       
DISPLAY 'Done!'
END-PROC


The first part defines the input and output fields, and working storage. The second part reformats the data and calculates account balances from the aging amounts, and checks to make sure the calculated balances match the given balances. The NUMFIX subroutine converts alphanumeric amounts (e.g., ’ 1234.56’) to numeric (e.g., ‘0000000000’), which is written in whole dollars. This program doesn’t have it, but some of my programs have a subroutine to convert lowercase to uppercase.

No personal experience with Easytrieve, but, if I have understood you correctly, those are exactly the type of jobs Perl was designed to script together easily (certainly processing/wrangling formatted text files and generating reports fall into that category). Python I always thought of as more of a general-purpose programming language, but you can certainly accomplish the same tasks and I don’t think there would be a great difference in speed, assuming proper programming.

Either way, both tools are free. If you are already handy with Python, it may not be worth the extra trouble learning to use an extra tool like Perl (or COBOL, SNOBOL, whatever).

I don’t know Python, and it’s been 20 years since I took a class in COBOL. I know Easytrieve.

Hm. How big are these files, anyway? Unless they are ridiculously huge you shouldn’t have a problem using plain Perl (or Python/whatever).

Could be tens of records, could be tens of thousands of records. My largest file is around 91,000 records. Since output is required to be in uppercase and Excel won’t do a global conversion, some programs have the case conversion subroutine in them where the entire record is parsed. That’s the thing that takes the most time.

ETA: About having separate sort, matching, and reformatting programs. I know I could put them all into a single program, but I like breaking them up so that I can have more control. In the event that I need to reprocess, I can skip steps.

.

I don’t know much about Easytrieve, but I think neither Perl nor Python resembles it, so if you need to adapt an existing script you will need to port/rewrite it to the new language, unless someone has made an automatic converter.

91000 records is nothing; also converting to uppercase should be no bottleneck (e.g. in Perl you can use the ‘uc’ command when you are writing your output). The trick is to minimize the number of string operations; uppercasing a big string or record in one command might be 1000x faster than manually looping over every single character and changing its case.

There are a lot of online resources to aid in learning Python such as:

O’Reilly also has a large series of products for learning Python, for doing everything from web programming and enterprise project development to data analysis and scientific programming.

However, unless you really want to learn Python, I’d have to agree with DPRK that Perl is actually better suited to what you are looking to do here. Python is a general purpose code, and while it is often described as a “scripting language” it has evolved to do damn near anything other than embedded systems. The basic mechanics are pretty simple and consistent, but it has a lot more functionality and very philosophically precise data types than you really need for what you are doing here which can add to the learning curve. Perl is ugly in the way that Unix shell scripting is ugly (unsurprising since Perl is basically a superset of sed and awk which was grown to be a more general purpose scripting language) but for doing expression matching and text processing it is nonpareil, and you can make it to basically create commands to be called for each of these “sort, matching, and reformatting” steps.

Much of what you want done can really be done using regular expressions (“regexs”) where doing things like complex pattern matching and converting from mixed case to all upper case is almost trivial once you understand the basics, and Perl has the best regex capability. Python has the re module as part of the standard library and it is pretty good, but with Perl regex processing is built into the core language so it is super easy to integrate regular expressions into other manipulations so you don’t have to call separate functions or have a bunch of subroutines doing things like searching for patterns. I haven’t followed everything you are doing here but I’m guessing you could probably write Perl scripts of less than a hundred lines to do what you are doing here. All about Perl.

Either way, handling tens of thousands of records should not be a problem for either Perl or Python. Both of these languages are routinely used to handle vastly more data than that. And both Perl and Python have modules for reading directly from .xls files, as well as reading comma-separated and variable format text files, allowing you to dump any step involving Excel entirely.

Stranger

Is the old hard drive a total loss or can you slave it to the new computer and read data off of it? It looks like the license is stored in a file called ca.olf that you then import into the program.

Instructions.

There are people out there who will look at your data and your requirements and quickly say “One way to do it is this: [insert fairly short and very reasonable explanation here].”

I think - maybe? - that you might be better off finding the right person to pay. It depends on how often you’re going to really use what you learn, if you were to learn how yourself - because if you won’t use it that often, you’ll be more likely to need assistance next time as well.

I’d have to rewrite everything. But it shouldn’t be that big of a deal, since most of my stuff is in two or three output formats.

The old HD is toast. I saved CA.olf to my folder specifically so that I would have it in case of disaster. I also have Easytrieve on a flash drive (including the key), but our IT people didn’t attempt to install it from there. It might have everything for installation, but then it might not. Thanks for the link. I’ll forward it.

Stranger: A lot of what you wrote is over my head, but it sounds like Perl would be easier for me to learn. I’ll check out the links later. Thanks.

I write and modify Easytrieves all the time. If I learn another tool to replace it, then I’ll be writing and modifying that all the time.

It says ‘Time to complete: 10 hours.’ Does that mean that it normally takes 10 hours to complete? Or does it mean that you have 10 hours to complete it, and if you don’t you’re SOL?

.

I would bet they’re only guiding you on how much time to allow yourself to get this done.

OK, right off it talks about a ‘Unix shell’. I have no idea what that is, let alone how to use one.

The thing is, I’m old. I learned BASIC around 1980 (and haven’t used it since 1985). Easytrieve is a sequential language; ‘do this, then do this’. I have zero experience with object-oriented languages.

Not sure what’s going on here, so I clidked ‘Run’ in the examples. It said, ‘Your session has been disconnected.’ It didn’t appear to do anything.

I really do better in a classroom environment, with interaction. :frowning:

Sorry, I used a lot of jargon; “regex” are regular expressions, which is just a complex and powerful pattern matching algorithm, kind of like a very narrowly focused scripting language in and of itself which allows you to do multiple manipulations on a segment of text in one action. A search-and-replace command to do something like find all numbers divisible by 5 and replace them with hash marks could be done in a single line. Basically, for the kind of pattern matching and reformatting functions you are looking to perform, Perl is essentially ideal.

It should take 10 hours to get through. The great thing about Perl is that because it is essentially an overgrown scripting language you can write very simple functions of just a few lines to learn how a function works; you don’t have to create an elaborate program with a main() function that calls subroutines and passes arguments, so the threshold to getting to bare minimum competency is pretty low. Given a couple hours a night or one long weekend you should be up to at least minimum competency in Perl quickly. Plus, it is a great general purpose scripting language you can use on macOS to bind together different functions like batch processing of image and video files. All of the time I wasted learning AppleScript, and you can do most of what you need with Perl (or Python or Ruby).

Stranger

So it sounds like I should be looking at Perl instead of Python.

All of my work is on my office PC running Windows something-or-other. I think it’s 2007. I use a Mac at home, but not for work – except for connecting on it to my office computer.

I can probably do a couple of hours a night, and definitely weekends. The thing is, I need someplace to start. I looked at the Python links, and I was lost at ‘Unix shell’. That’s why I think I need an actual class, where an instructor says ‘Do this. Now do this.’ I learned Easytrieve in a mainframe environment. I don’t remember how I started the programs (it’s been almost 20 years since I was with that company), but I know I saved the program to an .exe file that contained JCL. The version I’ve been using is PC-based. I double-click on the desktop icon, and it opens up. Then I put the code into a blank window (in reality, I save a program I’ve already written under a different name :wink: ), click the Compile button, and then click the Run button.

So the first thing I need is to have a Perl icon (or whatever) to start the environment I’m going to run the program in. Then I need to learn how to do what I need to do. In a classroom, the instructor would give the students some code and the students would go from there to complete the assignment. Right now, I have no starting point.