{"id":55000947,"date":"2014-08-01T00:00:00","date_gmt":"2020-05-22T21:12:12","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=947"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"QRCodes_mit_Access_erzeugen_Teil_II","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/QRCodes_mit_Access_erzeugen_Teil_II\/","title":{"rendered":"QR-Codes mit Access erzeugen, Teil II"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg07.met.vgwort.de\/na\/7a0acd8a80064cbe9ea3127de6d44785\" width=\"1\" height=\"1\" alt=\"\"><\/p>\n<p><b>Im ersten Teil dieser Beitragsreihe haben wir bereits den Ausdruck codiert, der sp&auml;ter in Form eines QR-Codes grafisch abgebildet werden soll. Der weitaus interessantere Teil folgt noch: Die Berechnung des Fehlerkorrekturcodes. Schlie&szlig;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&ouml;nnen. <\/b><\/p>\n<p>Der Stand nach dem ersten Teil der Beitragsreihe ist, dass wir eine codierte Zeichenkette vorliegen haben &#8211; unabh&auml;ngig davon, ob diese als Zahl, als reiner Text oder als alphanumerische Zeichenkette daherkommt. Au&szlig;erdem haben wir eine M&ouml;glichkeit geschaffen, den Grad der Fehlerkorrektur auszuw&auml;hlen und die Version, also die Kantenl&auml;nge des zu erzeugenden QR-Codes. Dieser wird schlie&szlig;lich bereits aus der L&auml;nge der zu kodierenden Zeichenkette, dem Fehlerkorrekturgrad und der Codiermethode ermittelt.<\/p>\n<p>Als N&auml;chstes ben&ouml;tigen wir den Fehlerkorrekturcode. Um diesen zu ermitteln, legen wir zun&auml;chst die L&auml;nge des Fehlerkorrekturcodes fest. Dies geschieht mithilfe einer Tabelle namens <b>tblNumberOfDataCodewords<\/b> (Entwurf siehe Bild 1). Die Tabelle liefert die folgenden wichtigen Informationen, wobei wir den Datensatz aus der Tabelle nutzen, dessen Felder <b>VersionID <\/b>und <b>ErrorCorrectionLevelID <\/b>f&uuml;r unsere Codierung zutreffen (s. Bild 2):<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2014_04\/pic_947_001.png\" alt=\"Entwurf der Tabelle tblVersions\" width=\"450\" height=\"282,1192\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Entwurf der Tabelle tblVersions<\/span><\/b><\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2014_04\/pic_947_002.png\" alt=\"Die Tabelle tblVersions mit einigen Werten\" width=\"650\" height=\"339,8305\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 2: Die Tabelle tblVersions mit einigen Werten<\/span><\/b><\/p>\n<ul>\n<li>Wir teilen den Code f&uuml;r unseren Text in ein, zwei oder vier Bl&ouml;cken mit einer bestimmten Anzahl von Codew&ouml;rtern mit je acht bin&auml;ren Zeichen auf. Wenn <b>NumberOfBlocksInGroup1 <\/b>den Wert <b>1 <\/b>enth&auml;lt, verwenden wir nur einen Block, der die im Feld <b>NumberOfDataCodewordsInGroup1Blocks <\/b>angegebene Anzahl von Codew&ouml;rtern enth&auml;lt.<\/li>\n<li>Wenn <b>NumberOfBlocksInGroup1 <\/b>den Wert <b>2 <\/b>oder einen gr&ouml;&szlig;eren Wert enth&auml;lt, ben&ouml;tigen wir zwei oder mehr Bl&ouml;cke mit der entsprechenden Anzahl von Codew&ouml;rtern in der ersten Gruppe.<\/li>\n<li>Es gibt noch eine zweite Gruppe, f&uuml;r welche die beiden Felder <b>NumberOfBlocksInGroup2 <\/b>und <b>NumberOfDataCodewordsInGroup1Blocks <\/b>die Anzahl der Bl&ouml;cke und Codew&ouml;rter angeben.<\/li>\n<\/ul>\n<p>Wenn wir also beispielsweise f&uuml;r <b>VersionID<\/b> den Wert <b>5 <\/b>und f&uuml;r die Fehlerkorrektur den Level <b>Q <\/b>ausgew&auml;hlt haben, haben wir zwei Gruppen, wobei die erste  zwei Bl&ouml;cke mit je 15 Codew&ouml;rtern aufnimmt und die zweite zwei Bl&ouml;cke mit je 16 Codew&ouml;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 &#8211; was auch der Fall ist. Wir brechen dies auf ein einfacheres Beispiel herunter, zum Beispiel zur Codierung der Zeichenkette <b>HELLO WORLD<\/b>. 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:<\/p>\n<p>0010000001011011000010110111100011010001011100101101110001001101<br \/>\n0100001101000000111011000001000111101100000100011110110000010001<\/p>\n<p>Die Tabelle <b>tblNumberOfDataCodewords <\/b>liefert die Information, dass diese Zeichenfolge in eine Gruppe mit 16 Bl&ouml;cken \u00e1 acht Zeichen aufgeteilt wird, also etwa so:<\/p>\n<ul>\n<li>00100000<\/li>\n<li>01011011<\/li>\n<li>00001011<\/li>\n<li>&#8230;<\/li>\n<\/ul>\n<p>Diese Zahlen ben&ouml;tigen wir sp&auml;ter, wenn wir ein Polynom f&uuml;r den zu codierenden Text erstellen m&uuml;ssen. Die Zahlen dienen dann als Koeffizienten.<\/p>\n<p><b>Steuerung der Codierung<\/b><\/p>\n<p>Die Codierung starten Sie mit einem Klick auf die Schaltfl&auml;che <b>cmdAktualisieren<\/b> des Formulars <b>frmQRCodes<\/b>, das nun wie in Bild 3 aussieht. Dieses Formular erlaubt, wie schon im ersten Teil erl&auml;utert, die Eingabe des zu codierenden Textes in das Textfeld <b>txtAusgangstext<\/b>, die Auswahl des Zeichensatzes mit dem Kombinationsfeld <b>cboModeID<\/b>, den Grad der Fehlerkorrektur mit <b>cboErrorCorrectionID<\/b> und die Version beziehungsweise Kantenl&auml;nge mit <b>cboVersionID<\/b>.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2014_04\/pic_947_003.png\" alt=\"Das Formular frmQRCodes\" width=\"650\" height=\"583,857\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 3: Das Formular frmQRCodes<\/span><\/b><\/p>\n<p>Die Schaltfl&auml;che <b>cmdAktualisieren <\/b>l&ouml;st nun die Prozedur aus Listing 1 aus. Diese erledigt zun&auml;chst die bereits im ersten Teil der Beitragsreihe beschriebenen Aufgaben, sprich: den bin&auml;ren Code zu ermitteln, welcher die Information &uuml;ber die Codierung, die Anzahl der Zeichen und den Text selbst in bin&auml;rer Form enth&auml;lt.<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>cmdAktualisieren_Click()\r\n     <span style=\"color:blue;\">Dim <\/span>strCode<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>lngBlocksGruppe1<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>lngWoerterGruppe1<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>lngBlocksGruppe2<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>lngWoerterGruppe2<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>lngVersionID<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>lngErrorCorrectionLevelID<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>db<span style=\"color:blue;\"> As <\/span>DAO.Database\r\n     <span style=\"color:blue;\">Dim <\/span>rst<span style=\"color:blue;\"> As <\/span>DAO.Recordset\r\n     <span style=\"color:blue;\">Dim <\/span>intAnzahlFehlerkorrekturWoerter <span style=\"color:blue;\"> As Integer<\/span>\r\n     <span style=\"color:blue;\">Set<\/span> db = CurrentDb\r\n     strCode = strCode & GetModeIndicator\r\n     strCode = strCode & GetCharacterCountIndicator\r\n     strCode = strCode & Encode(Me!txtAusgangstext, Me!cboModeID)\r\n     strCode = AddPadBytes(strCode, Me!cboVersionID, Me!cboErrorCorrectionID)\r\n     Me!txtCodeInhalt = strCode\r\n     lngVersionID = Me!cboVersionID\r\n     lngErrorCorrectionLevelID = Me!cboErrorCorrectionID\r\n     <span style=\"color:blue;\">Set<\/span> rst = db.OpenRecordset(\"SELECT * FROM tblNumberOfDataCodewords &quot; _\r\n         &amp; &quot;WHERE VersionID = \" & lngVersionID _\r\n         & \" AND ErrorCorrectionLevelID = \" & lngErrorCorrectionLevelID)\r\n     lngBlocksGruppe1 = rst!NumberOfBlocksInGroup1\r\n     lngWoerterGruppe1 = rst!NumberOfDataCodewordsInGroup1Blocks\r\n     lngBlocksGruppe2 = Nz(rst!NumberOfBlocksInGroup2, 0)\r\n     lngWoerterGruppe2 = Nz(rst!NumberOfDataCodewordsInGroup2Blocks, 0)\r\n     intAnzahlFehlerkorrekturWoerter = rst!ECCodewordsPerBlock\r\n     Me!txtInterleavedCode = InterleavedCode(strCode, lngBlocksGruppe1, lngWoerterGruppe1, _\r\n         lngBlocksGruppe2, lngWoerterGruppe2)\r\n     Me!txtInterleavedErrorCorrectionCode = InterleavedErrorCode(strCode, lngBlocksGruppe1, _\r\n         lngWoerterGruppe1, lngBlocksGruppe2, lngWoerterGruppe2, intAnzahlFehlerkorrekturWoerter)\r\n     Me!txtQRCode = Me!txtInterleavedCode & Me!txtInterleavedErrorCorrectionCode\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 1: Diese Prozedur steuert die komplette Codierung.<\/span><\/b><\/p>\n<p>Dann speichert die Prozedur die Werte der beiden Kombinationsfelder <b>cboVersionID<\/b> und <b>cboErrorCorrectionID <\/b>in entsprechenden Variablen, bevor sie darauf basierend ein Recordset &ouml;ffnet. Dieses enth&auml;lt den Datensatz der Tabelle <b>tblNumberOfDataCodewords<\/b>, der den mit den Kombinationsfeldern ausgew&auml;hlten Parametern entspricht. Aus dieser Tabelle entnehmen wir einige Werte und speichern diese in weiteren Variablen:<\/p>\n<ul>\n<li><b>lngBlocksGruppe1<\/b><\/li>\n<li><b>lngWoerterGruppe1<\/b><\/li>\n<li><b>lngBlocksGruppe2<\/b><\/li>\n<li><b>lngWoerterGruppe2<\/b><\/li>\n<li><b>intAnzahlFehlerkorrekturWoerter<\/b><\/li>\n<\/ul>\n<p>Nun folgt der interessante, in diesem Teil der Beitragsreihe beschriebene Part: Die Umwandlung des bin&auml;ren Codes in einen sogenannten &#8222;interleaved&#8220; Code und das Ermitteln und Hinzuf&uuml;gen des Fehlerkorrekturcodes.<\/p>\n<p>Dies geschieht in folgenden Schritten:<\/p>\n<ul>\n<li>Vermischen des Codes zum &#8222;interleaved&#8220; Code mit der Funktion <b>InterleavedCode<\/b>,<\/li>\n<li>Ermitteln des Fehlerkorrekturcodes auf Basis des Ausgangscodes und Vermischen zum &#8222;interleaved&#8220; Fehlerkorrekturcode mit der Funktion <b>InterleavedErrorCode <\/b>und<\/li>\n<li>Zusammenf&uuml;gen der beiden Teile im Textfeld <b>txtQRCode<\/b>.<\/li>\n<\/ul>\n<p>Schauen wir uns nun an, wie diese Funktionen arbeiten.<\/p>\n<p><b>Code weiter bearbeiten<\/b><\/p>\n<p>Den Code aus dem Textfeld <b>txtCodeInhalt <\/b>beziehungsweise der Variablen <b>strCode <\/b>verwenden wir nun nicht einfach so als ersten Teil des QR-Codes. Stattdessen wird dieser erste Teil gegebenenfalls noch etwas durcheinandergew&uuml;rfelt &#8211; allerdings nach fest vorgegebenen Regeln. Dies geschieht allerdings nur ab einer gewissen L&auml;nge des Codes beziehungsweise wenn die einzelnen achtstelligen Bin&auml;rzahlen auf mehr als nur die erste Gruppe aufgeteilt werden &#8211; also wenn in der Tabelle <b>tbl-NumberOfDataCodewords <\/b>in der Spalte f&uuml;r die aktuelle Konfiguration (aus Version und Fehlerkorrektur) auch ein Wert in den Spalten <b>NumberOfBlocksInGroup2 <\/b>beziehungsweise <b>NumberOfDataCodewordsInGroup2Blocks <\/b>vorliegen. Dies ist zum Beispiel der Fall, wenn Sie die Version <b>5 <\/b>(37 x 37 Pixel) und den Fehlerkorrekturgrad <b>Q <\/b>w&auml;hlen. Dieser Code hat insgesamt 62 Codew&ouml;rter, wobei die erste Gruppe zwei Blocks mit je 15 Codew&ouml;rtern enth&auml;lt und die zweite Gruppe zwei Blocks mit je 16 Codew&ouml;rtern. Die Prozedur <b>InterleavedCode <\/b>aus Listing 2 erwartet drei Parameter:<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>InterleavedCode(ByVal strCode<span style=\"color:blue;\"> As String<\/span>, lngBlocksGruppe1<span style=\"color:blue;\"> As Long<\/span>, _\r\n     lngWoerterGruppe1<span style=\"color:blue;\"> As Long<\/span>, lngBlocksGruppe2<span style=\"color:blue;\"> As Long<\/span>, lngWoerterGruppe2<span style=\"color:blue;\"> As Long<\/span>)\r\n     <span style=\"color:blue;\">Dim <\/span>i<span style=\"color:blue;\"> As Integer<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>j<span style=\"color:blue;\"> As Integer<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strTempNeu<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strTemp<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>intCodewoerterMatrix()<span style=\"color:blue;\"> As Integer<\/span>\r\n     intCodewoerterMatrix = CodeWoerterMatrix(lngBlocksGruppe1, lngWoerterGruppe1, _\r\n         lngWoerterGruppe2, lngBlocksGruppe2)\r\n     strTemp = <span style=\"color:blue;\">Trim<\/span>(strCode)\r\n     <span style=\"color:blue;\">If <\/span>lngWoerterGruppe2 &lt;&gt; 0<span style=\"color:blue;\"> Then<\/span>\r\n         For j = 1 To lngWoerterGruppe2\r\n             For i = 1 To lngBlocksGruppe1 + lngBlocksGruppe2\r\n                 <span style=\"color:blue;\">If <\/span>intCodewoerterMatrix(i, j) &lt;&gt; 0<span style=\"color:blue;\"> Then<\/span>\r\n                     strTempNeu = strTempNeu + Mid$(strTemp, intCodewoerterMatrix(i, j) * 8 - 7, 8)\r\n                 <span style=\"color:blue;\">End If<\/span>\r\n              <span style=\"color:blue;\">Next<\/span> i\r\n         <span style=\"color:blue;\">Next<\/span> j\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">If <\/span>lngWoerterGruppe2 = 0<span style=\"color:blue;\"> Then<\/span>\r\n         For j = 1 To lngWoerterGruppe1\r\n             For i = 1 To lngBlocksGruppe1 + lngBlocksGruppe2\r\n                 <span style=\"color:blue;\">If <\/span>intCodewoerterMatrix(i, j) &lt;&gt; 0<span style=\"color:blue;\"> Then<\/span>\r\n                     strTempNeu = strTempNeu + Mid$(strTemp, intCodewoerterMatrix(i, j) * 8 - 7, 8)\r\n                 <span style=\"color:blue;\">End If<\/span>\r\n             <span style=\"color:blue;\">Next<\/span> i\r\n         <span style=\"color:blue;\">Next<\/span> j\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     InterleavedCode = strTempNeu\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><!--30percent--><\/p>\n<p><b><span style=\"color:darkgrey;\">Listing 2: &#8222;Vermischen&#8220; des Bin&auml;rcodes f&uuml;r den Ausgangstext<\/span><\/b><\/p>\n<ul>\n<li><b>strCode<\/b>: Code in bin&auml;rer Form<\/li>\n<li><b>lngBlocksGruppe1<\/b>: Anzahl der Bl&ouml;cke in der ersten Gruppe<\/li>\n<li><b>lngWoerterGruppe1<\/b>: Anzahl der Codew&ouml;rter in der ersten Gruppe<\/li>\n<li><b>lngBlocksGruppe2<\/b>: Anzahl der Bl&ouml;cke in der zweiten Gruppe (gegebenenfalls <b>0<\/b>)<\/li>\n<li><b>lngWoerterGruppe2<\/b>: Anzahl der Codew&ouml;rter in der zweiten Gruppe (gegebenenfalls <b>0<\/b>)<\/li>\n<\/ul>\n<p>Die hinteren vier Werte wurden von der aufrufenden Prozedur <b>cmdAktualisieren <\/b>aus der Tabelle <b>tblNumberOfDataCodewords <\/b>f&uuml;r die aktuelle Kombination aus Version und Fehlerkorrekturgrad ausgew&auml;hlt.<\/p>\n<p>Die Prozedur ruft zun&auml;chst eine weitere Routine auf, die eine wichtige Aufgabe beim Mischen der Codew&ouml;rter erf&uuml;llt &#8211; sie erstellt n&auml;mlich ein Array, aus dem sp&auml;ter die neue Reihenfolge f&uuml;r die Codew&ouml;rter entnommen wird. Diese Prozedur hei&szlig;t <b>CodeWoerterMatrix <\/b>und erwartet die soeben ermittelten vier Werte f&uuml;r die gleichnamigen Parameter <b>lngBlocksGruppe1<\/b>, <b>lngWoerterGruppe1<\/b>, <b>lngWoerterGruppe2 <\/b>und <b>lngBlocksGruppe2<\/b> (s. Listing 3).<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>CodeWoerterMatrix(lngBlocksGruppe1<span style=\"color:blue;\"> As Long<\/span>, lngWoerterGruppe1<span style=\"color:blue;\"> As Long<\/span>, _\r\n         lngWoerterGruppe2<span style=\"color:blue;\"> As Long<\/span>, lngBlocksGruppe2<span style=\"color:blue;\"> As Long<\/span>, strDataCodewords()<span style=\"color:blue;\"> As Variant<\/span>)\r\n     <span style=\"color:blue;\">Dim <\/span>i<span style=\"color:blue;\"> As Integer<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>j<span style=\"color:blue;\"> As Integer<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>intZaehler<span style=\"color:blue;\"> As Integer<\/span>\r\n     <span style=\"color:blue;\">If <\/span>lngWoerterGruppe2 &lt;&gt; 0<span style=\"color:blue;\"> Then<\/span>\r\n         ReDim strDataCodewords(1 To lngBlocksGruppe1 + lngBlocksGruppe2, 1 To lngWoerterGruppe2)\r\n         For j = 1 To lngWoerterGruppe2\r\n             For i = 1 To lngBlocksGruppe1 + lngBlocksGruppe2\r\n                 strDataCodewords(i, j) = 0\r\n             <span style=\"color:blue;\">Next<\/span> i\r\n         <span style=\"color:blue;\">Next<\/span> j\r\n         intZaehler = 1\r\n         For i = 1 To lngBlocksGruppe1\r\n             For j = 1 To lngWoerterGruppe1\r\n                 strDataCodewords(i, j) = intZaehler\r\n                 intZaehler = intZaehler + 1\r\n             <span style=\"color:blue;\">Next<\/span> j\r\n         <span style=\"color:blue;\">Next<\/span> i\r\n         For i = lngBlocksGruppe1 + 1 To lngBlocksGruppe1 + lngBlocksGruppe2\r\n             For j = 1 To lngWoerterGruppe2\r\n                 strDataCodewords(i, j) = intZaehler\r\n                 intZaehler = intZaehler + 1\r\n             <span style=\"color:blue;\">Next<\/span> j\r\n         <span style=\"color:blue;\">Next<\/span> i\r\n     <span style=\"color:blue;\">Else<\/span>\r\n         ReDim strDataCodewords(1 To lngBlocksGruppe1 + lngBlocksGruppe2, 1 To lngWoerterGruppe1)\r\n         For j = 1 To lngWoerterGruppe1\r\n             For i = 1 To lngBlocksGruppe1\r\n                 strDataCodewords(i, j) = 0\r\n             <span style=\"color:blue;\">Next<\/span> i\r\n         <span style=\"color:blue;\">Next<\/span> j\r\n         intZaehler = 1\r\n         For i = 1 To lngBlocksGruppe1\r\n             For j = 1 To lngWoerterGruppe1\r\n                 strDataCodewords(i, j) = intZaehler\r\n                 intZaehler = intZaehler + 1\r\n             <span style=\"color:blue;\">Next<\/span> j\r\n         <span style=\"color:blue;\">Next<\/span> i\r\n     <span style=\"color:blue;\">End If<\/span>\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 3: Hilfsfunktion zum vermischen der Codew&ouml;rter<\/span><\/b><\/p>\n<p>Wenn die zweite Gruppe aus der Tabelle <b>tblNumberOfDataCodewords <\/b>mindestens einen Block enth&auml;lt, ist der erste Teil der <b>If&#8230;Then<\/b>-Bedingung der Prozedur <b>CodeWoerterMatrix <\/b>erf&uuml;llt. Dieser Teil f&uuml;llt nun beispielsweise die laufenden Nummern (im Falle von Version <b>5<\/b>, Fehlerkorrekturlevel <b>Q <\/b>von <b>1 <\/b>bis <b>62<\/b>) in ein zweidimensionales Array namens <b>intCodewoerterMatrix()<\/b>. Dieses wird zuvor mit der <b>ReDim<\/b>-Anweisung mit dem Bereich <b>1<\/b> bis <b>2 + 2 <\/b>f&uuml;r die erste Dimension und dem Bereich <b>1 <\/b>bis <b>16 <\/b>f&uuml;r die zweite Dimension dimensioniert. Die Zahlen werden dann einfach wie folgt eingetragen &#8211; also in vier Zeilen und 16 Spalten wie in der folgenden schematischen Darstellung:<\/p>\n<pre>1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 \r\n16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 0\r\n31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46\r\n47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62<\/pre>\n<p>Zuvor wird das Array noch komplett mit Nullen gef&uuml;llt. Sollte die Tabelle <b>tblNumberOfDataCodewords<\/b> keinen einzigen Block in der Zeile <b>NumberOfBlocksInGroup2 <\/b>f&uuml;r die gew&auml;hlte Konfiguration aus Version und Fehlerkorrekturgrad liefern, f&uuml;hrt die Prozedur <b>CodeWoerterMatrix <\/b>den zweiten Teil der <b>If&#8230;Then<\/b>-Bedingung aus. In diesem Fall legt die Prozedur nur f&uuml;r die Elemente der ersten Gruppe die laufenden Nummern der Codew&ouml;rter an. In unserem einfachen Beispiel von oben sieht dies so aus &#8211; also nur mit einer Zeile und 16 Spalten:<\/p>\n<pre>1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16<\/pre>\n<p>Das entsprechende Array <b>intCodewoerterMatrix() <\/b>wird nun als R&uuml;ckgabewertan die aufrufende Prozedur zur&uuml;ckgegeben. Diese speichert nun zun&auml;chst den Code aus dem Parameter <b>strCode <\/b>in der Variablen <b>strTemp<\/b>. Wenn die aktuelle Konfiguration W&ouml;rter in der zweiten Gruppe hergibt, werden die Anweisungen in der ersten <b>If&#8230;Then<\/b>-Bedingung ausgef&uuml;hrt. Hier werden zwei <b>For&#8230;Next<\/b>-Schleifen durchlaufen, die &auml;u&szlig;ere &uuml;ber die Anzahl der W&ouml;rter der zweiten Gruppe (hier 16), die innere die Anzahl der Blocks der ersten Gruppe plus die der zweiten Gruppe (hier <b>2 + 2<\/b>). Sollte das Array <b>intCodewoerterMatrix <\/b>f&uuml;r die Laufvariablen <b>i <\/b>und <b>j <\/b>einen Wert ungleich <b>0 <\/b>enthalten, beginnt die Prozedur mit dem Erstellen einer neuen Code-Zeichenkette in der Variablen <b>strTempNeu<\/b>. Dabei wird jeweils der Teil bestehend aus acht Zeichen aus <b>strTemp <\/b>eingelesen und an <b>strTempNeu <\/b>angeh&auml;ngt, welcher der laufenden Nummer des Elements von <b>intCodewoerterMatrix() <\/b>mit den Werten f&uuml;r <b>i <\/b>und <b>j <\/b>entspricht.<\/p>\n<p>Das hei&szlig;t, dass das Array nun nicht zun&auml;chst spalten- und dann zeilenweise durchlaufen wird (also 1, 2, 3 und so weiter), sondern erst zeilen- und dann spaltenweise. Die Reihenfolge der neu zusammengesetzten Elemente lautet also:<\/p>\n<p><b>1<\/b>, <b>16<\/b>, <b>31<\/b>, <b>47<\/b>, <b>2<\/b>, <b>17<\/b>, <b>32<\/b>, <b>48<\/b>, <b>3<\/b>, <b>18<\/b>, <b>33<\/b>, <b>49<\/b>, <b>4<\/b>, <b>19<\/b>, <b>34<\/b>, <b>50<\/b>, <b>5<\/b>, <b>20<\/b>, <b>35<\/b>, <b>51<\/b>, <b>6<\/b>, <b>21<\/b>, <b>36<\/b>, <b>52<\/b>, <b>7<\/b>, <b>22<\/b>, <b>37<\/b>, <b>53<\/b>, <b>8<\/b>, <b>23<\/b>, <b>38<\/b>, <b>54<\/b>, <b>9<\/b>, <b>24<\/b>, <b>39<\/b>, <b>55<\/b>, <b>10<\/b>, <b>25<\/b>, <b>40<\/b>, <b>56<\/b>, <b>11<\/b>, <b>26<\/b>, <b>41<\/b>, <b>57<\/b>, <b>12<\/b>, <b>27<\/b>, <b>42<\/b>, <b>58<\/b>, <b>13<\/b>, <b>28<\/b>, <b>43<\/b>, <b>59<\/b>, <b>14<\/b>, <b>29<\/b>, <b>44<\/b>, <b>60<\/b>, <b>15<\/b>, <b>30<\/b>, <b>45<\/b>, <b>61<\/b>, <b>46<\/b>, <b>62<\/b>.<\/p>\n<p>Sprich: Der Ausdruck in <b>strTempNeu <\/b>beginnt mit dem ersten Codewort aus <b>strTemp<\/b>, dann folgt das 16. Codewort, dann das 31. und so weiter.<\/p>\n<p>Sollte die zweite Gruppe keinen einzigen Block enthalten, durchl&auml;uft die Prozedur wiederum in zwei Schleifen die Werte des Arrays <b>intCodewoerterMatrix()<\/b>. Wenn <b>intCodewoerterMatrix <\/b>an dieser Stelle nur eine Zeile mit Daten enth&auml;lt, ist <b>strTempNeu <\/b>gleich der mit <b>strCode <\/b>&uuml;bergebenen Zeichenkette. Das Ergebnis wird dann als Ergebnis der Funktion <b>InterleavedCode <\/b>an die aufrufende Routine zur&uuml;ckgeliefert.<\/p>\n<p><b>Fehlerkorrekturcode ermitteln<\/b><\/p>\n<p>Der Fehlerkorrekturcode wird nach einer recht komplizierten Vorgehensweise erstellt. Daf&uuml;r ben&ouml;tigen wir zwei Polynome &#8211; eines f&uuml;r den zu verschl&uuml;sselnden Text und ein sogenanntes &#8222;generator polynomial&#8220;.<\/p>\n<p>Das Polynom f&uuml;r den zu verschl&uuml;sselnden Text erzeugen wir auf Basis der oben ermittelten Codew&ouml;rter.<\/p>\n<p>Ausgangspunkt f&uuml;r die Erstellung des Fehlerkorrekturcodes ist die Funktion <b>InterleavedErrorCode<\/b> aus Listing 4. Sie erwartet die gleichen Parameter wie die oben beschriebene Funktion <b>InterleavedCode <\/b>&#8211; plus einen weiteren, n&auml;mlich <b>intAnzahlFehlerkorrekturwoerter<\/b>. Dies ist ein weiterer Wert, der bereits in <b>cmdAktualisieren_Click <\/b>f&uuml;r die aktuelle Konfiguration aus Version und Fehlerkorrekturgrad aus der Tabelle <b>tblNumberOfDataCodewords <\/b>ermittelt wurde &#8211; und zwar aus dem Feld <b>ECCodewordsPerBlock<\/b>. Dieser Wert gibt an, wie viele bin&auml;re W&ouml;rter aus acht Zeichen noch an die bereits ermittelte Zeichenkette angeh&auml;ngt werden m&uuml;ssen, um den Code f&uuml;r den QR-Code zu vervollst&auml;ndigen. Das Verh&auml;ltnis der Anzahl der Fehlerkorrekturw&ouml;rter zu den Codew&ouml;rtern steigt mit wachsendem Fehlerkorrekturgrad.<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>InterleavedErrorCode(ByVal strCode<span style=\"color:blue;\"> As String<\/span>, lngBlocksGruppe1<span style=\"color:blue;\"> As Long<\/span>, _\r\n         lngWoerterGruppe1<span style=\"color:blue;\"> As Long<\/span>, lngBlocksGruppe2<span style=\"color:blue;\"> As Long<\/span>, lngWoerterGruppe2<span style=\"color:blue;\"> As Long<\/span>, _\r\n         intAnzahlFehlerkorrekturWoerter<span style=\"color:blue;\"> As Integer<\/span>)\r\n     <span style=\"color:blue;\">Dim <\/span>i<span style=\"color:blue;\"> As Integer<\/span>, j<span style=\"color:blue;\"> As Integer<\/span>, intStart<span style=\"color:blue;\"> As Integer<\/span>, intEnde<span style=\"color:blue;\"> As Integer<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>intMessagePolynomial()<span style=\"color:blue;\"> As Integer<\/span>, intAnzahlKoeffizientenMessage<span style=\"color:blue;\"> As Integer<\/span>, intBlock<span style=\"color:blue;\"> As Integer<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strTemp<span style=\"color:blue;\"> As String<\/span>, strCodeTeil<span style=\"color:blue;\"> As String<\/span>, strTempInterleaved<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>intFehlerwoerterMatrix()<span style=\"color:blue;\"> As Variant<\/span>, intCodeTeil<span style=\"color:blue;\"> As Integer<\/span>\r\n     intFehlerwoerterMatrix() = FehlerwoerterMatrix(lngBlocksGruppe1, lngBlocksGruppe2, _\r\n         intAnzahlFehlerkorrekturWoerter)\r\n     intStart = 1\r\n     intEnde = lngWoerterGruppe1 * 8\r\n     intBlock = 0\r\n     Do\r\n         intAnzahlKoeffizientenMessage = 1\r\n         <span style=\"color:blue;\">If <\/span>intBlock &lt; lngBlocksGruppe1<span style=\"color:blue;\"> Then<\/span>\r\n             For i = intStart To intEnde Step 8\r\n                 strCodeTeil = Mid$(strCode, i, 8)\r\n                 intCodeTeil = BinaerZuDezimal(strCodeTeil)\r\n                 ReDim Preserve intMessagePolynomial(intAnzahlKoeffizientenMessage)<span style=\"color:blue;\"> As Integer<\/span>\r\n                 intMessagePolynomial(intAnzahlKoeffizientenMessage) = intCodeTeil\r\n                 intAnzahlKoeffizientenMessage = intAnzahlKoeffizientenMessage + 1\r\n             <span style=\"color:blue;\">Next<\/span> i\r\n             intStart = intEnde + 1\r\n             <span style=\"color:blue;\">If <\/span>intBlock = lngBlocksGruppe1 - 1<span style=\"color:blue;\"> Then<\/span>\r\n                 intEnde = intEnde + lngWoerterGruppe2 * 8\r\n             <span style=\"color:blue;\">Else<\/span>\r\n                 intEnde = intEnde + lngWoerterGruppe1 * 8\r\n             <span style=\"color:blue;\">End If<\/span>\r\n         <span style=\"color:blue;\">End If<\/span>\r\n         <span style=\"color:blue;\">If <\/span>intBlock &gt;= lngBlocksGruppe1<span style=\"color:blue;\"> Then<\/span>\r\n             For i = intStart To intEnde Step 8\r\n                 strCodeTeil = Mid$(strCode, i, 8)\r\n                 intCodeTeil = BinaerZuDezimal(strCodeTeil)\r\n                 ReDim Preserve intMessagePolynomial(intAnzahlKoeffizientenMessage)<span style=\"color:blue;\"> As Integer<\/span>\r\n                 intMessagePolynomial(intAnzahlKoeffizientenMessage) = intCodeTeil\r\n                 intAnzahlKoeffizientenMessage = intAnzahlKoeffizientenMessage + 1\r\n             <span style=\"color:blue;\">Next<\/span> i\r\n             intStart = intEnde + 1\r\n             intEnde = intEnde + lngWoerterGruppe2 * 8\r\n         <span style=\"color:blue;\">End If<\/span>\r\n     ...<\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 4: Erstellen des Fehlerkorrekturcodes (Teil I)<\/span><\/b><\/p>\n<p>Die Prozedur ermittelt zun&auml;chst &uuml;ber die Funktion <b>FehlerwoerterMatrix <\/b>ein &auml;hnliches Array wie zuvor die Funktion <b>CodewoerterMatrix<\/b>. Diese liefert wieder die Grundlage f&uuml;r die sp&auml;ter zu verwendende Reihenfolge f&uuml;r das Durchmischen des Fehlerkorrekturcodes, um den &#8222;interleaved&#8220; Code zu erhalten. Das Ergebnis speichert die Prozedur in der Variablen <b>intFehlerwoerterMatrix()<\/b>.<\/p>\n<p>Die Funktion <b>FehlerwoerterMatrix <\/b>finden Sie in Listing 5. Sie erwartet die Anzahl der Bl&ouml;cke in Gruppe 1 und Grupp2 (<b>lngBlocksGruppe1 <\/b>und <b>lngBlocksGruppe2<\/b>) sowie die Anzahl der Fehlerkorrekturw&ouml;rter (<b>intAnzahlFehlerkorrekturwoerter<\/b>).<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>FehlerwoerterMatrix(lngBlocksGruppe1<span style=\"color:blue;\"> As Long<\/span>, lngBlocksGruppe2<span style=\"color:blue;\"> As Long<\/span>, _\r\n         intAnzahlFehlerkorrekturWoerter<span style=\"color:blue;\"> As Integer<\/span>)<span style=\"color:blue;\"> As Integer<\/span>()\r\n     <span style=\"color:blue;\">Dim <\/span>i<span style=\"color:blue;\"> As Integer<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>j<span style=\"color:blue;\"> As Integer<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>intTemp()<span style=\"color:blue;\"> As Integer<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>intZaehler<span style=\"color:blue;\"> As Integer<\/span>\r\n     ReDim intTemp(1 To lngBlocksGruppe1 + lngBlocksGruppe2, intAnzahlFehlerkorrekturWoerter)\r\n     For j = 1 To intAnzahlFehlerkorrekturWoerter\r\n         For i = 1 To lngBlocksGruppe1 + lngBlocksGruppe2\r\n             intTemp(i, j) = 0\r\n         <span style=\"color:blue;\">Next<\/span> i\r\n     <span style=\"color:blue;\">Next<\/span> j\r\n     intZaehler = 1\r\n     For i = 1 To lngBlocksGruppe1 + lngBlocksGruppe2\r\n         For j = 1 To intAnzahlFehlerkorrekturWoerter\r\n             intTemp(i, j) = intZaehler\r\n             intZaehler = intZaehler + 1\r\n         <span style=\"color:blue;\">Next<\/span> j\r\n     <span style=\"color:blue;\">Next<\/span> i\r\n     FehlerwoerterMatrix = intTemp\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 5: Zusammenstellen der Matrix f&uuml;r die Anordnung die W&ouml;rter im Fehlerkorrekturcode<\/span><\/b><\/p>\n<p>Das <b>Integer<\/b>-Array <b>intTemp <\/b>nimmt die Werte auf. Dazu wird es mit der <b>ReDim<\/b>-Anweisung vordimensioniert, und zwar in der ersten Dimension f&uuml;r die Summe der Bl&ouml;cke der beiden Gruppen und in der zweiten Dimension f&uuml;r die Anzahl der Fehlerkorrekturw&ouml;rter.<\/p>\n<p>Dann durchl&auml;uft eine erste &auml;u&szlig;ere Schleife alle Werte von <b>1 <\/b>bis zur Anzahl der Fehlerkorrekturw&ouml;rter (<b>intAnzahlFehlerkorrekturwoerter<\/b>) und eine innere Schleife die Werte von <b>1 <\/b>bis zur Summe von <b>lngBlocksGruppe1 <\/b>und <b>lngBlocksGruppe2<\/b>. Innerhalb der beiden verschachtelten Schleifen wird das Array <b>intTemp <\/b>f&uuml;r die aktuellen Laufvariablen <b>i <\/b>und <b>j <\/b>mit dem Wert <b>0 <\/b>gef&uuml;llt.<\/p>\n<p>In der zweiten Schleife folgen dann die tats&auml;chlichen Werte. Dazu verwenden wir wieder eine Z&auml;hlervariable namens <b>intZaehler<\/b>, die mit dem Wert <b>1 <\/b>beginnt und bei jedem Schleifendurchlauf der inneren Schleife um <b>1 <\/b>erh&ouml;ht wird. Die <b>For&#8230;Next<\/b>-Anweisungen sehen genauso aus wie beim F&uuml;llen des Array mit Nullen. Innerhalb der Schleife schreibt eine Anweisung jeweils den Wert von <b>intZaehler <\/b>in das aktuelle durch <b>i <\/b>und <b>j <\/b>gekennzeichnete Feld des Arrays <b>intTemp<\/b>. Dieses Array wird dann schlie&szlig;lich als Funktionswert an die aufrufende Variable zur&uuml;ckgegeben.<\/p>\n<p>Nun beginnt die eigentliche Arbeit. Wir schauen uns dies am bereits oben erw&auml;hnten einfachen Beispiel des Textes <b>HELLO WORLD <\/b>an, wobei wir die Version <b>1 <\/b>verwenden (21 x 21 Pixel) und den Fehlerkorrekturlevel <b>M<\/b>. Das Ziel der Aktion ist, zwei Polynome zu ermitteln und diese durcheinander zu teilen.<\/p>\n<p>Das ist nicht unkompliziert und erfordert Rechenschritte, die Otto Normalverbraucher wohl nicht aus dem &auml;rmel sch&uuml;ttelt (der Autor schlie&szlig;t sich hier nicht aus &#8230;). Das Ergebnis ist dann wiederum ein Polynom, dessen Koeffizienten die Hauptrolle beim Zusammenstellen des Fehlerkorrekturcodes spielen.<\/p>\n<p>Zur Auffrischung der mathematischen Kenntnisse &#8211; ein Polynom sieht etwa so aus:<\/p>\n<p>a0 + a1x + a2x2 + &#8230; + an-1xn-1 + anxn<\/p>\n<p><b>Polynom f&uuml;r den Text ermitteln<\/b><\/p>\n<p>Die Ermittlung des Polynoms f&uuml;r den Text ist relativ einfach. Als Grundlage dient der Bin&auml;rcode, den wir f&uuml;r den Text ermittelt haben &#8211; inklusive der zw&ouml;lf Zeichen, welche die Codierungsmethode und die  Anzahl der Zeichen beschreiben und teilen diesen auf jeweils acht Zeichen auf. Dies sieht dann so aus:<\/p>\n<ul>\n<li>00100000 = 32<\/li>\n<li>01011011 = 91<\/li>\n<li>00001011 = 11<\/li>\n<li>01111000 = 120<\/li>\n<li>11010001 = 209<\/li>\n<li>01110010= 114<\/li>\n<li>11011100 = 220<\/li>\n<li>01001101 = 77<\/li>\n<li>01000011 = 67<\/li>\n<li>01000000 = 64<\/li>\n<li>11101100 = 236<\/li>\n<li>00010001 = 17<\/li>\n<li>11101100 = 236<\/li>\n<li>00010001 = 17<\/li>\n<li>11101100 = 236<\/li>\n<li>00010001 = 17<\/li>\n<\/ul>\n<p>Die entsprechenden Zahlenwerte, also 32, 91, 11 und so weiter liefern dabei die Koeffizienten f&uuml;r unser erstes Polynom, dass wie folgt aussieht:<\/p>\n<p>32&#215;15 + 91&#215;14 + 11&#215;13 + 120&#215;12 + 209&#215;11 + 114&#215;10 + 220&#215;9 + 77&#215;8 + 67&#215;7 + 64&#215;6 + 236&#215;5 + 17&#215;4 + 236&#215;3 + 17&#215;2 + 236&#215;1 + 17x <\/p>\n<p><b>Polynom f&uuml;r den Fehlercode<\/b><\/p>\n<p>Das zweite Polynom l&auml;sst sich ebenso einfach ermitteln. Das hei&szlig;t: Eigentlich ist es nicht ganz so einfach. Aber zum Gl&uuml;ck gibt es fertige Tabellen, die wir schnell in unsere Beispieldatenbank &uuml;bertragen konnten und die uns die ben&ouml;tigten Informationen liefern. In diesem Fall hei&szlig;t die Tabelle <b>tblGeneratorPolynomical <\/b>aus Bild 4 (siehe ).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2014_04\/pic_947_004.png\" alt=\"Diese Tabelle liefert die Koeffizienten f&uuml;r das zweite Polynom.\" width=\"575\" height=\"471,0505\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 4: Diese Tabelle liefert die Koeffizienten f&uuml;r das zweite Polynom.<\/span><\/b><\/p>\n<p>Die Spalte <b>ECCodewordsPerBlock <\/b>gibt die ben&ouml;tigte Anzahl der Koeffizienten an, die in der Prozedur <b>InterleavedErrorCode <\/b>mit dem Parameter <b>intAnzahlFehlerkorrekturWoerter <\/b>&uuml;bergeben wurde &#8211; in diesem Fall <b>10<\/b>.<\/p>\n<p>Nun ben&ouml;tigen wir nur noch die Exponenten f&uuml;r dieses Polynom, die wir der Tabelle entnehmen k&ouml;nnen. Das Feld <b>Alphakoeffizient <\/b>liefert den Exponenten f&uuml;r den Koffezient, das Feld <b>XKoeffizient <\/b>den Exponent f&uuml;r <b>x<\/b>. Damit erhalten wir f&uuml;r den Start dieses Polynom:<\/p>\n<p>a0x10 + a1x9 + a216x8 + a194x7 + a159x6 + a111x5 + a199x4 + a94x3 + a95x2 + a113x1 + a157x + a193x<\/p>\n<p>Nun werden noch einige Operationen an diesem Polynom durchgef&uuml;hrt &#8211; Stichworte sind <b>Galois Field<\/b>, <b>Logs <\/b>und <b>Antilogs <\/b>&#8211; mehr dazu im Dokument aus .<\/p>\n<p>Tatsache ist: Die Division der beiden Polynome liefert ein neues Polynom, dessen Koeffizienten wiederum Zahlen von 1 bis 255 enthalten &#8211; und zwar genauso viele, wie im Feld <b>ECCodewordsPerBlock<\/b> der Tabelle <b>tbl-NumberOfDataCodewords <\/b>f&uuml;r unsere Kombination aus Version und Fehlerkorrekturgrad angegeben wurden (in diesem Fall <b>10<\/b>).<\/p>\n<p>Zur&uuml;ck zur Prozedur <b>InterleavedErrorCode<\/b>: Diese durchl&auml;uft eine <b>Do&#8230;Loop Until<\/b>-Schleife solange, bis die Laufvariable <b>intBlock <\/b>der Anzahl der Bl&ouml;cke aus Gruppe 1 und Gruppe 2 entspricht. Darin stellt sie zun&auml;chst in <b>intMessagePolynomial<\/b> ein Array zusammen, das die Koeffizienten f&uuml;r das Polynom f&uuml;r den zu codierenden Text enth&auml;lt &#8211; hier beispielsweise so:<\/p>\n<p>0  32  91  11  120  209  114  220  77  67  64  236  17  236  17  236  17<\/p>\n<p>Danach folgt eine Schleife, welche die Exponenten f&uuml;r die jeweiligen Elemente des Polynoms zusammenstellt:<\/p>\n<pre>0  25  24  23  22  21  20  19  18  17  16  15  14  13  12  11  10 <\/pre>\n<p>Dies sind die Daten, die das bereits oben beispielhaft dargestellte Polynom ergeben &#8211; allerdings mit um den Wert aus <b>intAnzahlFehlerkorrekturWoerter <\/b>(hier <b>10<\/b>) erh&ouml;htem Exponent, was mit der folgenden Division der beiden Polynome zu tun hat:<\/p>\n<p>32&#215;25 + 91&#215;24 + 11&#215;23 + 120&#215;22 + 209&#215;21 + 114&#215;20 + 220&#215;19 + 77&#215;18 + 67&#215;17 + 64&#215;16 + 236&#215;15 + 17&#215;14 + 236&#215;13 + 17&#215;12 + 236&#215;11 + 17&#215;10<\/p>\n<p>Mit einigen der in der Schleife ermittelten Daten, unter anderem dem Array mit dem Koeffizienten f&uuml;r das Code-Polynom, geht es nun in die Funktion Fehlerkorrekturcode. Dort erfolgt nun die Division der beiden Polynome, was in der R&uuml;ckgabe des Fehlerkorrekturstrings f&uuml;r den aktuell in der Schleife durchlaufenen Codeblock mit der Variablen <b>strTemp <\/b>m&uuml;ndet. In die Tiefen dieser recht komplizierten Funktion wollen wir an dieser Stelle nicht gehen.<\/p>\n<p><b>strTemp <\/b>hat f&uuml;r unser Beispiel folgenden Inhalt:<\/p>\n<pre>001111000011001011001110100101110111011000010101111110111011000100101100100011101001011010100010101100111000001010011010010100111100001111010110<\/pre>\n<p>Wichtig ist, dass der String der vorgegebenen L&auml;nge von 10 W&ouml;rtern entspricht, also 10 x 8 Zeichen.<\/p>\n<p>F&uuml;r komplexere Ausgangstexte und andere Codierungen und Fehlerkorrekturgrade wird die <b>Do&#8230;Loop Until<\/b>-Schleife nicht nur einmal durchlaufen, sondern entsprechend der Anzahl der Codebl&ouml;cke.<\/p>\n<p>Nun muss der Fehlerkorrekturcode nur noch gemischt werden, was in zwei weiteren, verschachtelten <b>For&#8230;Next<\/b>-Schleifen geschieht. Das Ergebnis wird schlie&szlig;lich als Funktionswert an die aufrufende Routine zur&uuml;ckgegeben.<\/p>\n<p>Weiter in die Materie einzusteigen ist nicht sinnvoll, da es kaum Grund f&uuml;r Anpassungen gibt &#8211; und wer dies dennoch tun m&ouml;chte, mag sich anhand des Codes und der Dokumentation aus  selbst heranwagen. F&uuml;r den hier verwendeten Code wurde &uuml;brigens ein Excel-Beispiel von Johan Schoemann verwendet.<\/p>\n<p><b>Zusammenfassung und Ausblick<\/b><\/p>\n<p>Damit w&auml;re der Code f&uuml;r den QR-Code vollst&auml;ndig &#8211; es fehlt nun nur noch die Umsetzung in Form der entsprechenden Grafik. Dies sehen wir uns im dritten und letzten Teil der Beitragsreihe an.<\/p>\n<p> http:\/\/www.thonky.com\/qr-code-tutorial\/<\/p>\n<h3>Downloads zu diesem Beitrag<\/h3>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>QRCodesII.mdb<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/{09AFA2D2-3D19-4AC2-9942-9BF30AABBA77}\/aiu_947.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Im ersten Teil dieser Beitragsreihe haben wir bereits den Ausdruck codiert, der sp&auml;ter in Form eines QR-Codes grafisch abgebildet werden soll. Der weitaus interessantere Teil folgt noch: Die Berechnung des Fehlerkorrekturcodes. Schlie&szlig;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&ouml;nnen.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[662014,66042014,44000027],"tags":[],"class_list":["post-55000947","post","type-post","status-publish","format-standard","hentry","category-662014","category-66042014","category-Loesungen"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.9 (Yoast SEO v27.3) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>QR-Codes mit Access erzeugen, Teil II - Access im Unternehmen<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/access-im-unternehmen.de\/QRCodes_mit_Access_erzeugen_Teil_II\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"QR-Codes mit Access erzeugen, Teil II\" \/>\n<meta property=\"og:description\" content=\"Im ersten Teil dieser Beitragsreihe haben wir bereits den Ausdruck codiert, der sp&auml;ter in Form eines QR-Codes grafisch abgebildet werden soll. Der weitaus interessantere Teil folgt noch: Die Berechnung des Fehlerkorrekturcodes. Schlie&szlig;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&ouml;nnen.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/QRCodes_mit_Access_erzeugen_Teil_II\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2020-05-22T21:12:12+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/vg07.met.vgwort.de\/na\/7a0acd8a80064cbe9ea3127de6d44785\" \/>\n<meta name=\"author\" content=\"Andr\u00e9 Minhorst\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Verfasst von\" \/>\n\t<meta name=\"twitter:data1\" content=\"Andr\u00e9 Minhorst\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"18\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/QRCodes_mit_Access_erzeugen_Teil_II\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/QRCodes_mit_Access_erzeugen_Teil_II\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"QR-Codes mit Access erzeugen, Teil II\",\"datePublished\":\"2020-05-22T21:12:12+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/QRCodes_mit_Access_erzeugen_Teil_II\\\/\"},\"wordCount\":2966,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/QRCodes_mit_Access_erzeugen_Teil_II\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg07.met.vgwort.de\\\/na\\\/7a0acd8a80064cbe9ea3127de6d44785\",\"articleSection\":[\"2014\",\"4\\\/2014\",\"L\u00f6sungen\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/QRCodes_mit_Access_erzeugen_Teil_II\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/QRCodes_mit_Access_erzeugen_Teil_II\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/QRCodes_mit_Access_erzeugen_Teil_II\\\/\",\"name\":\"QR-Codes mit Access erzeugen, Teil II - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/QRCodes_mit_Access_erzeugen_Teil_II\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/QRCodes_mit_Access_erzeugen_Teil_II\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg07.met.vgwort.de\\\/na\\\/7a0acd8a80064cbe9ea3127de6d44785\",\"datePublished\":\"2020-05-22T21:12:12+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/QRCodes_mit_Access_erzeugen_Teil_II\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/QRCodes_mit_Access_erzeugen_Teil_II\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/QRCodes_mit_Access_erzeugen_Teil_II\\\/#primaryimage\",\"url\":\"http:\\\/\\\/vg07.met.vgwort.de\\\/na\\\/7a0acd8a80064cbe9ea3127de6d44785\",\"contentUrl\":\"http:\\\/\\\/vg07.met.vgwort.de\\\/na\\\/7a0acd8a80064cbe9ea3127de6d44785\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/QRCodes_mit_Access_erzeugen_Teil_II\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"QR-Codes mit Access erzeugen, Teil II\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"name\":\"Access im Unternehmen\",\"description\":\"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access\",\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/access-im-unternehmen.de\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\",\"name\":\"Andr\u00e9 Minhorst Verlag\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"contentUrl\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"width\":370,\"height\":111,\"caption\":\"Andr\u00e9 Minhorst Verlag\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\",\"name\":\"Andr\u00e9 Minhorst\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"caption\":\"Andr\u00e9 Minhorst\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"QR-Codes mit Access erzeugen, Teil II - Access im Unternehmen","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/access-im-unternehmen.de\/QRCodes_mit_Access_erzeugen_Teil_II\/","og_locale":"de_DE","og_type":"article","og_title":"QR-Codes mit Access erzeugen, Teil II","og_description":"Im ersten Teil dieser Beitragsreihe haben wir bereits den Ausdruck codiert, der sp&auml;ter in Form eines QR-Codes grafisch abgebildet werden soll. Der weitaus interessantere Teil folgt noch: Die Berechnung des Fehlerkorrekturcodes. Schlie&szlig;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&ouml;nnen.","og_url":"https:\/\/access-im-unternehmen.de\/QRCodes_mit_Access_erzeugen_Teil_II\/","og_site_name":"Access im Unternehmen","article_published_time":"2020-05-22T21:12:12+00:00","og_image":[{"url":"http:\/\/vg07.met.vgwort.de\/na\/7a0acd8a80064cbe9ea3127de6d44785","type":"","width":"","height":""}],"author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"18\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/QRCodes_mit_Access_erzeugen_Teil_II\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/QRCodes_mit_Access_erzeugen_Teil_II\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"QR-Codes mit Access erzeugen, Teil II","datePublished":"2020-05-22T21:12:12+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/QRCodes_mit_Access_erzeugen_Teil_II\/"},"wordCount":2966,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/QRCodes_mit_Access_erzeugen_Teil_II\/#primaryimage"},"thumbnailUrl":"http:\/\/vg07.met.vgwort.de\/na\/7a0acd8a80064cbe9ea3127de6d44785","articleSection":["2014","4\/2014","L\u00f6sungen"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/QRCodes_mit_Access_erzeugen_Teil_II\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/QRCodes_mit_Access_erzeugen_Teil_II\/","url":"https:\/\/access-im-unternehmen.de\/QRCodes_mit_Access_erzeugen_Teil_II\/","name":"QR-Codes mit Access erzeugen, Teil II - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/QRCodes_mit_Access_erzeugen_Teil_II\/#primaryimage"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/QRCodes_mit_Access_erzeugen_Teil_II\/#primaryimage"},"thumbnailUrl":"http:\/\/vg07.met.vgwort.de\/na\/7a0acd8a80064cbe9ea3127de6d44785","datePublished":"2020-05-22T21:12:12+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/QRCodes_mit_Access_erzeugen_Teil_II\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/QRCodes_mit_Access_erzeugen_Teil_II\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/QRCodes_mit_Access_erzeugen_Teil_II\/#primaryimage","url":"http:\/\/vg07.met.vgwort.de\/na\/7a0acd8a80064cbe9ea3127de6d44785","contentUrl":"http:\/\/vg07.met.vgwort.de\/na\/7a0acd8a80064cbe9ea3127de6d44785"},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/QRCodes_mit_Access_erzeugen_Teil_II\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"QR-Codes mit Access erzeugen, Teil II"}]},{"@type":"WebSite","@id":"https:\/\/access-im-unternehmen.de\/#website","url":"https:\/\/access-im-unternehmen.de\/","name":"Access im Unternehmen","description":"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access","publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/access-im-unternehmen.de\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Organization","@id":"https:\/\/access-im-unternehmen.de\/#organization","name":"Andr\u00e9 Minhorst Verlag","url":"https:\/\/access-im-unternehmen.de\/","logo":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/","url":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","contentUrl":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","width":370,"height":111,"caption":"Andr\u00e9 Minhorst Verlag"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f","name":"Andr\u00e9 Minhorst","image":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","caption":"Andr\u00e9 Minhorst"}}]}},"_links":{"self":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55000947","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/comments?post=55000947"}],"version-history":[{"count":0,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55000947\/revisions"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55000947"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55000947"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55000947"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}