QR-Codes mit Access erzeugen, Teil II

Wenn Sie ein Abonnement des Magazins 'Access im Unternehmen' besitzen, können Sie sich anmelden und den kompletten Artikel lesen.
Anderenfalls können Sie das Abonnement hier im Shop erwerben.

QR-Codes mit Access erzeugen, Teil II

Im ersten Teil dieser Beitragsreihe haben wir bereits den Ausdruck codiert, der später in Form eines QR-Codes grafisch abgebildet werden soll. Der weitaus interessantere Teil folgt noch: Die Berechnung des Fehlerkorrekturcodes. Schließlich folgt dann im letzten Teil der Beitragsreihe noch die Erstellung der eigentlichen Grafik, die Sie dann beispielsweise als Bilddatei speichern und etwa in einem Bericht einer Access-Datenbank weiterverwenden können.

Der Stand nach dem ersten Teil der Beitragsreihe ist, dass wir eine codierte Zeichenkette vorliegen haben – unabhängig davon, ob diese als Zahl, als reiner Text oder als alphanumerische Zeichenkette daherkommt. Außerdem haben wir eine Möglichkeit geschaffen, den Grad der Fehlerkorrektur auszuwählen und die Version, also die Kantenlänge des zu erzeugenden QR-Codes. Dieser wird schließlich bereits aus der Länge der zu kodierenden Zeichenkette, dem Fehlerkorrekturgrad und der Codiermethode ermittelt.

Als Nächstes benötigen wir den Fehlerkorrekturcode. Um diesen zu ermitteln, legen wir zunächst die Länge des Fehlerkorrekturcodes fest. Dies geschieht mithilfe einer Tabelle namens tblNumberOfDataCodewords (Entwurf siehe Bild 1). Die Tabelle liefert die folgenden wichtigen Informationen, wobei wir den Datensatz aus der Tabelle nutzen, dessen Felder VersionID und ErrorCorrectionLevelID für unsere Codierung zutreffen (s. Bild 2):

Entwurf der Tabelle tblVersions

Bild 1: Entwurf der Tabelle tblVersions

Die Tabelle tblVersions mit einigen Werten

Bild 2: Die Tabelle tblVersions mit einigen Werten

  • Wir teilen den Code für unseren Text in ein, zwei oder vier Blöcken mit einer bestimmten Anzahl von Codewörtern mit je acht binären Zeichen auf. Wenn NumberOfBlocksInGroup1 den Wert 1 enthält, verwenden wir nur einen Block, der die im Feld NumberOfDataCodewordsInGroup1Blocks angegebene Anzahl von Codewörtern enthält.
  • Wenn NumberOfBlocksInGroup1 den Wert 2 oder einen größeren Wert enthält, benötigen wir zwei oder mehr Blöcke mit der entsprechenden Anzahl von Codewörtern in der ersten Gruppe.
  • Es gibt noch eine zweite Gruppe, für welche die beiden Felder NumberOfBlocksInGroup2 und NumberOfDataCodewordsInGroup1Blocks die Anzahl der Blöcke und Codewörter angeben.

Wenn wir also beispielsweise für VersionID den Wert 5 und für die Fehlerkorrektur den Level Q ausgewählt haben, haben wir zwei Gruppen, wobei die erste zwei Blöcke mit je 15 Codewörtern aufnimmt und die zweite zwei Blöcke mit je 16 Codewörtern. Wenn Sie also beispielsweise einen Text codieren, der mit den oben genannten Parametern um einen Fehlerkorrekturcode erweitert werden soll, wird dieser Text 2 x 15 x 8 + 2 x 16 x 8 Zeichen lang sein, also 496 Zeichen lang sein – was auch der Fall ist. Wir brechen dies auf ein einfacheres Beispiel herunter, zum Beispiel zur Codierung der Zeichenkette HELLO WORLD. Wir verwenden den Fehlerkorrekturgrad M und die kleinste Version mit 21 x 21 Zeichen. Die codierte Zeichenfolge sieht nach der Beschreibung aus dem ersten Teil der Beitragsreihe so aus:

0010000001011011000010110111100011010001011100101101110001001101
0100001101000000111011000001000111101100000100011110110000010001

Die Tabelle tblNumberOfDataCodewords liefert die Information, dass diese Zeichenfolge in eine Gruppe mit 16 Blöcken á acht Zeichen aufgeteilt wird, also etwa so:

  • 00100000
  • 01011011
  • 00001011
  • ...

Diese Zahlen benötigen wir später, wenn wir ein Polynom für den zu codierenden Text erstellen müssen. Die Zahlen dienen dann als Koeffizienten.

Steuerung der Codierung

Die Codierung starten Sie mit einem Klick auf die Schaltfläche cmdAktualisieren des Formulars frmQRCodes, das nun wie in Bild 3 aussieht. Dieses Formular erlaubt, wie schon im ersten Teil erläutert, die Eingabe des zu codierenden Textes in das Textfeld txtAusgangstext, die Auswahl des Zeichensatzes mit dem Kombinationsfeld cboModeID, den Grad der Fehlerkorrektur mit cboErrorCorrectionID und die Version beziehungsweise Kantenlänge mit cboVersionID.

Das Formular frmQRCodes

Bild 3: Das Formular frmQRCodes

Die Schaltfläche cmdAktualisieren löst nun die Prozedur aus Listing 1 aus. Diese erledigt zunächst die bereits im ersten Teil der Beitragsreihe beschriebenen Aufgaben, sprich: den binären Code zu ermitteln, welcher die Information über die Codierung, die Anzahl der Zeichen und den Text selbst in binärer Form enthält.

Private Sub cmdAktualisieren_Click()
     Dim strCode As String
     Dim lngBlocksGruppe1 As Long
     Dim lngWoerterGruppe1 As Long
     Dim lngBlocksGruppe2 As Long
     Dim lngWoerterGruppe2 As Long
     Dim lngVersionID As Long
     Dim lngErrorCorrectionLevelID As Long
     Dim db As DAO.Database
     Dim rst As DAO.Recordset
     Dim intAnzahlFehlerkorrekturWoerter  As Integer
     Set db = CurrentDb
     strCode = strCode & GetModeIndicator
     strCode = strCode & GetCharacterCountIndicator
     strCode = strCode & Encode(Me!txtAusgangstext, Me!cboModeID)
     strCode = AddPadBytes(strCode, Me!cboVersionID, Me!cboErrorCorrectionID)
     Me!txtCodeInhalt = strCode
     lngVersionID = Me!cboVersionID
     lngErrorCorrectionLevelID = Me!cboErrorCorrectionID
     Set rst = db.OpenRecordset("SELECT * FROM tblNumberOfDataCodewords " _
         & "WHERE VersionID = " & lngVersionID _
         & " AND ErrorCorrectionLevelID = " & lngErrorCorrectionLevelID)
     lngBlocksGruppe1 = rst!NumberOfBlocksInGroup1
     lngWoerterGruppe1 = rst!NumberOfDataCodewordsInGroup1Blocks
     lngBlocksGruppe2 = Nz(rst!NumberOfBlocksInGroup2, 0)
     lngWoerterGruppe2 = Nz(rst!NumberOfDataCodewordsInGroup2Blocks, 0)
     intAnzahlFehlerkorrekturWoerter = rst!ECCodewordsPerBlock
     Me!txtInterleavedCode = InterleavedCode(strCode, lngBlocksGruppe1, lngWoerterGruppe1, _
         lngBlocksGruppe2, lngWoerterGruppe2)
     Me!txtInterleavedErrorCorrectionCode = InterleavedErrorCode(strCode, lngBlocksGruppe1, _
         lngWoerterGruppe1, lngBlocksGruppe2, lngWoerterGruppe2, intAnzahlFehlerkorrekturWoerter)
     Me!txtQRCode = Me!txtInterleavedCode & Me!txtInterleavedErrorCorrectionCode
End Sub

Listing 1: Diese Prozedur steuert die komplette Codierung.

Dann speichert die Prozedur die Werte der beiden Kombinationsfelder cboVersionID und cboErrorCorrectionID in entsprechenden Variablen, bevor sie darauf basierend ein Recordset öffnet. Dieses enthält den Datensatz der Tabelle tblNumberOfDataCodewords, der den mit den Kombinationsfeldern ausgewählten Parametern entspricht. Aus dieser Tabelle entnehmen wir einige Werte und speichern diese in weiteren Variablen:

  • lngBlocksGruppe1
  • lngWoerterGruppe1
  • lngBlocksGruppe2
  • lngWoerterGruppe2
  • intAnzahlFehlerkorrekturWoerter

Nun folgt der interessante, in diesem Teil der Beitragsreihe beschriebene Part: Die Umwandlung des binären Codes in einen sogenannten "interleaved" Code und das Ermitteln und Hinzufügen des Fehlerkorrekturcodes.

Dies geschieht in folgenden Schritten:

  • Vermischen des Codes zum "interleaved" Code mit der Funktion InterleavedCode,
  • Ermitteln des Fehlerkorrekturcodes auf Basis des Ausgangscodes und Vermischen zum "interleaved" Fehlerkorrekturcode mit der Funktion InterleavedErrorCode und
  • Zusammenfügen der beiden Teile im Textfeld txtQRCode.

Schauen wir uns nun an, wie diese Funktionen arbeiten.

Code weiter bearbeiten

Den Code aus dem Textfeld txtCodeInhalt beziehungsweise der Variablen strCode verwenden wir nun nicht einfach so als ersten Teil des QR-Codes. Stattdessen wird dieser erste Teil gegebenenfalls noch etwas durcheinandergewürfelt – allerdings nach fest vorgegebenen Regeln. Dies geschieht allerdings nur ab einer gewissen Länge des Codes beziehungsweise wenn die einzelnen achtstelligen Binärzahlen auf mehr als nur die erste Gruppe aufgeteilt werden – also wenn in der Tabelle tbl­NumberOfDataCodewords in der Spalte für die aktuelle Konfiguration (aus Version und Fehlerkorrektur) auch ein Wert in den Spalten NumberOfBlocksInGroup2 beziehungsweise NumberOfDataCodewordsInGroup2Blocks vorliegen. Dies ist zum Beispiel der Fall, wenn Sie die Version 5 (37 x 37 Pixel) und den Fehlerkorrekturgrad Q wählen. Dieser Code hat insgesamt 62 Codewörter, wobei die erste Gruppe zwei Blocks mit je 15 Codewörtern enthält und die zweite Gruppe zwei Blocks mit je 16 Codewörtern. Die Prozedur InterleavedCode aus Listing 2 erwartet drei Parameter:

Public Function InterleavedCode(ByVal strCode As String, lngBlocksGruppe1 As Long, _
     lngWoerterGruppe1 As Long, lngBlocksGruppe2 As Long, lngWoerterGruppe2 As Long)
     Dim i As Integer
     Dim j As Integer
     Dim strTempNeu As String
     Dim strTemp As String
     Dim intCodewoerterMatrix() As Integer
     intCodewoerterMatrix = CodeWoerterMatrix(lngBlocksGruppe1, lngWoerterGruppe1, _
         lngWoerterGruppe2, lngBlocksGruppe2)
     strTemp = Trim(strCode)
     If lngWoerterGruppe2 <> 0 Then
         For j = 1 To lngWoerterGruppe2
             For i = 1 To lngBlocksGruppe1 + lngBlocksGruppe2
                 If intCodewoerterMatrix(i, j) <> 0 Then
                     strTempNeu = strTempNeu + Mid$(strTemp, intCodewoerterMatrix(i, j) * 8 - 7, 8)
                 End If
              Next i
         Next j
     End If
     If lngWoerterGruppe2 = 0 Then
         For j = 1 To lngWoerterGruppe1
             For i = 1 To lngBlocksGruppe1 + lngBlocksGruppe2
                 If intCodewoerterMatrix(i, j) <> 0 Then
                     strTempNeu = strTempNeu + Mid$(strTemp, intCodewoerterMatrix(i, j) * 8 - 7, 8)
                 End If
             Next i
         Next j
     End If
     InterleavedCode = strTempNeu
End Function

Listing 2: "Vermischen" des Binärcodes für den Ausgangstext

  • strCode: Code in binärer Form
  • lngBlocksGruppe1: Anzahl der Blöcke in der ersten Gruppe
  • lngWoerterGruppe1: Anzahl der Codewörter in der ersten Gruppe
  • lngBlocksGruppe2: Anzahl der Blöcke in der zweiten Gruppe (gegebenenfalls 0)
  • lngWoerterGruppe2: Anzahl der Codewörter in der zweiten Gruppe (gegebenenfalls 0)

Dies war die Leseprobe dieses Artikels.
Melden Sie sich an, um auf den vollständigen Artikel zuzugreifen.

Bitte geben Sie die Zeichenfolge in das nachfolgende Textfeld ein

Die mit einem * markierten Felder sind Pflichtfelder.

Ich habe die Datenschutzbestimmungen zur Kenntnis genommen.