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):
Bild 1: Entwurf der Tabelle tblVersions
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.
Bild 3: Das Formular frmQRCodesDie 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 tblNumberOfDataCodewords 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.