IBM Mainframe Forum Index
 
Log In
 
IBM Mainframe Forum Index Mainframe: Search IBM Mainframe Forum: FAQ Register
 

Pack to Unpack conversion for sending files to Windows


IBM Mainframe Forums -> COBOL Programming
Post new topic   Reply to topic
View previous topic :: View next topic  
Author Message
A_programmers

New User


Joined: 24 Mar 2010
Posts: 19
Location: USA

PostPosted: Wed Sep 11, 2019 10:46 pm
Reply with quote

Dear All,

I read multiple forums but could not come to any conclusion.

I have mainframe file (& corresponding copybook layout). This file contains combination packed and binary fields. Before sending (sftp) this file to Windows; I want to convert all packed / binary fields into display format fields.

Any idea what is the best way to do it ?

1. Do we have any converter available which converts input packed copybook layout to output display copybook layout ?

2. Any COBOL Program / Sort which takes input file & copybook and converts to output display format ?
Back to top
View user's profile Send private message
Nic Clouston

Global Moderator


Joined: 10 May 2007
Posts: 2454
Location: Hampshire, UK

PostPosted: Thu Sep 12, 2019 1:13 am
Reply with quote

A reasonably simple sort process will do it. Examples exist.
Back to top
View user's profile Send private message
Rohit Umarjikar

Global Moderator


Joined: 21 Sep 2010
Posts: 3076
Location: NYC,USA

PostPosted: Thu Sep 12, 2019 3:08 am
Reply with quote

If it’s few fields then DFSORT/SYNCSORT can be used to convert them to any EDITed Zoned Decimal format but if it’s so many fields then write a COBOL program to write in readable format.
Back to top
View user's profile Send private message
sergeyken

Senior Member


Joined: 29 Apr 2008
Posts: 2141
Location: USA

PostPosted: Thu Sep 12, 2019 7:09 pm
Reply with quote

Rohit Umarjikar wrote:
If it’s few fields then DFSORT/SYNCSORT can be used to convert them to any EDITed Zoned Decimal format but if it’s so many fields then write a COBOL program to write in readable format.

Yes, this is correct.
Only one problem exists: writing any COBOL program just to convert field formats takes about 50-100 times more efforts (and 100-300 times more lines of code, in total - including compilation and binder steps coding, and debugging) compared to doing the same via SORT control statements.

Using COBOL makes sense only when some other processing is required (or has been already implemented) via COBOL.
Writing a new COBOL code specifically to convert field formats is a good exercise for learning COBOL, but nothing else.
Back to top
View user's profile Send private message
sergeyken

Senior Member


Joined: 29 Apr 2008
Posts: 2141
Location: USA

PostPosted: Thu Sep 12, 2019 7:35 pm
Reply with quote

The only visible problem in using SORT control statements is: its requirement to specify actual field positions within the record. In COBOL, so called COPYBOOKs are used (I hope so?) for this purpose - to refer to any field of the record by its symbolic name.

In order to simplify this process in SORT approach, especially when hundreds of different files need to be converted and transferred, I had to write (already several times in my career) quite simple REXX code, to provide conversion of COBOL copybook(s) to their equivalent SORT symbol table(s). This has simplified the conversion process dramatically.

I had to re-create similar REXX scripts every time I left one company, and joined another one, for not to "violate the signed agreements on company copyright formalities for any created code". This rarely took longer than 30 minutes.

Just recently I had to created one of those scripts again. I can demonstrate it as an example; every version of those codes usually had specific limitations depending on possible variety of used records.
In each particular case it can be enhanced, to handle more specific record variations used by a particular company.
Code:
/* REXX */                                                         
XCOBSYM: /* conversion of COBOL layout to SORT symbol table */ 
         /* limited version; to be enchanced to handle :           
            - OCCURS groups, on multiple levels                     
            - REDEFINE groups                                       
         */                                                         
Arg FromDD ToDD .                                                   
If FromDD = '' Then                                                 
   FromDD = 'COBOLIN'                                               
If ToDD = '' Then                                                   
   ToDD = 'SYMOUT'                                                 
                                                                   
"EXECIO * DISKR" FromDD "(FINIS"                                   
Lines = Queued()                                                   
                                                                   
Parse Source . . REXXNAME .                                         
/*                                                                 
*/                                                                 
LongLine = ''                                                       
StemNum = 0                                                         
StemLine. = ''                                                     
Do x = 1 By 1 To Lines                                             
   Pull . =7 TestLine =73 .                                         
   If Left( TestLine, 1 ) ¬= '*' ,                                 
    & TestLine ¬= ' ' Then Do                                       
      TestLine = Space( TestLine, 1 )                               
      LongLine = LongLine TestLine                                 
      If Right( TestLine, 1 ) = '.' Then Do                         
         LongLine = Left( LongLine, Length(LongLine) - 1 )         
         StemNum = StemNum + 1                                     
         StemLine.StemNum = LongLine                               
         LongLine = ''                                             
      End                                                           
   End                                                             
End x                                                               
StemLine.0 = StemNum                                               
                                                                   
Queue "*======================================================"     
Queue "* Symbolic Names Table for SORT"                             
Queue "* Created by" REXXNAME "on" Date() "at" Time()                   
Queue "* from COBOL layout definition"                                 
Queue "*======================================================"         
                                                                       
Occurs.0 = 0                                                           
RedefLevel = 0                                                         
Do x = 1 By 1 To StemLine.0                                             
   Parse Var StemLine.x FLevel FName FDescr                             
                                                                       
   If Level = '*' ,                                                     
    | Descr = '' Then Do                                               
      Iterate x                                                         
   End                                                                 
   Call ProcessQueue FLevel FName FDescr                               
                                                                       
End x                                                                   
                                                                       
"EXECIO" Queued() "DISKW" ToDD "(FINIS"                                 
                                                                       
Return 0                                                               
/**********************************************************************/
ProcessQueue: procedure expose Occurs. RedefLevel                       
Arg Level C_Name Descr                                                 
                                                                       
If RedefLevel > 0 Then Do                                               
   If Level + 0 > RedefLevel Then Do                                   
      Queue "*" Level C_Name Descr                                     
      Return 0                                                         
   End                                                                 
   Else Do                                                             
      RedefLevel = 0                                                   
/*    Say "continue from:" Level C_Name Descr */                       
   End                                                                 
End                                                                     
                                                                       
If Pos( 'REDEF', Descr ) > 0 Then Do                                   
   RedefLevel = Level + 0                                               
   Queue "*" Level C_Name Descr                                         
End                                                                   
Else Do                                                               
   If Level = '88' Then Do                                           
      Return 0                                                       
   End                                                               
                                                                     
   Parse Var Descr . 'OCCURS' Array_Size .                           
                                                                     
   NewLine = ''                                                       
   Name = Translate( C_Name, '_', '-' )                               
   If Left( Name, 3 ) = 'FD_' Then                                   
      Name = Substr( Name, 4 )                                       
                                                                     
   Parse Var Descr . 'PICTURE' PicValue LeftDescr                     
   If PicValue = '' Then                                             
      Parse Var Descr . 'PIC' PicValue LeftDescr                     
                                                                     
   If PicValue = '' Then Do                                           
      Queue "*" Level Name Descr                                     
      If Array_Size > '' Then Do /* OCCURS only - for the group */   
         Array_Level = Occurs.0 + 1                                   
         Occurs.Array_Level.Prefix = Level                           
         Occurs.Array_Level.Count  = Array_Size                       
         Occurs.0 = Array_Level                                       
         If ¬ Datatype( Array_Size, 'W' ) ,                           
          | Array_Size > 1 Then Do                                   
            Say "*" Name Descr                                       
            Say "* OCCURS clause not supported"                       
            Say "* Program terminated. RC=8"                         
            Exit 8                                                   
         End                                                         
      End                                                             
      Else                       /* just dummy group */               
         Return 0                                                     
   End                                                               
                                                                     
   LongPic = ''                                                       
   Do x = 1 By 1 While PicValue > ''                                 
      Parse Var PicValue PicChar +1 PicValue                         
      If Left( PicValue, 1 ) = '(' Then Do                         
         Parse Var PicValue '(' CharCount ')' PicValue             
         If ¬ Datatype( CharCount, 'W' ) Then Do                   
            Say "*" Name Descr                                     
            Say "* bad size count:" PicChar"("CharCount")"PicValue 
            Say "* Program terminated. RC=12"                       
            Exit 12                                                 
         End                                                       
         PicChar = Copies( PicChar, CharCount )                     
      End                                                           
      LongPic = LongPic || PicChar                                 
   End x                                                           
                                                                   
   S_Count = 0                                                     
   D_Count = 0                                                     
   V_Count = 0                                                     
   X_Count = 0                                                     
   O_Count = 0                                                     
                                                                   
   Do i = 1 By 1 While LongPic > ''                                 
      Parse Var LongPic Cx +1 LongPic                               
      Select                                                       
      When Cx = 'S' Then S_Count = S_Count + 1                     
      When Cx = '9' Then D_Count = D_Count + 1                     
      When Cx = 'V' Then V_Count = V_Count + 1                     
      When Cx = 'X' Then X_Count = X_Count + 1                     
      Otherwise          O_Count = O_Count + 1                     
      End /* Select */                                             
   End i                                                           
                                                                   
   Select                                                           
                                                                   
   When Pos( 'COMP-3', LeftDescr ) > 0 ,                           
      | Pos( 'COMPUTATIONAL-3', LeftDescr ) > 0 Then Do             
      Size = (D_Count + 2) % 2                                     
      Type = "PD"                                                   
   End                                                             
                                                                   
   When Pos( 'COMP-1', LeftDescr ) > 0 ,                           
      | Pos( 'COMPUTATIONAL-1', LeftDescr ) > 0 ,                       
      | Pos( 'COMP', LeftDescr ) > 0 ,                                 
      | Pos( 'COMPUTATIONAL', LeftDescr ) > 0 Then Do                   
      Size = 2 + 2 * (D_Count >= 5) + 4 * (D_Count >= 10)               
      Type = "BI"                                                       
   End                                                                 
                                                                       
   When X_Count = 0 Then Do /* PIC S99999V99 */                         
      Size = D_Count + O_Count                                         
      Type = "CH"                                                       
   End                                                                 
                                                                       
   Otherwise               /* some 'X' found -> not zoned decimal */   
      Size = S_Count + D_Count + X_Count + O_Count                     
      Type = "CH"                                                       
                                                                       
   End /* Select */                                                     
                                                                       
   If Name = 'FILLER' Then Do                                           
      Queue "*" Level C_Name Descr                                     
      Queue "SKIP,"Size                                                 
   End                                                                 
   Else Do                                                             
      Queue "*" Level C_Name Descr                                     
      Queue Name",*,"Size","Type                                       
   End                                                                 
End                                                                     
                                                                       
Return 0                                                               
/**********************************************************************/
Back to top
View user's profile Send private message
sergeyken

Senior Member


Joined: 29 Apr 2008
Posts: 2141
Location: USA

PostPosted: Thu Sep 12, 2019 9:16 pm
Reply with quote

Some typo in the copied code above, sorry... icon_redface.gif
Not extremely important, but misleading.

Code:
 . . . . . . . . . . . .                                                                         
Occurs.0 = 0                                                           
RedefLevel = 0                                                         
Do x = 1 By 1 To StemLine.0                                             
   Parse Var StemLine.x FLevel FName FDescr                             
                                                                       
   If FLevel = '*' ,                                                     
    | FDescr = '' Then Do                                               
      Iterate x                                                         
   End                                                                 
   Call ProcessQueue FLevel FName FDescr                               
. . . . . . . . . . . . . . . .
Back to top
View user's profile Send private message
A_programmers

New User


Joined: 24 Mar 2010
Posts: 19
Location: USA

PostPosted: Thu Sep 12, 2019 10:45 pm
Reply with quote

Nic Clouston.

Writing SORT step for 70+ files with different layouts is cumbersome. As for every PD / Binary field we need to first calculate location of every field in input and output. Also manual calculation to convert size of field into target format.

I thought this is standard requirement which every one needs; why IBM has not provided any standard utility.

Rohit Umarjikar.

Personally I feel creating output copybook layout with unpacked fields; then moving input fields to output copybook is also the solution. SORT might get complex after we add additional filtering criteria or want to change fields.

sergeyken,

In mainframe if you open copybook using file manager / fileaid; it gives you starting position of every field.

Also; listing of the program should give starting position of every field. (I have not tried this.)

I strongly feel this is where mainframe is lagging. Even for standard requirement there is no library functions available. Where java is growing with lot of reusable libraries.
Back to top
View user's profile Send private message
enrico-sorichetti

Superior Member


Joined: 14 Mar 2007
Posts: 10888
Location: italy

PostPosted: Fri Sep 13, 2019 3:37 am
Reply with quote

Quote:
Even for standard requirement there is no library functions available.


making <binary> fields readable might be a common/standard requirement,

Quote:
why IBM has not provided any standard utility.


You would still have to provide for each field ,

source position, source length, source type
destination position, destination length, destination type

no library function /utility will do the above by itself

providing the above info would be as cumbersome as writing the sort control cards or the cobol file layouts
Back to top
View user's profile Send private message
Rohit Umarjikar

Global Moderator


Joined: 21 Sep 2010
Posts: 3076
Location: NYC,USA

PostPosted: Fri Sep 13, 2019 9:38 am
Reply with quote

Quote:
Personally I feel creating output copybook layout with unpacked fields; then moving input fields to output copybook is also the solution.
That is what I meant by writing a COBOL program which reusable for many datasets with different copybooks. It’s a clean way To maintain and achieve the results. Many years back we had written standard subprograms which will convert the comp and pd values to readable format, you could write that one and call it across many fields.
Back to top
View user's profile Send private message
Phrzby Phil

Senior Member


Joined: 31 Oct 2006
Posts: 1050
Location: Richmond, Virginia

PostPosted: Sun Sep 15, 2019 12:18 am
Reply with quote

I have done this as suggested above with an unpacked version of the copybook (easy to create).

MOVE CORRESPONDING is helpful, except as I remember does not handle OCCURS items.

Another reason to use a program as opposed to a utility is that if (when) there are errors (and when are there not?), tracing back to the source, especially by someone other than the converting person, is more straightforward.
Back to top
View user's profile Send private message
Marso

REXX Moderator


Joined: 13 Mar 2006
Posts: 1353
Location: Israel

PostPosted: Sun Sep 15, 2019 7:53 pm
Reply with quote

A_programmers wrote:
I have mainframe file (& corresponding copybook layout). This file contains combination packed and binary fields. Before sending (sftp) this file to Windows; I want to convert all packed / binary fields into display format fields.
A_programmers wrote:
Writing SORT step for 70+ files with different layouts is cumbersome.


Your question was about ONE file, but when provided with a solution you start talking about 70+ files !
This means you have been wasting our time.
Please don't do that ! sterb050.gif
Back to top
View user's profile Send private message
don.leahy

Active Member


Joined: 06 Jul 2010
Posts: 765
Location: Whitby, ON, Canada

PostPosted: Mon Sep 16, 2019 7:36 pm
Reply with quote

Our shop uses INSYNC, a product from Macro4 to convert files from one format to another. It’s competitors (File aid from Compuware and File Manager from IBM) likely have similar capabilities.

I also have an automated process that converts COBOL copybooks to DFSORT symbols and then generates the BUILD statement to convert the file. I tend to prefer the INSYNC approach now.
Back to top
View user's profile Send private message
sergeyken

Senior Member


Joined: 29 Apr 2008
Posts: 2141
Location: USA

PostPosted: Mon Sep 16, 2019 10:27 pm
Reply with quote

Whenever the SORT symbols table is automatically created from the COBOL copybook, then any conversion of any dataset to printable format (e.g. suitable to FTP to other platforms) becomes just a piece of cake. With new conversion features of nowadays utilities creating a new COBOL program for each dataset conversion is possible, but seems to be a sort of masochism.

In my experience a typical JCL to convert a particular file looks like this
Code:
//CONVERT EXEC CONV2FTP,     standard procedure
//        LAYOUT='&SYSUID..COPYBOOK(INRECORD)',
//        SOURCE='&SYSUID..TESTDATA',
//        OUTPUT='&SYSUID..CONVDATA'
//CONVERT.SYSIN DD  *
 SORT FIELDS=COPY                                                   
*                                                                   
 OUTREC BUILD=(FIELD_PIC20X,                 PIC X(20).             
               FLAG_PIC1X,                   PIC X.                 
               FIELD_9_5,                    PIC 9(5).             
                 ZD,EDIT=(TTTTT),                                   
               FIELD_S9_5,                   PIC S9(5).             
                 ZD,EDIT=(STTTTT),SIGNS=(,-),                       
               FIELD_S9_5V2,                 PIC S9(5)V99.         
                 ZD,EDIT=(STTTTT.TT),SIGNS=(,-),                   
               COMP3_9_4,                    PIC 9(4) COMP-3.       
                 PD,EDIT=(TTTT),                                   
               COMP3_S9_8,                   PIC S9(8) COMP-3.     
                 PD,EDIT=(STTTTTTTT),SIGNS=(,-),                   
               COMP3_S9_8V2,                 PIC S9(8)V99 COMP-3.   
                 PD,EDIT=(STTTTTTTT.TT),SIGNS=(,-),                 
               COMP_9_4,                    PIC 9(4) COMP.         
                 BI,EDIT=(TTTT),                                   
               COMP_S9_8,                   PIC S9(8) COMP.         
                 FI,EDIT=(STTTTTTTT),SIGNS=(,-),                   
               COMP_S9_5V2,                 PIC S9(8)V99 COMP.     
                 FI,EDIT=(STTTTTTTT.TT),SIGNS=(,-),                 
               DATE_YYDDD_PACKED,           PIC 99999 COMP-3.       
                 Y2U,DT=(4MD-),                                     
               DATE_YYMMDD_PACKED,          PIC 999999 COMP-3.     
                 Y2V,DT=(4MD-),                                     
               DATE_YYYYMMDD_PACKED,        PIC 99999999 COMP-3.   
                 Y4V,DT=(4MD-),                                     
               DATE_YYDDD,                  PIC 99999.             
                 Y2T,DT=(4MD-),                                     
               DATE_YYMMDD,                 PIC 999999.             
                 Y2T,DT=(4MD-),                                     
               DATE_YYYYMMDD,               PIC 99999999.           
                 Y4T,DT=(4MD-),                                     
               TIME_HHMM_PACKED,            PIC 9999 COMP-3.       
                 PD,EDIT=(TT.TT),                                   
               TIME_HHMMSS_PACKED,          PIC 999999 COMP-3.     
                 PD,EDIT=(TT.TT.TT),                               
               TIME_HHMM,                   PIC 9999.       
                 ZD,EDIT=(TT.TT),                           
               TIME_HHMMSS,                 PIC 999999.     
                 ZD,EDIT=(TT.TT.TT))                       
*                                                           
 END                                                       
//*

Assuming we have input record copybook INRECORD as follows
Code:
      *                                                             
       01 TEST-COBOL-DATA.                                           
          05 CHARACTER-DATA.                                         
             10 FIELD-PIC20X                  PIC X(20).             
             10 FLAG-PIC1X                    PIC X.                 
      *                                                             
          05 NUMERIC-DATA.                                           
             10 FIELD-9-5                     PIC 9(5).             
             10 FIELD-S9-5                    PIC S9(5).             
             10 FIELD-S9-5V2                  PIC S9(5)V99.         
      *                                                             
          05 DECIMAL-DATA.                                           
             10 COMP3-9-4                     PIC 9(4) COMP-3.       
             10 COMP3-S9-8                    PIC S9(8) COMP-3.     
             10 COMP3-S9-8V2                  PIC S9(8)V99 COMP-3.   
      *                                                             
          05 BINARY-DATA.                                           
             10 COMP-9-4                     PIC 9(4) COMP.         
             10 COMP-S9-8                    PIC S9(8) COMP.         
             10 COMP-S9-5V2                  PIC S9(8)V99 COMP.     
      *                                                             
          05 DATE-DATA.                                             
             10 DATE-YYDDD-PACKED            PIC 99999 COMP-3.       
             10 DATE-YYMMDD-PACKED           PIC 999999 COMP-3.     
             10 DATE-YYYYMMDD-PACKED         PIC 99999999 COMP-3.   
             10 DATE-YYDDD                   PIC 99999.             
             10 DATE-YYMMDD                  PIC 999999.             
             10 DATE-YYYYMMDD                PIC 99999999.           
      *                                                             
          05 TIME-DATA.                                             
             10 TIME-HHMM-PACKED             PIC 9999 COMP-3.       
             10 TIME-HHMMSS-PACKED           PIC 999999 COMP-3.     
             10 TIME-HHMM                    PIC 9999.               
             10 TIME-HHMMSS                  PIC 999999.             
      *   
Back to top
View user's profile Send private message
sergeyken

Senior Member


Joined: 29 Apr 2008
Posts: 2141
Location: USA

PostPosted: Tue Sep 17, 2019 12:05 am
Reply with quote

Exactly in the same manner the output format can be easily changed to, let's say, CSV file:
Code:
//CONVERT EXEC CONV2FTP,     standard procedure
 //        LAYOUT='&SYSUID..COPYBOOK(INRECORD)',
 //        SOURCE='&SYSUID..TESTDATA',
 //        OUTPUT='&SYSUID..CSVDATA'
 //CONVERT.SYSIN DD  *
*                                                                   
 SORT FIELDS=COPY                                                   
*                                                                   
 OUTREC BUILD=(C'"',                                               
               FIELD_PIC20X,                 PIC X(20).             
        C'","',FLAG_PIC1X,                   PIC X.                 
        C'","',FIELD_9_5,                    PIC 9(5).             
                 ZD,EDIT=(IIIIT),                                   
        C'","',FIELD_S9_5,                   PIC S9(5).             
                 ZD,EDIT=(SIIIIT),SIGNS=(,-),                       
        C'","',FIELD_S9_5V2,                 PIC S9(5)V99.         
                 ZD,EDIT=(SIIIII.TT),SIGNS=(,-),                   
        C'","',COMP3_9_4,                    PIC 9(4) COMP-3.       
                 PD,EDIT=(IIIT),                                   
        C'","',COMP3_S9_8,                   PIC S9(8) COMP-3.     
                 PD,EDIT=(SIIIIIIIT),SIGNS=(,-),                   
        C'","',COMP3_S9_8V2,                 PIC S9(8)V99 COMP-3.   
                 PD,EDIT=(SIIIIIIII.TT),SIGNS=(,-),                 
        C'","',COMP_9_4,                    PIC 9(4) COMP.         
                 BI,EDIT=(IIIT),                                   
        C'","',COMP_S9_8,                   PIC S9(8) COMP.         
                 FI,EDIT=(SIIIIIIIT),SIGNS=(,-),                   
        C'","',COMP_S9_5V2,                 PIC S9(8)V99 COMP.     
                 FI,EDIT=(SIIIIIIII.TT),SIGNS=(,-),                 
        C'","',DATE_YYDDD_PACKED,           PIC 99999 COMP-3.       
                 Y2U,DT=(4MD-),                                     
        C'","',DATE_YYMMDD_PACKED,          PIC 999999 COMP-3.     
                 Y2V,DT=(4MD-),                                     
        C'","',DATE_YYYYMMDD_PACKED,        PIC 99999999 COMP-3.   
                 Y4V,DT=(4MD-),                                     
        C'","',DATE_YYDDD,                  PIC 99999.             
                 Y2T,DT=(4MD-),                                     
        C'","',DATE_YYMMDD,                 PIC 999999.             
                 Y2T,DT=(4MD-),                                     
        C'","',DATE_YYYYMMDD,               PIC 99999999.           
                 Y4T,DT=(4MD-),                                     
        C'","',TIME_HHMM_PACKED,            PIC 9999 COMP-3.       
                 PD,EDIT=(TT.TT),                                   
        C'","',TIME_HHMMSS_PACKED,          PIC 999999 COMP-3.     
                 PD,EDIT=(TT.TT.TT),                           
        C'","',TIME_HHMM,                   PIC 9999.         
                 ZD,EDIT=(TT.TT),                             
        C'","',TIME_HHMMSS,                 PIC 999999.       
                 ZD,EDIT=(TT.TT.TT),                           
        C'"')                                                 
*                                                             
 OUTFIL FTOV,                                                 
        BUILD=(1,239,SQZ=(SHIFT=LEFT))                         
*                                                             
 END                                                           
//* 
Back to top
View user's profile Send private message
View previous topic :: :: View next topic  
Post new topic   Reply to topic View Bookmarks
All times are GMT + 6 Hours
Forum Index -> COBOL Programming

 


Similar Topics
Topic Forum Replies
No new posts 3 files concatenated to 1 DFSORT/ICETOOL 2
No new posts JCL sort to compare dates in two file... DFSORT/ICETOOL 2
No new posts GDG generation name to GDG Base name ... DFSORT/ICETOOL 3
No new posts FB to .CSV conversion using sort DFSORT/ICETOOL 7
No new posts small int to zoned decimal conversion DFSORT/ICETOOL 3
Search our Forums:

Back to Top