EAN-Strichcode mit Bordmitteln

Nicht selten fragen Access-Entwickler, wie sie Strichcodes in Berichten abbilden können. Das Internet bietet verschiedene Möglichkeiten von kostenpflichtigen Tools bis hin zu speziellen Schriftarten. Wir wollen am Beispiel von EAN-13 zeigen, wie Sie einen solchen Code mit ein wenig Handarbeit selbst generieren und in einem Bericht anzeigen können.

Die European Article Number

EAN steht für European Article Number, die wiederum die Globel Trade Item Number (GTIN) abgelöst hat. Es gibt zwei Varianten (mit acht und mit 13 Stellen), die von der Organisation Global Standards One (GT1) vergeben werden.

In diesem Beitrag konzentrieren wir uns auf die 13-stellige Variante, die als eindeutige Produktkennzeichnung dient – dies gilt ebenfalls für die achtstellige Version, die speziell für Artikel geringeren Ausmaßes und dementsprechend mit weniger Platz zum Platzieren des Codes auskommen müssen.

Anlass für diesen Beitrag ist übrigens die Veröffentlichung eines Buchs und damit der Wunsch, dieses auch mit einer ISBN und einem entsprechenden Strichcode auszustatten. Die ISBN wiederum ist ein Spezialfall eines EAN-Codes, wobei sich die Unterschiede auf die Notation (bei Büchern mit Bindestrichen, also etwa 978-3-944216-00-3 und beim EAN-Code ohne Bindestriche) und auf die ersten Ziffern beschränken, welche beim EAN-Code für Waren eigentlich als Länderkennzeichen dienen. Bei Waren besteht der EAN-13-Code also aus folgenden Bestandteilen:

  • Erste drei Stellen: Länderpräfix (in Deutschland 400 bis 440)
  • Folgende vier bis sechs Stellen: Unternehmensnummer des Herstellers
  • Folgende drei bis fünf Stellen: Artikelnummer, muss zusammen mit den vorherigen Stellen insgesamt 12 Stellen ergeben
  • Letzte Stelle: Prüfcode, der die Richtigkeit der vorherigen Stellen gewährleistet

Bei Büchern besteht die ISBN aus diesen Informationen:

  • Erste drei Stellen: Ein Code für Bücher (978 und 979, für Zeitschriften 977)
  • Folgende ein bis drei Stellen: Ländernummer (Gruppennummer), für Deutschland beispielsweise 3
  • Die folgenden sieben bis neun Stellen enthalten die Verlagsnummer und die Titelnummer.
  • Die letzte Stelle enthält wiederum die Prüfziffer.

Prüfziffer berechnen

Bevor wir uns an die Ausgabe des EAN-13-Codes in einem Access-Bericht begeben, schauen wir uns noch die Berechnung der Prüfziffer an, also der letzten Ziffer des Codes.

Diese erfolgt nach der Formel aus Bild 1. Das bedeutet, dass Sie zunächst die erste, dritte, fünfte, siebte, neunte und elfte Ziffer addieren. Als Nächstes addieren Sie die zweite, vierte, sechste, achte, zehnte und zwölfte Ziffer und multiplizieren diese Summe mit 3. Danach berechnet man den Modulo für die Summe der beiden Zwischenergebnisse und die Zahl 10, was bedeutet, dass Sie den Rest der Division ermitteln. Angenommen, wir arbeiten mit der Zahl 978394421600, dann erhalten wir als erste Summe 9+8+9+4+1+0 gleich 31 und als zweite Summe 7+3+4+2+6+0 gleich 22. Die erste Summe zum Dreifachen der zweiten Summe addiert ergibt 97. Der Modulo aus 97 und 10 ist 7. Dieses Ergebnis wird schließlich noch von 10 subtrahiert und erneut mit mod 10 behandelt – dies sorgt dafür, dass der Wert 10 gegebenenfalls zum Ergebnis 0 führt und keine zweistellige Prüfziffer herauskommt.

pic001.png

Bild 1: Formel zur Berechnung der Prüfziffer

Dies müssen Sie nun nur noch in VBA-Code gießen. Kein Problem – das Ergebnis sieht wie in Listing 1 aus. Die Funktion Pruefziffer erwartet eine zwölfstellige Zeichenkette, anderenfalls wird sie gleich mit einer entsprechenden Meldung beendet. Die beiden Summen über die Ziffern auf den ungeraden und den geraden Positionen bildet die Funktion in einer Schleife, wobei der Faktor drei bei den Ziffern auf den geraden Positionen gleich mit einfließt. Die letzte Anweisung der Prozedur führt die beiden Modulo-Operationen durch und gibt das Endergebnis als Funktionswert zurück.

Listing 1: Ermitteln der Prüfziffer für einen EAN-Code

Public Function Pruefziffer(strEANOhne) As String
    Dim intSummeEinfach As Integer
    Dim intSummeDreifach As Integer
    Dim i As Integer
    If Not Len(strEANOhne) = 12 Then
        MsgBox "Die zu prüfende Ziffernfolge muss zwölf Ziffern enthalten."
        Exit Function
    End If
    For i = 1 To 6
        intSummeEinfach = intSummeEinfach + Mid(strEANOhne, i * 2 - 1, 1)
        intSummeDreifach = intSummeDreifach + 3 * Mid(strEANOhne, i * 2, 1)
    Next i
    Pruefziffer = (10 - (intSummeEinfach + intSummeDreifach) Mod 10) Mod 10
End Function

Wenn Sie eine solche Funktion erstellen und testen, helfen einige Testaufrufe mit Beispielwerten weiter. Dies kann etwa wie in Listing 2 aussehen und liefert eine entsprechende Ausgabe an das Direktfenster.

Listing 2: Testaufrufe der Prüfziffern-Berechnung

Public Sub Test_Pruefziffer()
    Debug.Print "978382732950", Pruefziffer("978382732950") = "9", Pruefziffer("978382732950")
    Debug.Print "978394421600", Pruefziffer("978394421600") = "3", Pruefziffer("978394421600")
    Debug.Print "978394421601", Pruefziffer("978394421601") = "0", Pruefziffer("978394421601")
    ...
End Sub

Nachdem diese Funktion schon recht einfach zu erstellen war, setzen wir noch eine weitere Funktion oben drauf, mit der Sie einen 13-stelligen EAN-Code auf seine Gültigkeit prüfen können. Diese Funktion heißt EANPruefen und sieht wie in Listing 3 aus. Die Funktion prüft wiederum die korrekte Länge des zu prüfenden Codes und teilt diesen dann zunächst in den eigentlichen Code (also die ersten zwölf Ziffern) und die Prüfziffer auf. Wenn die an der letzten Stelle des Codes enthaltene Prüfziffer mit der Prüfziffer übereinstimmt, welche die Funktion Pruefziffer für die ersten zwölf Stellen ermittelt, dann ist der EAN-Code inklusive Prüfziffer korrekt.

Listing 3: Prüfung kompletter EAN-Codes inklusive Prüfziffer

Public Function EANPruefen(strEAN) As Boolean
    Dim strEANOhne As String
    Dim strPruefziffer As String
    If Not Len(strEAN) = 13 Then
        MsgBox "Die zu prüfende Ziffernfolge muss 13 Ziffern enthalten."
        Exit Function
    End If
    strEANOhne = Left(strEAN, 12)
    strPruefziffer = Right(strEAN, 1)
    EANPruefen = strPruefziffer = Pruefziffer(strEANOhne)
End Function

EAN-Strichcode

Wenn Sie denken, damit wäre der komplizierteste Teil erledigt, irren Sie. Verglichen mit dem Aufwand, der zum Ausdrucken des Strichcodes für einen EAN-Code nötig ist, war dies ein Kinderspiel. In Bild 2 haben wir einen solchen Strichcode schematisch abgebildet. Der Strichcode unterteilt sich grob in die folgenden Bereiche:

pic002.png

Bild 2: Aufbau des Strichcodes

  • Strich 1 bis 3: Startbegrenzung
  • Strich 4 bis 45: Code für die Ziffern 2 bis 7
  • Strich 46 bis 50: Markierung zum Aufteilen der ersten und zweiten Hälfte des tatsächlichen Codes
  • Strich 51 bis 92: Code für die Ziffern 8 bis 13
  • Strich 93 bis 95: Abschlussbegrenzung

Die erste Ziffer wird nicht als Strichcode abgebildet, sie entscheidet jedoch, wie die ersten sechs Ziffern als Strichcode dargestellt werden. Und das geht so: Sie schauen in die Tabelle aus Bild 3 und suchen die Zeile heraus, die der ersten Ziffer entspricht. Bei Büchern ist das immer die Ziffer 9, also verwenden wir die unterste Zeile.

pic003.png

Bild 3: Festlegung der zu verwendende Spalte für die Strichcodes

Damit und mit der Tabelle aus Bild 4 betrachten wir nun die folgenden zwölf Ziffern. Für unser Beispiel 978-3-8273-2950-9 (der besseren Übersicht halber als ISBN formatiert) kommt also als Erstes die Ziffer 7 an die Reihe. Dies ist die zweite Ziffer, also verwenden wir Spalte A. Spalte A liefert für die Ziffer 7 den Wert 0111011.

pic004.png

Bild 4: Je nach dem Wert der ersten Ziffer wird die aktuelle Ziffer durch eine dieser Ziffernfolgen ersetzt.

Die dritte Ziffer ist die 8 und soll durch den entsprechenden Wert aus Spalte B ersetzt werden – also 0001001. So gehen wir weiter vor und finden für die zweite bis siebte Ziffer diese Werte:

  • Die zweite Ziffer 7 entspricht 0111011 (aus Spalte A),
  • die dritte Ziffer 8 entspricht 0001001 (aus Spalte B),
  • die vierte Ziffer 3 entspricht 0100001 (aus Spalte B),
  • die fünfte Ziffer 8 entspricht 0110111 (aus Spalte A),
  • die sechste Ziffer 2 entspricht 0011011 (aus Spalte B) und
  • die siebte Ziffer 7 entspricht 0111011 (aus Spalte A).

Bei der achten bis dreizehnten Ziffer ist es einfacher, da die entsprechenden Werte alle aus Spalte C der zweiten Tabelle stammen. Für die Ziffern 329509 kommt so der Ausdruck 1000010-1101100-1110100-1001110-1110010-1110100 zusammen (der besseren Übersicht wegen durch Bindestriche getrennt).

Damit hätten wir zwei sehr längliche Ausdrücke, die aus 1 und 0 bestehen. Vor dem ersten Ausdruck (also den 42 Zeichen für die ersten sechs Ziffern) schieben wir nun die Startbegrenzung 101 ein, zwischen den Ausdrücken für die Ziffern zwei bis sieben und acht bis dreizehn fügen wir als Unterteilung 01010 ein und am Ende hängen wir nochmals als Endbegrenzung die Folge 101 an.

Dies ergibt 101_0111011_0001001_0100001_0110111_0011011_0111011_01010_1000010_1101100_1110100_1001110_1110010_1110100_101, wobei die einzelnen Elemente für die Übersicht durch Unterstriche voneinander getrennt wurden.

Und das ist auch schon die Grundlage für den Strichcode! Sie müssen nun nur noch für jede 1 einen Strich markieren und für jede 0 einen Leerraum, wobei Striche und Leerräume natürlich die gleiche Breite aufweisen müssen. Die Striche für die Start- und die Endbegrenzungen 101 sowie den Mittelteil 01010 müssen unten länger sein, die Zahlen werden davor beziehungsweise dazwischen platziert.

Nun kommen zwei Aufgaben auf uns zu: Erstens die Erstellung einer Prozedur, die aus den 13 Ziffern eines EAN-Codes den aus 1 und 0 bestehenden und in Form eines Strichcodes anzeigbaren Ausdruck zu ermitteln und – noch interessanter – das Erstellen eines Access-Berichts, der diese Striche auf den Bericht zaubert.

Strichcode aus EAN-Code berechnen

Die Funktion ConvertEAN ermittelt die aus 1 und 0 bestehende Zeichenfolge, die es ermöglicht, einen EAN-Code als Strichcode anzuzeigen (siehe Bild 5 erfolgt.

Listing 4: Ermitteln der Binärzeichenfolge aus einem EAN-Code

Public Function ConvertEAN(strEAN As String) As String
    Dim i As Integer
    Dim intNumber As Integer
    Dim strResult As String
    Const cTA As String = "0001101001100100100110111101010001101100010101111011101101101110001011"
    Const cTB As String = "0100111011001100110110100001001110101110010000101001000100010010010111"
    Const cTC As String = "1110010110011011011001000010101110010011101010000100010010010001110100"
    strResult = strResult & "101"
    For i = 2 To 7 ''Ziffern 2 bis 13
        intNumber = Mid(strEAN, i, 1)
        Select Case i
            Case 2
                Select Case Left(strEAN, 1)
                    Case 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
                        strResult = strResult & Mid(cTA, (intNumber) * 7 + 1, 7)
                End Select
        Case 3
            Select Case Left(strEAN, 1)
                Case 0, 1, 2, 3
                    strResult = strResult & Mid(cTA, (intNumber) * 7 + 1, 7)
                Case Else
                    strResult = strResult & Mid(cTB, (intNumber) * 7 + 1, 7)
            End Select
        Case 4
            Select Case Left(strEAN, 1)
                Case 0, 4, 7, 8
                    strResult = strResult & Mid(cTA, (intNumber) * 7 + 1, 7)
                Case Else
                    strResult = strResult & Mid(cTB, (intNumber) * 7 + 1, 7)
            End Select
        Case 5
            Select Case Left(strEAN, 1)
                Case 0, 1, 4, 5, 9
                    strResult = strResult & Mid(cTA, (intNumber) * 7 + 1, 7)
                Case Else
                    strResult = strResult & Mid(cTB, (intNumber) * 7 + 1, 7)
            End Select
        Case 6
            Select Case Left(strEAN, 1)
                Case 0, 2, 5, 6, 7
                    strResult = strResult & Mid(cTA, (intNumber) * 7 + 1, 7)
                Case Else
                    strResult = strResult & Mid(cTB, (intNumber) * 7 + 1, 7)
            End Select
        Case 7
            Select Case Left(strEAN, 1)
                Case 0, 3, 6, 8, 9
                    strResult = strResult & Mid(cTA, (intNumber) * 7 + 1, 7)
                Case Else
                    strResult = strResult & Mid(cTB, (intNumber) * 7 + 1, 7)
            End Select
        End Select
    Next i
    strResult = strResult & "01010"
    For i = 8 To 13
         intNumber = Mid(strEAN, i, 1)
        strResult = strResult & Mid(cTC, (intNumber) * 7 + 1, 7)
    Next i
    strResult = strResult & "101"
    ConvertEAN = strResult
End Function

pic005.png

Bild 5: Ermittlung eines Strichcodes im Direktfenster

Die Funktion fasst die Werte der Tabelle mit den drei Spalten A, B und C in drei Konstanten namens cTA, cTB und cTC zusammen, wobei die jeweils zehn Zeichen einfach in der richtigen Reihenfolge aneinandergehängt wurden. Die Variable strResult wird nun Stück für Stück mit den benötigten Elementen gefüllt. Den Start macht die Anfangsbegrenzung 101.

Anschließend durchläuft die Prozedur eine Schleife über die zweite bis siebte Ziffer des EAN-Codes. In dieser Schleife prüft die Funktion in einer Select Case-Bedingung zunächst, von welcher Position des EAN-Codes die aktuelle Ziffer stammt.

Handelt es sich beispielsweise um die zweite Stelle, soll immer der in Spalte A der Tabelle abgebildete Strichcode verwendet werden – also für alle Ziffern von 0 bis 9. Die Mid-Funktion ermittelt dann aus den 70 Zeichen der Konstanten cTA die sieben Zeichen, die der jeweiligen Ziffer entsprechen. Das sind für die 0 die ersten sieben, für die 1 die zweiten sieben und so weiter.

Damit dies funktioniert, multipliziert der folgende Ausdruck zunächst die Zahl aus intNumber mit 7, addiert 1 und liest von dieser Position aus sieben Zeichen des Wertes der Konstanten cTA:

Mid(cTA, (intNumber) * 7 + 1, 7)

Hat intNumber also etwa den Wert 3, liefert dies die Zeichen von der 22. bis zur 28. Stelle.

Bei der zweiten Stelle wird es schon interessanter, denn hier kommen die sieben Ziffern für den Strichcode für die aktuelle Ziffer des EAN-Codes nicht alle aus Spalte A der Tabelle, sondern sowohl aus Spalte A als auch aus Spalte B. Dies deckt der entsprechende Case-Zweig wie folgt ab:

Case 3
    Select Case Left(strEAN, 1)
        Case 0, 1, 2, 3
            strResult = strResult & Mid(cTA, (intNumber) * 7 + 1, 7)
        Case Else
            strResult = strResult & Mid(cTB, (intNumber) * 7 + 1, 7)
    End Select

In diesem Fall soll für die dritte Stelle des EAN-Codes die Ziffernfolge aus Spalte A der zweiten Tabelle verwendet werden, wenn die erste Stelle des EAN-Codes den Wert 0, 1, 2 oder 3 enthält und sonst die Ziffernfolge aus Spalte B.

Auf diese Weise fertigt die Funktion die zweite bis siebte Stelle des EAN-Codes ab und stellt die entsprechenden Einsen und Nullen zusammen. Dann fügt sie der Variablen strResult für den Mittelteil die Ziffernfolge 01010 hinzu und widmet sich dann der Umsetzung der Positionen 8 bis 13 des EAN-Codes.

Das ist wesentlich einfacher, da hier alle Werte aus Spalte C der zweiten Tabelle stammen. Die For…Next-Schleife braucht daher einige Fallunterscheidungen weniger:

For i = 8 To 13
    intNumber = Mid(strEAN, i, 1)
    strResult = strResult & Mid(cTC, (intNumber) * 7 + 1, 7)
Next i

Zu guter Letzt hängt die Funktion noch die abschließende Ziffernfolge 101 an den in strResult gespeicherten Ausdruck an und gibt diesen als Funktionswert zurück.

Strichcodes in Berichten drucken

Fehlt noch eine abschließende Aufgabe: das Drucken der Strichcodes für die auf Basis des EAN-13-Codes ermittelte Kombination aus Einsen und Nullen.

Hier gibt es zwei Ansätze. Der erste setzt auf das Linie-Steuerelement. Sie könnten eine ausreichende Anzahl davon auf dem Bericht platzieren und die Linie-Steuerelemente dann in der gewünschten Höhe und Breite anzeigen lassen. Außerdem fügen Sie noch drei Textfelder hinzu, welche die Zahl vor dem Strichcode (also die erste Position des EAN-Codes), die Zahlen der zweiten bis siebten Position und die Zahlen der achten bis dreizehnten Position an den entsprechenden Stellen unterbringen.

Diese Variante setzt allerdings auch voraus, dass Sie vorher wissen, wie viele EANs Sie auf dem Bericht unterbringen möchten – dementsprechend viele Linie-Steuerelemente müssen Sie bevorraten.

Deshalb wählen wir eine flexiblere Lösung. Diese benötigt gar keine Steuerelemente, sondern zeichnet alle Linien zur Laufzeit mit der Line-Methode des Berichts-Objekts. Und sogar die Zahlen unter dem Strichcode werden einfach mit der Print-Methode erzeugt. Gut, ganz so leicht ist es dann doch nicht: Immerhin müssen Sie diesen Befehlen als Parameter noch die Koordinaten der Elemente mitgeben, was die Hauptarbeit der folgenden Schritte ist.

Damit Sie schon einmal sehen, worauf wir hinarbeiten – die folgende Prozedur, die durch das Ereignis Bei Seite des betroffenen Berichts aufgerufen wird, legt die neun Strichcodes aus Bild 6 im Bericht an:

Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...

den kompletten Artikel im PDF-Format mit Beispieldatenbank

diesen und alle anderen Artikel mit dem Jahresabo

Schreibe einen Kommentar