Tony et al.,
I use a calculation method in 3 steps. The method avoids big INTEGER values.
It is valid for Germany, Switzerland and Austria.
$COMMAND
vviban1
*( --------------------------------------------------------
IBAN Berechnung Einzelmitglieder
International Bank Account Number
aufgerufen in mi_vvrba/Daten/IBAN Bearbeiten/Ja
Copyright (c) 1987-2013 Dr. Hartmut Braun, Karlsruhe
Version: 12.3 R:BASE Version 7.6+9.5 32/64
-------------------------------------------------------- )
-- vvnat=nationality, vvlang=language, blz=bank code, kto=account
-- midat=TABLE membership data
IF vvnat <> 'd' AND vvnat <> 'z' AND vvnat <> 'o' THEN
SET VAR vcapt = 'IBAN Calculator'
SET VAR vmess = 'This IBAN Calculation is not available for your
country!'
PAUSE 1 USING .vmess +
CAPTION .vcapt ICON stop +
&vpausopt |THEMENAME &vtheme
GOTO liban1
ENDIF
SET VAR vpnr INTE = 0, vcnt INTE = 0
SET VAR vk2 INTE = 0, vk3 TEXT = NULL, vk31 TEXT = NULL
SET VAR vk4 INTE = 0, vk5 TEXT = NULL
SET VAR vba1 TEXT = NULL, vba2 TEXT = NULL, vba3 TEXT = NULL
SET VAR vm1 INTE = 0, vm2 INTE = 0, vm3 INTE = 0, vm4 INTE = 0
SET VAR vbb1 INTE = 0, vbb2 INTE = 0, vbb3 INTE = 0, vbb4 INTE = 0
SET VAR vpz INTE = 0, vpz1 TEXT = NULL, vbban TEXT = NULL
SET VAR vbban1 TEXT = NULL, vbban2 TEXT = NULL, vbban3 TEXT = NULL
SELECT COUNT(*) INTO vcnt INDICATOR vi1 FROM midat +
WHERE inr = '1' AND blz <> '00000000' AND blz <> '11111111' +
AND iban IS NULL
IF vcnt = 0 THEN
GOTO liban1
ENDIF
SET VAR vmess = 'Moment, ich berechne die fehlenden IBANs!'
IF vvlang <> 'd' THEN
SET VAR vmess = lmsg IN tstlmess +
WHERE svlang = (.vvlang) AND msgnr = 194
ENDIF
PAUSE 3 USING .vmess +
CAPTION .vcapt ICON APP +
&vpaus1opt |THEMENAME &vtheme
SET ERROR MESSAGE 705 OFF
DROP CURSOR ccsh1
SET ERROR MESSAGE 705 ON
-- IBAN Berechnung
DECLARE ccsh1 CURSOR FOR SELECT blz, kto FROM midat +
WHERE inr = '1' AND blz <> '00000000' AND blz <> '11111111' +
AND iban IS NULL
-- DE
IF vvnat = 'd' THEN
OPEN ccsh1
FETCH ccsh1 INTO vblz vi1, vkto vi2
WHILE SQLCODE = 0 THEN
SET VAR vk2 = (10 - (SLEN(.vkto)))
SET VAR vk3 = ((SFIL('0',.vk2)) + .vkto)
SET VAR vk4 = (8 - (SLEN(.vblz)))
SET VAR vk5 = ((SFIL('0',.vk4)) + .vblz)
SET VAR vbban = (.vk5 + .vk3)
SET VAR vbban1 = (SGET(.vbban,9,1))
SET VAR vbban2 = (SGET(.vbban,7,10))
SET VAR vbban3 = ((SGET(.vbban,2,17)) + '13140')
-- D = 13, E = 14
-- 1. 9er Zeile
SET VAR vbb1 = (INT(.vbban1))
SET VAR vm1 = (MOD(.vbb1,97))
SET VAR vba1 = ((CTXT(.vm1)) + .vbban2)
-- 2. 9er Zeile
SET VAR vbb2 = (INT(.vba1))
SET VAR vm2 = (MOD(.vbb2,97))
SET VAR vba2 = ((CTXT(.vm2)) + .vbban3)
-- 3. 9er Zeile
SET VAR vbb3 = (INT(.vba2))
SET VAR vm3 = (MOD(.vbb3,97))
SET VAR vba3 = ((CTXT(.vm3)) + '0')
-- Rest
SET VAR vbb4 = (INT(.vba3))
SET VAR vm4 = (MOD(.vbb4,97))
SET VAR vpz = (98 - .vm4)
IF vpz < 10 THEN
SET VAR vpz1 = ('0' + (CTXT(.vpz)))
ELSE
SET VAR vpz1 = (CTXT(.vpz))
ENDIF
UPDATE midat SET iban = ('DE' + .vpz1 + .vk5 + .vk3) +
WHERE CURRENT OF ccsh1
SET VAR vpnr = (.vpnr + 1)
SET VAR vdial = ((CTXT(.vpnr)) & 'von' & (CTXT(.vcnt)))
PAUSE 4 USING .vdial +
CAPTION 'IBAN' ICON APP +
&vpausopt |THEMENAME &vtheme
FETCH ccsh1 INTO vblz vi1, vkto vi2
ENDWHILE
ENDIF
-- CH
IF vvnat = 'z' THEN
OPEN ccsh1
FETCH ccsh1 INTO vblz vi1, vkto vi2
WHILE SQLCODE = 0 THEN
SET VAR vk2 = (12 - (SLEN(.vkto)))
SET VAR vk3 = ((SFIL('0',.vk2)) + .vkto)
SET VAR vk31 = .vk3
SET VAR vk4 = (5 - (SLEN(.vblz)))
SET VAR vk5 = ((SFIL('0',.vk4)) + .vblz)
-- Ersetzen der Buchstaben
IF vk3 CONTAINS 'A' THEN
SET VAR vk31 = (SRPL(.vk31,'A','10',0))
ENDIF
IF vk3 CONTAINS 'B' THEN
SET VAR vk31 = (SRPL(.vk31,'B','11',0))
ENDIF
IF vk3 CONTAINS 'C' THEN
SET VAR vk31 = (SRPL(.vk31,'C','12',0))
ENDIF
IF vk3 CONTAINS 'D' THEN
SET VAR vk31 = (SRPL(.vk31,'D','13',0))
ENDIF
IF vk3 CONTAINS 'E' THEN
SET VAR vk31 = (SRPL(.vk31,'E','14',0))
ENDIF
IF vk3 CONTAINS 'F' THEN
SET VAR vk31 = (SRPL(.vk31,'F','15',0))
ENDIF
IF vk3 CONTAINS 'G' THEN
SET VAR vk31 = (SRPL(.vk31,'G','16',0))
ENDIF
IF vk3 CONTAINS 'H' THEN
SET VAR vk31 = (SRPL(.vk31,'H','17',0))
ENDIF
IF vk3 CONTAINS 'I' THEN
SET VAR vk31 = (SRPL(.vk31,'I','18',0))
ENDIF
IF vk3 CONTAINS 'J' THEN
SET VAR vk31 = (SRPL(.vk31,'J','19',0))
ENDIF
IF vk3 CONTAINS 'K' THEN
SET VAR vk31 = (SRPL(.vk31,'K','20',0))
ENDIF
IF vk3 CONTAINS 'L' THEN
SET VAR vk31 = (SRPL(.vk31,'L','21',0))
ENDIF
IF vk3 CONTAINS 'M' THEN
SET VAR vk31 = (SRPL(.vk31,'M','22',0))
ENDIF
IF vk3 CONTAINS 'N' THEN
SET VAR vk31 = (SRPL(.vk31,'N','23',0))
ENDIF
IF vk3 CONTAINS 'O' THEN
SET VAR vk31 = (SRPL(.vk31,'O','24',0))
ENDIF
IF vk3 CONTAINS 'P' THEN
SET VAR vk31 = (SRPL(.vk31,'P','25',0))
ENDIF
IF vk3 CONTAINS 'Q' THEN
SET VAR vk31 = (SRPL(.vk31,'Q','26',0))
ENDIF
IF vk3 CONTAINS 'R' THEN
SET VAR vk31 = (SRPL(.vk31,'R','27',0))
ENDIF
IF vk3 CONTAINS 'S' THEN
SET VAR vk31 = (SRPL(.vk31,'S','28',0))
ENDIF
IF vk3 CONTAINS 'T' THEN
SET VAR vk31 = (SRPL(.vk31,'T','29',0))
ENDIF
IF vk3 CONTAINS 'U' THEN
SET VAR vk31 = (SRPL(.vk31,'U','30',0))
ENDIF
IF vk3 CONTAINS 'V' THEN
SET VAR vk31 = (SRPL(.vk31,'V','31',0))
ENDIF
IF vk3 CONTAINS 'W' THEN
SET VAR vk31 = (SRPL(.vk31,'W','32',0))
ENDIF
IF vk3 CONTAINS 'X' THEN
SET VAR vk31 = (SRPL(.vk31,'X','33',0))
ENDIF
IF vk3 CONTAINS 'Y' THEN
SET VAR vk31 = (SRPL(.vk31,'Y','34',0))
ENDIF
IF vk3 CONTAINS 'Z' THEN
SET VAR vk31 = (SRPL(.vk31,'Z','35',0))
ENDIF
SET VAR vbban = (.vk5 + .vk31)
SET VAR vbban1 = (SGET(.vbban,9,1))
SET VAR vbban2 = (SGET(.vbban,7,10))
SET VAR vbban3 = ((SGET(.vbban,2,17)) + '12170')
-- C = 12, H = 17
-- 1. 9er Zeile
SET VAR vbb1 = (INT(.vbban1))
SET VAR vm1 = (MOD(.vbb1,97))
SET VAR vba1 = ((CTXT(.vm1)) + .vbban2)
-- 2. 9er Zeile
SET VAR vbb2 = (INT(.vba1))
SET VAR vm2 = (MOD(.vbb2,97))
SET VAR vba2 = ((CTXT(.vm2)) + .vbban3)
-- 3. 9er Zeile
SET VAR vbb3 = (INT(.vba2))
SET VAR vm3 = (MOD(.vbb3,97))
SET VAR vba3 = ((CTXT(.vm3)) + '0')
-- Rest
SET VAR vbb4 = (INT(.vba3))
SET VAR vm4 = (MOD(.vbb4,97))
SET VAR vpz = (98 - .vm4)
IF vpz < 10 THEN
SET VAR vpz1 = ('0' + (CTXT(.vpz)))
ELSE
SET VAR vpz1 = (CTXT(.vpz))
ENDIF
UPDATE midat SET iban = ('CH' + .vpz1 + .vk5 + .vk3) +
WHERE CURRENT OF ccsh1
SET VAR vpnr = (.vpnr + 1)
SET VAR vdial = ((CTXT(.vpnr)) & 'von' & (CTXT(.vcnt)))
PAUSE 4 USING .vdial +
CAPTION 'IBAN' ICON APP +
&vpausopt |THEMENAME &vtheme
FETCH ccsh1 INTO vblz vi1, vkto vi2
ENDWHILE
ENDIF
-- AT
IF vvnat = 'o' THEN
OPEN ccsh1
FETCH ccsh1 INTO vblz vi1, vkto vi2
WHILE SQLCODE = 0 THEN
SET VAR vk2 = (11 - (SLEN(.vkto)))
SET VAR vk3 = ((SFIL('0',.vk2)) + .vkto)
SET VAR vk4 = (5 - (SLEN(.vblz)))
SET VAR vk5 = ((SFIL('0',.vk4)) + .vblz)
SET VAR vbban = (.vk5 + .vk3)
SET VAR vbban1 = (SGET(.vbban,9,1))
SET VAR vbban2 = (SGET(.vbban,7,10))
SET VAR vbban3 = ((SGET(.vbban,2,17)) + '10290')
-- A = 10, T = 29
-- 1. 9er Zeile
SET VAR vbb1 = (INT(.vbban1))
SET VAR vm1 = (MOD(.vbb1,97))
SET VAR vba1 = ((CTXT(.vm1)) + .vbban2)
-- 2. 9er Zeile
SET VAR vbb2 = (INT(.vba1))
SET VAR vm2 = (MOD(.vbb2,97))
SET VAR vba2 = ((CTXT(.vm2)) + .vbban3)
-- 3. 9er Zeile
SET VAR vbb3 = (INT(.vba2))
SET VAR vm3 = (MOD(.vbb3,97))
SET VAR vba3 = ((CTXT(.vm3)) + '0')
-- Rest
SET VAR vbb4 = (INT(.vba3))
SET VAR vm4 = (MOD(.vbb4,97))
SET VAR vpz = (98 - .vm4)
IF vpz < 10 THEN
SET VAR vpz1 = ('0' + (CTXT(.vpz)))
ELSE
SET VAR vpz1 = (CTXT(.vpz))
ENDIF
UPDATE midat SET iban = ('AT' + .vpz1 + .vk5 + .vk3) +
WHERE CURRENT OF ccsh1
SET VAR vpnr = (.vpnr + 1)
SET VAR vdial = ((CTXT(.vpnr)) & 'von' & (CTXT(.vcnt)))
PAUSE 4 USING .vdial +
CAPTION 'IBAN' ICON APP +
&vpausopt |THEMENAME &vtheme
FETCH ccsh1 INTO vblz vi1, vkto vi2
ENDWHILE
ENDIF
DROP CURSOR ccsh1
LABEL liban1
CLS
CLEAR VAR vpnr, vcnt, vk2, vk3, vk4, vk5, vk31
CLEAR VAR vba1, vba2, vba3, vm1, vm2, vm3, vm4
CLEAR VAR vbb1, vbb2, vbb3, vbb4, vpz, vpz1
CLEAR VAR vbban, vbban1, vbban2, vbban3, vi%
RETURN
Hartmut Braun
Am 02.05.2013 09:20, schrieb Tony IJntema:
Hi,
In 2014 we will have to use a new bank account number in Europe.
It looks like this: NL91ABNA0417164300
91 is a check digit
This check digit is a result of a mod 97 operation.
The calculation that needs to be performed is:
(mod(101123100417164300232100,97))
(The length of the figure is 24 characters)
The result = 7
The check digit then becomes 98 - 7 = 91
My question is: This figure is too big for a modular operation and bignums
are not allowed in the mod function. Does anybody know a workaround?
N.B.
To rules to create the long figure are:
Change the IBAN to: ABNA0417164300NL00 (Put NL (=countrycode) after the
figure and add two zeroes to it.
Replace all letters by it's position in the Alphabet and add 9 to this
number ( A = 10, B = 11, and so on)
Tony