|
OK everybody. Time for me to toss in 2 cents more.
I've been trying to find the front of this topic, and think that it is from
Frank. Take a close look at his CHECK_56 subroutine, and note that there is
an overlap where A7,A8->(A9 or B0)->B1, B2. So multiple inputs (A9 and B0)
need to get mapped to the same sequential number. Other solutions that have
the 6th position as a multiple of 10 actually generate too many unique
numbers. The following sample solves that. Pardon the wordiness, it's just
stuff I found on the way, and passed on in case anyone else can use it too.
(I'm not sure I understand WHY the original code operates that way, but I
took it as a functional requirement).
Try the code below on for size. It's not as elegant as some other procedures
(Lim Hock-Chai)'s looks really nice, and (Dan Bale)'s approach looked fine
with the niggling exception of that last digit. But I think it produces the
correct result set.
I explain some reasons I picked the structures I did. If you already know
this stuff, just ignore the comments.
* Assign a sequential number to Canadian Postal Code for
* checking if NEXT sequential number is valid.
* Equivalent logic as shown by requester's CHECK_56 routine.
* This does what I THINK it should, but I may have missed something.
* WARNING/Note: CanadaPostalCode(CPC) position 6 uses base(9) {0..8};
*
* Note: THIS IS A SAMPLE ONLY, IT CONTAINING NO ERROR CHECKING!
* (Valid Letter/number/letter/number/letter/numbers are expected)
*
* Actually, I changed from V5 %bif %lookup, doing binary searchs
* on short arrays(12% slower than using simple and CLEARER %scan).
* On a little model 800, it returned about 1,000,000 in 6 seconds).
*
* Clever readers can transform this into a function for ease of use:
* if ( CanCPCSeq(CurrentCPC)= CanCPCSeq(SavedCPC)+1
* or CanCPCSeq(CurrentCPC)= CanCPCSeq(SavedCPC) )
* then ...do stuff...
* else ...do other stuff...
*
* I hope some bright readers will test/verify the program limits,
* and post this as an RPG function, or turn it into an SQL UDF
* so that it could be used like the SQL statement below:
* Select CITY, CANCPC6, CanCPCSeq(CANCPC6) from Custmast
*
* This would be a pretty good example of how to expose/use functions.
*
* If you do repost a better version, be sure to take out
* the *LR on each call, since it would be a performance killer.
*
*
* Background: Canadian Postal Code format
* Valid sets of numbers for canadian postal code (LNL NLN)
* Based on original code requirements:
* (LNL NLn )
* Where (L.L .L. ) has 26 possible values, A=0 thru Z=25
* Where ( N N . ) has 10 possible values, 0=0 thru 9=9
* Where ( n ) has 9 possible values, 0=0 thru 8=8,
* and 9 overlaps, so postal value xxxxx9 gets
* the same sequential number as xxxx10.
*
* Sample results: these sequential numbers are returnred for
* various Canada Postal Codes.
* Call pgm ('A0A0A0') -> sequence( 0)
* Call pgm ('A0A0A1') -> sequence( 1)
* Call pgm ('A0A0A8') -> sequence( 8)
* Call pgm ('A0A0A9') -> sequence( 9) !!! matches CHECK_56
* Call pgm ('A0A0B0') -> sequence( 9) !!! matches CHECK_56
* Call pgm ('A0A0B1') -> sequence( 10)
* Call pgm ('A0A0B8') -> sequence( 17)
* Call pgm ('A0A0B9') -> sequence( 18)
* Call pgm ('A0A0C0') -> sequence( 18)
* Call pgm ('A0A0C1') -> sequence( 19)
* Call pgm ('Z9Z9Z8') -> sequence(15818399)
* Call pgm ('Z9Z9Z9') -> sequence(15818400)
**********************************************************************
D num10 C const('0123456789')
D ltr26 C
const('ABCDEFGHIJKLMNOPQRSTUVWXYZ')
D colval S 9 0 DIM(6)
D rtnCPCseq S like(colval)
C *entry plist
C parm CPC 6
Canadian Postal Code
* (inz column values can be faster)
C eval colval(6)=1
f(000001)= 1
C eval colval(5)=%len(num10)-1*colval(6)
f(000010)= 9
C eval colval(4)=%len(ltr26)*colval(5)
f(000100)= 234
C eval colval(3)=%len(num10)*colval(4)
f(001000)= 2340
C eval colval(2)=%len(ltr26)*colval(3)
f(010000)= 60840
C eval colval(1)=%len(num10)*colval(2)
f(100000)=608400
C eval rtnCPCseq =
C
colval(1)*(%scan(%SUBST(CPC:1:1):ltr26)-1)+
C
colval(2)*(%scan(%SUBST(CPC:2:1):num10)-1)+
C
colval(3)*(%scan(%SUBST(CPC:3:1):ltr26)-1)+
C
colval(4)*(%scan(%SUBST(CPC:4:1):num10)-1)+
C
colval(5)*(%scan(%SUBST(CPC:5:1):ltr26)-1)+
C
colval(6)*(%scan(%SUBST(CPC:6:1):num10)-1)
C rtnCPCseq dsply
C SETON LR
As an Amazon Associate we earn from qualifying purchases.
This mailing list archive is Copyright 1997-2025 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].
Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.