Die Unterschiede liegen bei fast allen diesen Varianten bei der Wertigkeit der Multiplikatoren und dem Modulowert. Beginnt bei einem EAN-13 die Multiplikation mit 1 und wechselt sich danach mit 3 ab so arbeitet die Berechnung für EAN-14 genau umgekehrt. Beim EAN-128 hingegen liegt der Unterschied zum EAN-13 im Modulowert. Anstelle von 10 wird hier mit 103 gearbeitet. Die Berechnung des Code128 wiederum beruht auf den selben Multiplikatoren wie beim EAN128, arbeitet jedoch wie der EAN13 mit einem Modulowort von 10.
Am Beispiel einer Code128 Nummer sähe die Berechnung wie folgt aus:
EAN-Nummer 8 154711 00011
Ziffern 8 1 5 4 7 1 1 0 0 0 1 1
Multiplikation 3 1 3 1 3 1 3 1 3 1 3 1
Ergebnis 24 1 15 4 21 1 3 0 0 0 3 1 Summe: 73
Division durch 10 ergibt einen Restwert von 3
Subtrahiert von 10 erhalten wir als Prüfziffer die 7
Um nun mit verschiedenen Multiplikatoren und Modulowerten arbeiten zu können benötigen wir zwei Funktionen. Die Erste beinhaltet die eigentliche Berechnung welche wiederum als erstes die zweite Funktion aufruft, in welcher die Wertezuweisung für die Multiplikatoren und den Modulowert vorgenommen werden.
Diese zweite Funktion kann natürlich anstatt als fixe Funktion auch als Cursor, basierend auf einer XML Datei oder einer Tabelle, verfügbar gemacht werden.
* // Funktionstest
CLEAR
?GetCheckDigit([815471100011],[EAN-13])
?GetCheckDigit([815471100012],[EAN-14])
?GetCheckDigit([815471100013],[Code25])
?GetCheckDigit([815471100014],[Code128])
?GetCheckDigit([815471100015],[Leitcode])
FUNCTION GetCheckDigit as String
LPARAMETERS pcString as String, pcVariante as String
LOCAL lcReturn as String, i as Integer, liQuersumme as Integer, ;
liMP1 as Integer, liMP2 as Integer, liModulo as Integer
STORE [] TO lcReturn
STORE 0 TO liQuersumme, liMP1, liMP2, liModulo
IF GetCheckDigitValues(pcVariante,@liMP1,@liMP2,@liModulo)
FOR i = 1 TO LEN(pcString)
* // Bei ungeraden Position mit liMP1 multiplizieren, andern-
* // falls nur mit liMP2 (=Beibehaltung des Originalwertes)
liQuersumme = liQuersumme + (INT(VAL(SUBSTR(pcString,i,1)) * IIF(MOD(i,2) > 0,liMP1,liMP2)))
ENDFOR
* // Die berechnete Quersumme nun mit Modulo auf den
* // Restwert reduzieren
lcReturn = CAST(IIF(10 - MOD(liQuersumme, liModulo) = liModulo,0,liModulo - MOD(liQuersumme, liModulo)) as C(1))
ENDIF
RETURN lcReturn
ENDFUNC
FUNCTION GetCheckDigitValues as Boolean
LPARAMETERS pcVariante as String, riMP1 as Integer, riMP2 as Integer, riModulo as Integer
LOCAL llReturn as Boolean
lLReturn = .T.
pcVariante = UPPER(pcVariante)
DO CASE
CASE pcVariante = [EAN-13]
riMP1 = 1
riMP2 = 3
riModulo = 10
CASE INLIST(pcVariante,[CODE25],[CODE128],[EAN-14],[ITF-14],[SCC-14],[DUN-14])
riMP1 = 3
riMP2 = 1
riModulo = 10
CASE INLIST(pcVariante,[EAN-128],[GS1-128],[UCC-128])
riMP1 = 1
riMP2 = 3
riModulo = 103
CASE pcVariante = [LEITCODE]
riMP1 = 4
riMP2 = 9
riModulo = 10
OTHERWISE
llReturn = .F.
ENDCASE
RETURN llReturn
ENDFUNC
Das erste Beispiel ist m.M. nach ne EAN13, nicht ne EAN128 Berechnung?
AntwortenLöschenHallo wOOdy,
AntwortenLöschendas Musterbeispiel im ersten grauen Block ist ein Code128. Erster Multiplikator: 3, zweiter Multiplikator: 1, Modulowert: 10
Der Unterschied zum EAN13 ist allerdings tatsächlich winzig. Beim EAN13 sind die beiden Multiplikatoren in ihrer Reihenfolge ausgetauscht.
Vermutlich kommt Deine Irritation daher, dass im vorstehenden Einleitungstext nur die Rede von EAN13 und EAN128 ist. Das werde ich sicherheitshalber mal korrigieren. :-)