{"id":55000955,"date":"2014-10-01T00:00:00","date_gmt":"2022-03-30T17:32:17","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=955"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"QRCodes_mit_Access_erzeugen_Teil_III","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/QRCodes_mit_Access_erzeugen_Teil_III\/","title":{"rendered":"QR-Codes mit Access erzeugen, Teil III"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg07.met.vgwort.de\/na\/b0f848c8c23b4d28a2ca5b9348d8713d\" width=\"1\" height=\"1\" alt=\"\"><\/p>\n<p><b>Im dritten und letzten Teil der Beitragsreihe zum Thema QR-Codes wollen wir den in den ersten beiden Teilen ermittelten Code zusammen mit den ben&ouml;tigten Markierungen in eine Bilddatei gie&szlig;en und den dabei eingeschlagenen Weg zur besseren Nachvollziehbarkeit Schritt f&uuml;r Schritt in einer Excel-Datei darstellen. Die entstandenen Bilder k&ouml;nnen Sie dann entweder als Bilddatei speichern oder aber direkt in Formularen und Berichten einsetzen.<\/b><\/p>\n<p><b>Der Start<\/b><\/p>\n<p>Die Erstellung der Bilddatei f&uuml;hren wir mithilfe einer Funktion namens <b>ImageErzeugen <\/b>durch, die folgende Parameter erwartet:<\/p>\n<ul>\n<li><b>intVersion<\/b>: Version des QR-Codes, liefert Informationen &uuml;ber die Dimension der zu erstellenden Bilddatei.<\/li>\n<li><b>intErrorCorrectionLevel<\/b>: Liefert den Grad der Fehlerkorrektur.<\/li>\n<li><b>strCode<\/b>: Enth&auml;lt den in der Bilddatei anzuzeigenden QR-Code.<\/li>\n<\/ul>\n<p><b>Zwei Arrays<\/b><\/p>\n<p>F&uuml;r das F&uuml;llen des QR-Codes ben&ouml;tigen wir zwei Arrays. Dazu wollen wir uns kurz die notwendigen Schritte ansehen: Zuerst f&uuml;gen wir den Array n&auml;mlich die Markierungen hinzu, mit denen der Scanner sp&auml;ter erkennen kann, in welcher Position sich der QR-Code befindet. Diese landen typischerweise links oben, rechts oben und links unten im Bild. Au&szlig;erdem ben&ouml;tigen wir je nach Version noch ein sogenanntes Alignment Pattern. Auch dieses wird gleich zu Beginn eingef&uuml;gt. Schlie&szlig;lich werden einige allgemeine Informationen zum QRCode-Bild hinzugef&uuml;gt &Atilde;&#162;&#8220;&not;&#8220; und zwar in Form einer horizontalen und einer vertikalen Anordnung. Wie dies aussieht, k&ouml;nnen Sie Bild 1 entnehmen &Atilde;&#162;&#8220;&not;&#8220; in diesem Fall f&uuml;r die Versionen 1 (21&#215;21), 2 (25&#215;25), 7 (45&#215;45) und 14 (73&#215;73).<\/p>\n<p class=\"image\"><img loading=\"lazy\" decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2014_05\/pic_955_010.png\" alt=\"Die Elemente des QR-Codes ohne die eigentlichen Daten f&uuml;r verschiedene Versionen beziehungsweise Kantenl&auml;ngen\" width=\"400\" height=\"400\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Die Elemente des QR-Codes ohne die eigentlichen Daten f&uuml;r verschiedene Versionen beziehungsweise Kantenl&auml;ngen<\/span><\/b><\/p>\n<p>Nun m&uuml;ssen nur noch die wei&szlig;en und schwarzen Pixel hinzugef&uuml;gt werden, welche den eigentlichen Code ausmachen &Atilde;&#162;&#8220;&not;&#8220; plus den Fehlerkorrekturcode. Diese nehmen den &uuml;brigen Platz ein.<\/p>\n<p>Allerdings werden die Pixel nicht einfach Zeile f&uuml;r Zeile und Spalte f&uuml;r Spalte zum Bild hinzugef&uuml;gt, sondern ausgehend von unten rechts, und dann auch nur dort, wo noch keine Informationen etwa in Form von Markierungen abgelegt wurden &Atilde;&#162;&#8220;&not;&#8220; plus einem kleinen Puffer von einem Pixel.<\/p>\n<p>Wie aber k&ouml;nnen wir beim Einf&uuml;llen der Einsen und Nullen f&uuml;r den Code erkennen, welches Pixel bereits gef&uuml;llt ist und welches nicht &Atilde;&#162;&#8220;&not;&#8220; wenn diese doch teilweise mit einer Eins und teilweise mit einer Nulll gef&uuml;llt sind Dazu ben&ouml;tigen wir ein zweites Array, das wir zu Beginn mit einer Maske f&uuml;llen. Diese sieht wiederum wie in Bild 2 aus.<\/p>\n<p class=\"image\"><img loading=\"lazy\" decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2014_05\/pic_955_005.png\" alt=\"Diese Bereiche der QR-Codes werden mit den eigentlichen Daten gef&uuml;llt.\" width=\"400\" height=\"400\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 2: Diese Bereiche der QR-Codes werden mit den eigentlichen Daten gef&uuml;llt.<\/span><\/b><\/p>\n<p>Die Bereiche, die nicht durch eine der Markierungen belegt sind, werden mit einer Art Muster gef&uuml;llt. Warum ein Muster und nicht einfach nur eine schwarze Fl&auml;che Weil dieses Muster, die sogenannte Maske, wiederum eine spezielle Funktion hat.<\/p>\n<p>Wenn eines der Pixel wei&szlig; ist und das Bit des Codes, das dort abgelegt werden soll, den Wert <b>0 <\/b>hat, bleibt das Pixel wei&szlig;. Hat der Code den Wert <b>1<\/b>, wird das Pixel schwarz. War das Pixel zuvor schwarz, sorgt der Wert <b>0 <\/b>daf&uuml;r, dass das Pixel schwarz bleibt, beim Wert <b>1 <\/b>hingegen wird das Pixel wei&szlig;.<\/p>\n<p>Es gibt acht verschiedene Masken, von denen eine ausgew&auml;hlt werden muss. Die Masken stehen deshalb zur Verf&uuml;gung, damit man eine andere Maske verwenden kann, wenn das fertige Bild zu gro&szlig;e wei&szlig;e oder schwarze Bereiche zur Darstellung des Inhalts enth&auml;lt. In der Beispieldatenbank ist dies auf die Maske mit der Nummer Sieben voreingestellt.<\/p>\n<p>Mit dieser Maske wissen wir aber immer noch nicht, welche Pixel des Bildes mit dem QR-Code belegt werden k&ouml;nnen und welche nicht &Atilde;&#162;&#8220;&not;&#8220; sie liefert doch nur Einsen und Nullen Eben nicht: Was in der Abbildung nicht zu erkennen ist, sind die Unterschiede, die leer sind, weil die Maske f&uuml;r diese keinen Wert enth&auml;lt (also weder Eins noch Null) und denen, die den Wert Null enthalten. Wir haben dies mit einer kleinen Hilfsfunktion wie in Bild 3 dargestellt.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2014_05\/pic_955_012.png\" alt=\"Die Maske mit den per x als leer markierten Pixeln\" width=\"445\" height=\"321,2202\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 3: Die Maske mit den per x als leer markierten Pixeln<\/span><\/b><\/p>\n<p>Beim Einf&uuml;llen des QR-Codes in die Maske werden also nur diejenigen Stellen gef&uuml;llt beziehungsweise geswitcht, die bereits einen der Werte 0 oder 1 enthalten. Die mit x markierten Stellen, die ja die Positionsmarken und weitere Informationen zum Aufbau des QR-Codes enthalten, werden nicht ge&auml;ndert.<\/p>\n<p><b>Steuerfunktion<\/b><\/p>\n<p>Kommen wir zum Formular <b>frmQRCodes <\/b>zur&uuml;ck und zu den Schritten, die zur Erstellung des Bildes f&uuml;r den QR-Code erforderlich sind (s. Bild 4).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2014_05\/pic_955_011.png\" alt=\"Formular zum Erstellen der QR-Codes\" width=\"575\" height=\"515,212\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 4: Formular zum Erstellen der QR-Codes<\/span><\/b><\/p>\n<p>Ein Klick auf die Schaltfl&auml;che <b>ImagesErzeugen <\/b>ruft die Prozedur aus Listing 1 auf. Diese Prozedur deklariert die drei Steuerelemente zur Anzeige der verschiedenen Stadien des QR-Codes, die sp&auml;ter mit Verweisen auf die Steuerelemente <b>imgBasis<\/b>, <b>imgBelegung <\/b>und <b>imgQRCode <\/b>gef&uuml;llt werden. Bei diesen Steuerelementen handelt es sich um das <b>Image<\/b>-Steuerelement der <b>MSForms<\/b>-Bibliothek, die Sie &uuml;ber die Liste der ActiveX-Steuerelemente zum Formular hinzuf&uuml;gen k&ouml;nnen.<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>cmdImageErzeugen_Click()\r\n     <span style=\"color:blue;\">Dim <\/span>ctlImageBelegung<span style=\"color:blue;\"> As <\/span>MSForms.Image, ctlImageBasis<span style=\"color:blue;\"> As <\/span>MSForms.Image\r\n     Dim ctlImageQRCode<span style=\"color:blue;\"> As <\/span>MSForms.Image\r\n     <span style=\"color:blue;\">Dim <\/span>picQRCode<span style=\"color:blue;\"> As <\/span>StdPicture, picBelegung<span style=\"color:blue;\"> As <\/span>StdPicture, picBasis<span style=\"color:blue;\"> As <\/span>StdPicture\r\n     <span style=\"color:blue;\">Set<\/span> picQRCode = ImageErzeugen(Me!cboVersionID, Me!cboErrorCorrectionID, _\r\n         Me!txtQRCode, picBelegung, picBasis)\r\n     <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> picQRCode Is Nothing<span style=\"color:blue;\"> Then<\/span>\r\n         SavePicGDIPlus picQRCode, CurrentProject.Path & \"\\QRCode_\" & Me!QRCodeID & \".png\", pictypePNG\r\n     <span style=\"color:blue;\">Else<\/span>\r\n         <span style=\"color:blue;\">MsgBox<\/span> \"Bild nicht erzeugt.\"\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">Set<\/span> ctlImageBasis = Me!imgBasis.Object\r\n     <span style=\"color:blue;\">With<\/span> ctlImageBasis\r\n         .PictureSizeMode = fmPictureSizeModeStretch\r\n         .Picture = picBasis\r\n     End <span style=\"color:blue;\">With<\/span>\r\n     <span style=\"color:blue;\">Set<\/span> ctlImageBelegung = Me!imgBelegung.Object\r\n     <span style=\"color:blue;\">With<\/span> ctlImageBelegung\r\n         .PictureSizeMode = fmPictureSizeModeStretch\r\n         .Picture = picBelegung\r\n     End <span style=\"color:blue;\">With<\/span>\r\n     <span style=\"color:blue;\">Set<\/span> ctlImageQRCode = Me!imgQRCode.Object\r\n     <span style=\"color:blue;\">With<\/span> ctlImageQRCode\r\n         .PictureSizeMode = fmPictureSizeModeStretch\r\n         .Picture = picQRCode\r\n     End <span style=\"color:blue;\">With<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 1: Die Steuerprozedur zum Erzeugen des Bildes mit dem QR-Code<\/span><\/b><\/p>\n<p>Au&szlig;erdem deklariert die Prozedur drei <b>StdPicture<\/b>-Objekte, welche die Bilder aufnehmen, die von einer Funktion erzeugt und dann in den <b>Image<\/b>-Steuerelementen angezeigt werden.<\/p>\n<p>Die Funktion <b>ImageErzeugen <\/b>erwartet als Parameter die Version, den Fehlerkorrekturlevel und den QR-Code sowie die beiden Variablen <b>picBelegung <\/b>und <b>picBasis <\/b>als Parameter. Die letzten beiden werden mit den <b>StdPicture<\/b>-Objekten zu diesen beiden Status des QR-Code-Bildes gef&uuml;llt, die Funktion selbst liefert das <b>StdPicture<\/b>-Objekt mit dem vollst&auml;ndigen QR-Code-Bild zur&uuml;ck.<\/p>\n<p>Nachdem die drei <b>StdPicture<\/b>-Objekte mit den Bildern gef&uuml;llt und zur&uuml;ckgegeben wurden, speichert die Prozedur <b>cmd&Atilde;&#8220;-Image&Atilde;&#8220;-Er&Atilde;&#8220;-zeugen_Click <\/b>das fertige Bild im Datenbankverzeichnis unter dem Namen <b>QRCode_123.png <\/b>(wobei <b>123 <\/b>der Nummer des Datensatzes der Tabelle <b>tblQRCodes <\/b>entspricht, in der die Basisinformationen zu den jeweiligen QR-Codes gespeichert werden).<\/p>\n<p>Au&szlig;erdem landen die Bilder aus den <b>StdPicture<\/b>-Objekten in den Image-Steuerelementen. Fertig! Nun m&uuml;ssen wir uns nur noch die paar hundert Codezeilen ansehen, die den QR-Code in ein Bildobjekt umwandeln.<\/p>\n<p><b>Die Funktion ImageErzeugen<\/b><\/p>\n<p>Diese Funktion steuert die Erzeugung der QR-Code-Bilder. Sie erwartet die bereits weiter oben beschriebenen, von der Prozedur <b>cmdImageErzeugen_Click <\/b>&uuml;bergebenen Parameter (s. Listing 2).<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>ImageErzeugen(intVersion<span style=\"color:blue;\"> As Integer<\/span>, lngErrorCorrectionLevelID<span style=\"color:blue;\"> As Long<\/span>, strcode<span style=\"color:blue;\"> As String<\/span>, _\r\n     <span style=\"color:blue;\">Optional<\/span> picBelegung<span style=\"color:blue;\"> As <\/span>StdPicture, <span style=\"color:blue;\">Optional<\/span> picBasis<span style=\"color:blue;\"> As <\/span>StdPicture)<span style=\"color:blue;\"> As <\/span>StdPicture\r\n     <span style=\"color:blue;\">Dim <\/span>intXKoordinate(32000)<span style=\"color:blue;\"> As Integer<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>intYKoordinate(32000)<span style=\"color:blue;\"> As Integer<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>intModulesToPack<span style=\"color:blue;\"> As Integer<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>intVersionWidth<span style=\"color:blue;\"> As Integer<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>bolQRBild()<span style=\"color:blue;\"> As Boolean<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strMaske()<span style=\"color:blue;\"> As Variant<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>objPicture<span style=\"color:blue;\"> As <\/span>StdPicture\r\n     <span style=\"color:blue;\">Dim <\/span>intMaske<span style=\"color:blue;\"> As Integer<\/span>\r\n     intMaske = 7\r\n     intVersionWidth = DLookup(\"VersionWidth\", \"tblVersions\", \"VersionID = \" & intVersion)\r\n     <span style=\"color:blue;\">Call<\/span> BasisErzeugen(intVersion, intVersionWidth, lngErrorCorrectionLevelID, intMaske, _\r\n         bolQRBild, strMaske)\r\n     <span style=\"color:blue;\">Set<\/span> picBasis = CreatePicture(intVersionWidth, intVersionWidth)\r\n     SetQRCode picBasis, bolQRBild(), intVersionWidth\r\n     <span style=\"color:blue;\">Set<\/span> picBelegung = CreatePicture(intVersionWidth, intVersionWidth)\r\n     SetBelegung picBelegung, strMaske(), intVersionWidth\r\n     intModulesToPack = DLookup(\"ModulesToPack\", \"tblVersions\", \"VersionID = \" & intVersion)\r\n     KoordinatenErmitteln intVersionWidth, strMaske, intXKoordinate, _\r\n         intYKoordinate, intModulesToPack\r\n     CodeHinzufuegen strcode, intModulesToPack, bolQRBild(), strMaske, _\r\n         intXKoordinate, intYKoordinate\r\n     <span style=\"color:blue;\">Set<\/span> objPicture = CreatePicture(intVersionWidth, intVersionWidth)\r\n     SetQRCode objPicture, bolQRBild(), intVersionWidth\r\n     <span style=\"color:blue;\">Set<\/span> ImageErzeugen = objPicture\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 2: Prozedur zum Aufruf der Routinen zum Erzeugen des QR-Code-Bilds<\/span><\/b><\/p>\n<p>Die Funktion verwendet einige Variablen, von denen vier hier erl&auml;utert werden sollen:<\/p>\n<ul>\n<li><b>intXKoordinate(32000)<\/b>: nimmt die X-Koordinaten f&uuml;r den Pfad des QR-Codes im Bild auf.<\/li>\n<li><b>intYKoordinate(32000)<\/b>: nimmt die Y-Koordinaten f&uuml;r den Pfad des QR-Codes im Bild auf.<\/li>\n<li><b>bolQRBild()<\/b>: Nimmt in einem zweidimensionalen Array vom Datentyp <b>Boolean <\/b>die bereits fertigen Bits f&uuml;r das QR-Code-Bild auf, also nur die Werte <b>-1 <\/b>und <b>0<\/b>.<\/li>\n<li><b>strMaske()<\/b>: Nimmt in einem ebenfalls zweidimensionalen Array, diesmal vom Datentyp <b>String<\/b>, die Maske auf, die aus <b>1<\/b>, <b>0<\/b> und Leerzeichen besteht.<\/li>\n<\/ul>\n<p>Die Funktion legt fest, dass die Maske mit der Nummer <b>7 <\/b>verwendet wird. Sie k&ouml;nnen auch die anderen, von <b>0 <\/b>bis <b>6 <\/b>durchnummerierten Masken verwenden &Atilde;&#162;&#8220;&not;&#8220; die Funktion beschr&auml;nkt sich auf die Maske <b>7<\/b>. Jede Maske sorgt f&uuml;r ein anderes Ausgangsmuster, das durch das Hinzuf&uuml;gen des QR-Codes ge&auml;ndert wird. Je nach Maske und QR-Code entstehen so mitunter QR-Code-Bilder, die gro&szlig;e wei&szlig;e oder schwarze Bereiche aufweisen &Atilde;&#162;&#8220;&not;&#8220; schlecht zu lesen f&uuml;r QR-Code-Scanner. In diesem Fall k&ouml;nnten Sie eine andere Maske als Grundlage verwenden. Diese hier wird mit dem Wert <b>7 <\/b>f&uuml;r die Variable <b>intMaske <\/b>fest vorgegeben. Danach ermittelt die Funktion die Ausma&szlig;e der zu erstellenden Pixelmatrix aus der Tabelle <b>tblVersions<\/b>. Die Kantenl&auml;nge landet in der Variablen <b>intVersionWidth<\/b>. Nun startet die Funktion eine weitere Routine namens <b>BasisErzeugen<\/b>. Diese f&uuml;llt die beiden Arrays <b>bolQRBild <\/b>und <b>strMaske <\/b>mit den Daten f&uuml;r die Positionsmarken und die &uuml;brigen Grundinformationen zum verwendeten QR-Code (s. Listing 3).<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>BasisErzeugen(intVersion<span style=\"color:blue;\"> As Integer<\/span>, intVersionWidth<span style=\"color:blue;\"> As Integer<\/span>, _\r\n         lngErrorCorrectionLevelID<span style=\"color:blue;\"> As Long<\/span>, intMaske<span style=\"color:blue;\"> As Integer<\/span>, _\r\n         bolQRBild()<span style=\"color:blue;\"> As Boolean<\/span>, strMaske()<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>intX<span style=\"color:blue;\"> As Integer<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>intY<span style=\"color:blue;\"> As Integer<\/span>\r\n     ReDim bolQRBild(intVersionWidth, intVersionWidth)\r\n     ReDim strMaske(intVersionWidth, intVersionWidth)\r\n     For intX = 1 To intVersionWidth\r\n         For intY = 1 To intVersionWidth\r\n             i = i + 1\r\n             strMaske(intY, intX) = -(i <span style=\"color:blue;\">Mod<\/span> 2)\r\n             bolQRBild(intY, intX) = -1\r\n         <span style=\"color:blue;\">Next<\/span> intY\r\n     <span style=\"color:blue;\">Next<\/span> intX\r\n     MaskeAnwenden strMaske, intMaske, intVersionWidth\r\n     PositionsmusterAnwenden strMaske, bolQRBild, intVersionWidth\r\n     TimingPatternAnwenden strMaske, bolQRBild, intVersionWidth\r\n     VersionsinformationenSchreiben strMaske, bolQRBild, intVersion, _\r\n         intVersionWidth\r\n     BereicheLeeren strMaske, bolQRBild, intVersionWidth\r\n     FormatinformationenSchreiben bolQRBild(), lngErrorCorrectionLevelID, _\r\n         intMaske, intVersionWidth\r\n     AlignmentPatternAnwenden strMaske, bolQRBild, intVersion\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 3: Diese Prozedur f&uuml;gt die Positionsmarkierungen und andere Elemente hinzu.<\/span><\/b><\/p>\n<p>Sie f&uuml;llt also das als Parameter &uuml;bergebene Array <b>bolQRBild<\/b>, das zuvor komplett mit dem Standardwert <b>0 <\/b>gef&uuml;llt war und nun an den Stellen mit den Markierungen die Werte <b>0 <\/b>und <b>1 <\/b>enth&auml;lt. Das Array <b>strMaske<\/b> wird auf &auml;hnliche Weise gef&uuml;llt, allerdings wird dieses zun&auml;chst komplett mit der Maske gef&uuml;llt, bevor die Bereiche, die Markierungen und Informationen enthalten, jeweils mit Leerzeichen versehen werden. <\/p>\n<p>Hieraus werden die beiden oberen Bilder des Formulars <b>frmQRCode <\/b>erzeugt. Das erste wird &uuml;ber die Funktion <b>SetQRCode <\/b>in der <b>StdPicture<\/b>-Variablen <b>picBasis <\/b>als Bild verewigt (und sp&auml;ter im Formular als oberstes Bild angezeigt). Es enth&auml;lt die aktuellen Werte des Array <b>bolQRBild<\/b>, also die bereits hinzugef&uuml;gten Markierungen.<\/p>\n<p>Das zweite Bild namens <b>picBelegung <\/b>soll nur den aktuellen Stand des Inhalts von <b>strMaske <\/b>liefern. Daher f&uuml;llen wir die entsprechende <b>StdPicture<\/b>-Variable entsprechend. Schlie&szlig;lich folgt das eigentliche F&uuml;llen der Matrix in <b>bolQRBild() <\/b>mit dem QR-Code. Dazu ermittelt die Prozedur <b>KoordinatenErmitteln <\/b>zun&auml;chst den Pfad durch die Matrix, in dem die Werte des QR-Codes eingetragen werden sollen. Mehr dazu weiter unten. Schlie&szlig;lich f&uuml;gt die Prozedur <b>CodeHinzufuegen<\/b> den QR-Code in Abh&auml;ngigkeit von der in <b>strMaske <\/b>gespeicherten Vorgaben in das Array <b>bolQRBild() <\/b>ein. Das Ergebnis dieses Vorgangs landet dann schlie&szlig;lich in der <b>StdPicture<\/b>-Variablen <b>objPicture<\/b>, die auch gleichzeitig als R&uuml;ckgabewert der Funktion <b>ImageErzeugen <\/b>dient.<\/p>\n<p><b>Markierungen und Informationen einf&uuml;gen<\/b><\/p>\n<p>Die Prozedur <b>BasisErzeugen <\/b>ruft verschiedene Routinen auf, welche die unterschiedlichen Markierungen und Informationen zu der in <b>bolQRBild() <\/b>gespeicherten Matrix hinzuf&uuml;gen und die Matrix aus <b>strMaske()<\/b> zun&auml;chst mit der Maske f&uuml;llen und dann die Bereiche leeren, die mit Markierungen und sonstigen Informationen gef&uuml;llt werden, damit diese sp&auml;ter beim Hinzuf&uuml;gen des QR-Codes als gef&uuml;llt erkannt werden.<\/p>\n<p>Im ersten Schritt redimensioniert die Prozedur die beiden Variablen <b>bolQRBild <\/b>und <b>strMaske <\/b>entsprechend der zuvor ermittelten Dimensionen der Matrix. Dann durchl&auml;uft die Prozedur zwei verschachtelte Schleifen, in denen alle Felder des Arrays <b>bolQRBild <\/b>mit dem Wert <b>-1 <\/b>gef&uuml;llt werden. Die Felder des Arrays <b>strMaske <\/b>werden abwechselnd mit den Werten <b>-1 <\/b>und <b>0 <\/b>gef&uuml;llt.<\/p>\n<p>Nun f&uuml;gt die Prozedur <b>MaskeAnwenden <\/b>dem Array <b>strMaske <\/b>die als Grundlage zu verwendende Maske hinzu (s. Listing 4). Wir haben hier nur den letzten Zweig der <b>Select Case<\/b>-Bedingung abgebildet, in dem unsere zuvor festgelegte Maske angewendet wird. Die detaillierte Erl&auml;uterung sparen wir uns an dieser Stelle &Atilde;&#162;&#8220;&not;&#8220; die zwei verschachtelten Schleifen &auml;ndern die Werte des Array <b>strMaske <\/b>so, dass es anschlie&szlig;end wie in Bild 5 aussieht.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2014_05\/pic_955_013.png\" alt=\"Die von der Beispieldatenbank verwendete Maske\" width=\"275\" height=\"281,011\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 5: Die von der Beispieldatenbank verwendete Maske<\/span><\/b><\/p>\n<p><b>Hinzuf&uuml;gen der Finderpatterns<\/b><\/p>\n<p>Nach dem Anwenden der Maske landen die Finderpatterns im Array <b>bolQRBild<\/b>. Au&szlig;erdem werden die Bereiche, in denen sich die Finderpatterns befinden, im Array <b>strMaske <\/b>geleert (s. Bild 6). F&uuml;r diese Aufgabe ist die Prozedur <b>FinderPatternsAnwenden <\/b>aus Listing 5 verantworlich.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2014_05\/pic_955_014.png\" alt=\"bolQRBild und strMaske mit Positionsmustern\" width=\"400\" height=\"203,1579\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 6: bolQRBild und strMaske mit Positionsmustern<\/span><\/b><\/p>\n<p>Die Prozedur erstellt zun&auml;chst ein Array, das den Aufbau eines Finderpatterns enth&auml;lt. Das Aussehen k&ouml;nnen Sie schematisch bereits dem Listing entnehmen. Die Prozedur durchl&auml;uft jeweils zwei ineinander verschachtelte Schleifen. Die Durchl&auml;ufe, bei denen die Laufvariablen jeweils die Werte von <b>1 <\/b>bis <b>7 <\/b>annehmen, repr&auml;sentieren den Aufbau der einzuf&uuml;genden Finderpatterns. Insgesamt gibt es drei Finderpatterns. Um Code zu sparen, werden die gleichen Schleifen f&uuml;r alle drei Finderpatterns verwendet.<\/p>\n<p>Der Ablauf der Prozedur sieht so aus: Nach dem Start haben die beiden Schleifenvariablen <b>i <\/b>und <b>j <\/b>den Wert <b>1<\/b>. Auch die zus&auml;tzliche Z&auml;hlervariable namens <b>intZaehler <\/b>besitzt den Wert <b>1<\/b>. Die Prozedur pr&uuml;ft dann in der <b>If&#8230;Then<\/b>-Bedingung, welchen Wert das Array f&uuml;r die durch <b>intZaehler <\/b>markierte Position hat. Im Falle des Wertes <b>1 <\/b>wird das aktuelle Feld von <b>bolQRBild<\/b>, also das mit der Position <b>1|1<\/b>, mit dem Wert <b>0 <\/b>versehen. Das entsprechende Feld des Arrays <b>strMaske <\/b>wird mit einer leeren Zeichenkette gef&uuml;llt, damit dieses Feld sp&auml;ter nicht mehr durch den eigentlichen QR-Code gef&uuml;llt werden kann. Dies war das erste der 7&#215;7 Pixel f&uuml;r das Finderpattern oben links.<\/p>\n<p>Die beiden folgenden Anweisungen k&uuml;mmern sich um das Finderpattern oben rechts, die n&auml;chsten beiden um das Finderpattern unten links.<\/p>\n<p>Anschlie&szlig;end wird <b>intZaehler <\/b>um Eins erh&ouml;ht, damit im folgenden Durchlauf der inneren <b>For&#8230;Next<\/b>-Schleife das folgende Element des im Array <b>varFinderPattern <\/b>gespeicherte Finderpatterns oben links, oben rechts und unten links eingef&uuml;gt werden kann.<\/p>\n<p>Der <b>Else<\/b>-Teil der <b>If&#8230;Then<\/b>-Bedingung legt die entsprechenden Werte in <b>bolQRBild <\/b>und <b>strMaske <\/b>f&uuml;r den Fall fest, dass das aktuelle Element von <b>varFinderPattern<\/b> den Wert <b>0 <\/b>hat.<\/p>\n<p><b>Timingpattern und Dark Module einf&uuml;gen<\/b><\/p>\n<p>Das n&auml;chste einzuf&uuml;gende Element ist das Timingpattern. Dabei handelt es sich um eine horizontale gepunktete Linie zwischen den beiden oberen Finderpatterns und eine vertikale gepunktete Linie zwischen den beiden linken Finderpatterns. Au&szlig;erdem ben&ouml;tigen wir das sogenannte Dark Module, ein schwarzes Bit rechts oben neben dem linken, unteren Finderpattern (s. Bild 7). <\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2014_05\/pic_955_015.png\" alt=\"bolQRBild und strMaske mit Timing Pattern\" width=\"400\" height=\"204,7244\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 7: bolQRBild und strMaske mit Timing Pattern<\/span><\/b><\/p>\n<p>Das Hinzuf&uuml;gen dieser Elemente &uuml;bernimmt die Prozedur <b>TimingPatternAnwenden <\/b>aus Listing 6. Der erste Teil legt das horizontale Timingpattern an.<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>TimingPatternAnwenden(strMaske()<span style=\"color:blue;\"> As Variant<\/span>, bolQRBild()<span style=\"color:blue;\"> As Boolean<\/span>, _\r\n         intVersionWidth<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     For i = 10 To intVersionWidth - 7 \r\n         <span style=\"color:blue;\">If <\/span>i <span style=\"color:blue;\">Mod<\/span> 2 = 0<span style=\"color:blue;\"> Then<\/span>\r\n             bolQRBild(i - 1, 7) = 0\r\n             strMaske(i - 1, 7) = \"\"\r\n         <span style=\"color:blue;\">Else<\/span>\r\n             bolQRBild(i - 1, 7) = -1\r\n             strMaske(i - 1, 7) = \"\"\r\n         <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">Next<\/span> i\r\n     For i = 10 To intVersionWidth - 7 \r\n         <span style=\"color:blue;\">If <\/span>i <span style=\"color:blue;\">Mod<\/span> 2 = 0<span style=\"color:blue;\"> Then<\/span>\r\n             bolQRBild(7, i - 1) = 0\r\n             strMaske(7, i - 1) = \"\"\r\n         <span style=\"color:blue;\">Else<\/span>\r\n             bolQRBild(7, i - 1) = -1\r\n             strMaske(7, i - 1) = \"\"\r\n         <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">Next<\/span> i\r\n     bolQRBild(9, intVersionWidth - 7) = 0\r\n     strMaske(9, intVersionWidth - 7) = \"\"\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 6: Hinzuf&uuml;gen des Timingpatterns<\/span><\/b><\/p>\n<p>Dazu durchl&auml;uft die Prozedur eine <b>For&#8230;Next<\/b>-Schleife &uuml;ber die Werte von <b>10 <\/b>bis zur Breite des QR-Codes minus sieben. Hier werden die Elemente im Array <b>bolQRBild<\/b> von links nach rechts abwechselnd mit den Werten <b>0<\/b> und <b>-1 <\/b>gef&uuml;llt.<\/p>\n<p>Die entsprechenden Elemente des Arrays <b>strMaske<\/b> werden mit leeren Zeichenketten gef&uuml;llt, um diese als belegt zu markieren. Die zweite <b>For&#8230;Next<\/b>-Schleife erledigt dies f&uuml;r die vertikale Linie.<\/p>\n<p>Die letzten beiden Anweisungen dieser Prozedur legen das Dark Module fest. Dieses liegt immer an der gleichen Position, n&auml;mlich an der neunten Stelle von links und der achten Stelle von unten. Das entsprechende Element der Maske wird mit einer leeren Zeichenkette gef&uuml;llt.<\/p>\n<p><b>Versionsinformationen schreiben<\/b><\/p>\n<p>Wenn die Version des QR-Codes gr&ouml;&szlig;er als sieben ist (also f&uuml;r eine Dimension von 45&#215;45 und mehr), f&uuml;gt die Funktion <b>VersionsinformationenSchreiben <\/b>an zwei Stellen zus&auml;tzliche Informationen &uuml;ber die Version des verwendeten QR-Codes hinzu (siehe Listing 7).<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>VersionsinformationenSchreiben(strMaske()<span style=\"color:blue;\"> As Variant<\/span>, _\r\n         bolQRBild()<span style=\"color:blue;\"> As Boolean<\/span>, intVersion<span style=\"color:blue;\"> As Integer<\/span>, intVersionWidth<span style=\"color:blue;\"> As Integer<\/span>)\r\n     <span style=\"color:blue;\">Dim <\/span>strVersionInfo<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>intZaehler<span style=\"color:blue;\"> As Integer<\/span>, i<span style=\"color:blue;\"> As Integer<\/span>, j<span style=\"color:blue;\"> As Integer<\/span>\r\n     <span style=\"color:blue;\">If <\/span>intVersion &gt;= 7<span style=\"color:blue;\"> Then<\/span>\r\n         strVersionInfo = DLookup(\"VersionInfo\", \"tblVersions\", \"VersionID = \" _\r\n             & intVersion)\r\n         intZaehler = 1\r\n         For i = 1 To 6\r\n             For j = 1 To 3\r\n                 <span style=\"color:blue;\">If <\/span>Mid$(strVersionInfo, intZaehler, 1) = \"1\"<span style=\"color:blue;\"> Then<\/span>\r\n                     bolQRBild(intVersionWidth - 11 + j, i) = 0\r\n                     strMaske(intVersionWidth - 11 + j, i) = \"\"\r\n                     intZaehler = intZaehler + 1\r\n                 <span style=\"color:blue;\">Else<\/span>\r\n                     bolQRBild(intVersionWidth - 11 + j, i) = -1\r\n                     strMaske(intVersionWidth - 11 + j, i) = \"\"\r\n                     intZaehler = intZaehler + 1\r\n                 <span style=\"color:blue;\">End If<\/span>\r\n             <span style=\"color:blue;\">Next<\/span> j\r\n         <span style=\"color:blue;\">Next<\/span> i\r\n         intZaehler = 1\r\n         For j = 1 To 6\r\n             For i = 1 To 3\r\n                 <span style=\"color:blue;\">If <\/span>Mid$(strVersionInfo, intZaehler, 1) = \"1\"<span style=\"color:blue;\"> Then<\/span>\r\n                     bolQRBild(j, intVersionWidth - 11 + i) = 0\r\n                     strMaske(j, intVersionWidth - 11 + i) = \"\"\r\n                     intZaehler = intZaehler + 1\r\n                 <span style=\"color:blue;\">Else<\/span>\r\n                     bolQRBild(j, intVersionWidth - 11 + i) = -1\r\n                     strMaske(j, intVersionWidth - 11 + i) = \"\"\r\n                     intZaehler = intZaehler + 1\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;\">End Sub<\/span><\/pre>\n<p><!--30percent--><\/p>\n<p><b><span style=\"color:darkgrey;\">Listing 7: Hinzuf&uuml;gen der Versionsinformation<\/span><\/b><\/p>\n<p>Diese landen an den markierten Stellen in Bild 8. Auch hier verwendet die Prozedur immer die gleiche Position f&uuml;r die jeweils 6&#215;3 Pixel beziehungsweise 3&#215;6 Pixel gro&szlig;en Elemente &Atilde;&#162;&#8220;&not;&#8220; n&auml;mlich elf Pixel vom rechten Rand f&uuml;r die Versionsinformationen neben dem rechten, oberen Finderpattern und elf Pixel vom unteren Rand f&uuml;r die Versionsinformationen &uuml;ber dem linken, unteren Finderpattern.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2014_05\/pic_955_016.png\" alt=\"bolQRBild und strMaske mit Versionsinformationen\" width=\"400\" height=\"203,0928\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 8: bolQRBild und strMaske mit Versionsinformationen<\/span><\/b><\/p>\n<p>Die jeweils 18 Bits f&uuml;r die Finderpatterns sind in der Tabelle <b>tblVersions <\/b>gespeichert, von wo die Prozedur diese auch ausliest. Dies jedoch, wie bereits erw&auml;hnt, nur f&uuml;r einen Wert von <b>intVersion <\/b>gr&ouml;&szlig;er als <b>7<\/b>. Danach erfolgt das Anlegen der Versionsinformationen wieder innerhalb von zwei verschachtelten <b>For&#8230;Next<\/b>-Schleifen. Diese durchlaufen jeweils die 3&#215;6 beziehungsweise 6&#215;3 Pixel gr&ouml;&szlig;en Bereiche der beiden Variablen <b>bolQRBild <\/b>und <b>strMaske<\/b>. <b>bolQRBild <\/b>wird dabei wie &uuml;blich mit den Werten <b>0 <\/b>und <b>-1 <\/b>gef&uuml;llt, <b>strMaske <\/b>erh&auml;lt die entsprechenden leeren Zeichenketten, um diese Bereiche als gesperrt zu markieren.<\/p>\n<p><b>Zus&auml;tzliche Bereiche leeren<\/b><\/p>\n<p>Die Prozedur <b>BereicheLeeren<\/b> markiert einige weitere Bereiche mit dem Wert <b>-1 <\/b>und legt diese als gesperrt fest (s. Listing 8). Dies dient haupts&auml;chlich dazu, die Finderpatterns mit einem Pixel Abstand zu dem sp&auml;ter einzuf&uuml;genden QR-Code zu versehen.<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>BereicheLeeren(strMaske()<span style=\"color:blue;\"> As Variant<\/span>, bolQRBild()<span style=\"color:blue;\"> As Boolean<\/span>, __\r\n         intVersionWidth<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     For i = 1 To 8\r\n         bolQRBild(i, 8) = 0\r\n         strMaske(i, 8) = \"\"\r\n         bolQRBild(i, intVersionWidth - 7) = 0\r\n         strMaske(i, intVersionWidth - 7) = \"\"\r\n         bolQRBild(intVersionWidth - 8 + i, 8) = 0\r\n         strMaske(intVersionWidth - 8 + i, 8) = \"\"\r\n     <span style=\"color:blue;\">Next<\/span> i\r\n     For i = 1 To 8\r\n         bolQRBild(8, i) = 0\r\n         strMaske(8, i) = \"\"\r\n         bolQRBild(intVersionWidth - 7, i) = 0\r\n         strMaske(intVersionWidth - 7, i) = \"\"\r\n         bolQRBild(8, intVersionWidth - 8 + i) = 0\r\n         strMaske(8, intVersionWidth - 8 + i) = \"\"\r\n     <span style=\"color:blue;\">Next<\/span> i\r\n     For i = 1 To 9\r\n         strMaske(i, 9) = \"\"\r\n         <span style=\"color:blue;\">If <\/span>i &lt; 9<span style=\"color:blue;\"> Then<\/span>\r\n             strMaske(9, intVersionWidth - 8 + i) = \"\"\r\n         <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">Next<\/span> i\r\n     For i = 1 To 8\r\n         strMaske(i, 9) = \"\"\r\n         strMaske(intVersionWidth - 8 + i, 9) = \"\"\r\n     <span style=\"color:blue;\">Next<\/span> i\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 8: Leeren einiger Bereiche<\/span><\/b><\/p>\n<p>Das Ergebnis sieht etwa wie in Bild 9 aus. Dort finden Sie allerdings nur die beiden innerhalb der ersten beiden <b>For&#8230;Next<\/b>-Schleifen hinzugef&uuml;gten leeren Linien unter, &uuml;ber, links und rechts von den Finderpatterns.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2014_05\/pic_955_017.png\" alt=\"bolQRBild und strMaske mit gesperrten Bereichen\" width=\"400\" height=\"204,2105\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 9: bolQRBild und strMaske mit gesperrten Bereichen<\/span><\/b><\/p>\n<p>Die erste <b>For&#8230;Next<\/b>-Schleife l&auml;uft &uuml;ber die Zahlenwerte von <b>1 <\/b>bis <b>8<\/b>. Die ersten beiden Anweisungen stellen die horizontale Linie unter dem linken, oberen Finderpattern so ein, dass dieses in <b>bolQRBild <\/b>mit dem Wert <b>0 <\/b>und in <b>strMaske <\/b>mit einer leeren Zeichenkette gef&uuml;llt wird. Die zweiten beiden Zeilen f&uuml;llen die horizontale Linie unter dem rechten, oberen Finderpattern entsprechend. Die folgenden Zeilen erledigen dies f&uuml;r die horizontale Linie &uuml;ber dem linken, unteren Finderpattern.<\/p>\n<p>Die zweite <b>For&#8230;Next<\/b>-Schleife nimmt sich auf &auml;hnliche Weise die vertikalen Linien rechts von den linken Finderpattern sowie links vom rechten, oberen Finderpattern vor. Diese Markierungen sind in der Abbildung blau markiert (in der gedruckten Version nicht zu erkennen, siehe dazu das PDF zu diesem Beitrag).<\/p>\n<p>Die dritte <b>For&#8230;Next<\/b>-Schleife enth&auml;lt zwei Anweisungen, welche zwei weitere Streifen als gesperrt markiert, um zu verhindern, dass diese sp&auml;ter mit den Daten des QR-Codes beschrieben werden.<\/p>\n<p>Dazu tr&auml;gt sie mit der ersten Anweisung f&uuml;r den horizontalen, neun Zeichen langen Streifen unterhalb des linken, oberen Finderpattern einige leere Zeichenketten in das Array <b>strMaske <\/b>ein. Ein weiterer Streifen wird gleich rechts von diesem Finderpattern angelegt &Atilde;&#162;&#8220;&not;&#8220; siehe die gr&uuml;nen Markierungen in der Abbildung. Die vierte <b>For&#8230;Next<\/b>-Schleife f&uuml;gt noch zwei Streifen zur Sperrung des Bereichs rechts vom linken, unteren Finderpattern und unter dem rechten, oberen Finderpattern hinzu.<\/p>\n<p><b>Formatinformationen schreiben<\/b><\/p>\n<p>Damit kommen wir zu den Formatinformationen. Diese liest die Prozedur <b>FormatinformationenSchreiben<\/b> aus Listing 9 zun&auml;chst per <b>DLookup<\/b>-Funktion aus der Tabelle <b>tblFormatInformation <\/b>f&uuml;r den verwendeten Fehlerkorrekturlevel und die verwendete Maske ein. Bei diesen Informationen handelt es sich um jeweils 15-stellige bin&auml;re Zahlen, zum Beispiel <b>111011111000100<\/b>. Nachdem diese Information in der Variagblen <b>strFormatInformation <\/b>gelandet ist, setzt die Prozedur zun&auml;chst den in <b>intZaehler <\/b>gespeicherten Z&auml;hler auf den Wert <b>1 <\/b>ein.<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>FormatinformationenSchreiben(bolQRBild()<span style=\"color:blue;\"> As Boolean<\/span>, _\r\n         lngErrorCorrectionLevelID<span style=\"color:blue;\"> As Long<\/span>, intMaske<span style=\"color:blue;\"> As Integer<\/span>, _\r\n         intVersionWidth<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;\">Dim <\/span>strFormatInformation<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>i<span style=\"color:blue;\"> As Integer<\/span>\r\n     strFormatInformation = DLookup(\"FormatInformation\", \"tblFormatInformation\", _\r\n         \"ErrorCorrectionLevel = \" & lngErrorCorrectionLevelID & \" AND Maske = \" _\r\n         & intMaske)\r\n     intZaehler = 1\r\n     For i = 1 To 15\r\n         <span style=\"color:blue;\">If <\/span>Mid$(strFormatInformation, i, 1) = \"1\"<span style=\"color:blue;\"> Then<\/span>\r\n             bolQRBild(intZaehler, 9) = -1\r\n         <span style=\"color:blue;\">Else<\/span>\r\n             bolQRBild(intZaehler, 9) = 0\r\n         <span style=\"color:blue;\">End If<\/span>\r\n         intZaehler = intZaehler + 1\r\n         <span style=\"color:blue;\">If <\/span>intZaehler = 7<span style=\"color:blue;\"> Then<\/span> intZaehler = intZaehler + 1\r\n         <span style=\"color:blue;\">If <\/span>intZaehler = 9<span style=\"color:blue;\"> Then<\/span> intZaehler = intVersionWidth + 1 - 8\r\n     <span style=\"color:blue;\">Next<\/span> i\r\n     intZaehler = intVersionWidth\r\n     For i = 1 To 15\r\n         <span style=\"color:blue;\">If <\/span>Mid$(strFormatInformation, i, 1) = \"1\"<span style=\"color:blue;\"> Then<\/span>\r\n             bolQRBild(9, intZaehler) = -1\r\n         <span style=\"color:blue;\">Else<\/span>\r\n             bolQRBild(9, intZaehler) = 0\r\n         <span style=\"color:blue;\">End If<\/span>\r\n         intZaehler = intZaehler - 1\r\n         <span style=\"color:blue;\">If <\/span>intZaehler = intVersionWidth + 1 - 8<span style=\"color:blue;\"> Then<\/span> intZaehler = 9\r\n         <span style=\"color:blue;\">If <\/span>intZaehler = 7<span style=\"color:blue;\"> Then<\/span> intZaehler = 6\r\n     <span style=\"color:blue;\">Next<\/span> i\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 9: Schreiben der Formatinformationen<\/span><\/b><\/p>\n<p>Die Prozedur durchl&auml;uft wieder zwei <b>For&#8230;Next<\/b>-Schleifen. Die erste enth&auml;lt eine <b>If&#8230;Then<\/b>-Bedingung, die pr&uuml;ft, ob das aktuelle der in der Schleife durchlaufenen 15 Zeichen der Zeichenkette aus <b>strFormatInformation <\/b>dem Wert <b>1 <\/b>entspricht. Falls ja, tr&auml;gt die Prozedur im Array <b>bolQRBild <\/b>den Wert <b>-1 <\/b>f&uuml;r das Element an, das sich unter dem linken, oberen Finderpattern am linken Rand befindet, anderenfalls den Wert <b>0<\/b>. Auf diese Weise f&auml;hrt die Schleife weiter fort und tr&auml;gt die Werte von links nach rechts ein. Die x-Koordinate bezieht die Prozedur dabei aus der Variablen <b>intZaehler<\/b>, der normalerweise mit jedem Schleifendurchlauf um eins erh&ouml;ht wird.<\/p>\n<p>Es gibt nur zwei Sonderf&auml;lle: Nach dem siebten Zeichen wird <b>intZaeh&Atilde;&#8220;-ler <\/b>um zwei erh&ouml;ht, da sich an dieser Stelle bereits die Linie mit dem Timingpattern befindet. Und nach neun Zeichen f&auml;hrt <b>intZaehler <\/b>unter dem rechten, oberen Finderpattern fort. Die Formatierungsinformationen werden also unterhalb der Finderpatterns von links nach rechts untergebracht &Atilde;&#162;&#8220;&not;&#8220; mit zwei Unterbrechungen. Dies k&ouml;nnen Sie auch in Bild 10 anhand der Pfeile nachvollziehen.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2014_05\/pic_955_018.png\" alt=\"bolQRBild mit und ohne Formatinformationen\" width=\"375\" height=\"191,9292\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 10: bolQRBild mit und ohne Formatinformationen<\/span><\/b><\/p>\n<p>Die zweite Schleife f&uuml;gt die gleichen Informationen noch einmal rechts neben die linken Finderpattern ein, wieder an zwei Stellen unterbrochen.<\/p>\n<p><b>Alignmentpattern hinzuf&uuml;gen<\/b><\/p>\n<p>Fehlt noch das Alignmentpattern beziehungsweise, bei gr&ouml;&szlig;eren QR-Codes, die Alignmentpatterns. Dabei handelt es sich um ein oder mehrere weitere Markierungen, die beim Erkennen der Ausrichtung des QR-Codes helfen sollen. Bild 11 zeigt, wie diese Markierung im Array <b>bolQRBild <\/b>und im Array <b>strMaske <\/b>erscheint. Wenn Sie eine gr&ouml;&szlig;ere Version des QR-Codes w&auml;hlen, erscheinen mehrere Alignmentpatterns.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2014_05\/pic_955_020.png\" alt=\"bolQRBild() und strMaske() mit einem Alignmentpattern\" width=\"400\" height=\"201,5666\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 11: bolQRBild() und strMaske() mit einem Alignmentpattern<\/span><\/b><\/p>\n<p>Die Prozedur, die f&uuml;r das Anlegen der Alignmentpatterns verantworlich ist, hei&szlig;t <b>AlignmentPatternAnwenden<\/b> (s. Listing 10). Sie definiert zun&auml;chst das Aussehen des Ausrichtungsmusters in der Variablen <b>varAusrichtungsmuster <\/b>&Atilde;&#162;&#8220;&not;&#8220; und zwar als Array aus den Werten <b>1 <\/b>und <b>0<\/b>.<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>AlignmentPatternAnwenden(strMaske()<span style=\"color:blue;\"> As Variant<\/span>, bolQRBild()<span style=\"color:blue;\"> As Boolean<\/span>, intVersion<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>, k<span style=\"color:blue;\"> As Integer<\/span> l<span style=\"color:blue;\"> As Integer<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>intXKoordinaten(7)<span style=\"color:blue;\"> As Integer<\/span>, intYKoordinaten(7)<span style=\"color:blue;\"> As Integer<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>intZaehler<span style=\"color:blue;\"> As Integer<\/span>, bolGueltigePosition<span style=\"color:blue;\"> As Boolean<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>intX(49)<span style=\"color:blue;\"> As Integer<\/span>, intY(49)<span style=\"color:blue;\"> As Integer<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>intErsteKoordinate<span style=\"color:blue;\"> As Integer<\/span>, intLetzteKoordinate<span style=\"color:blue;\"> As Integer<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>varAusrichtungsmuster()<span style=\"color:blue;\"> As Variant<\/span>\r\n     varAusrichtungsmuster = Array( _\r\n         1, 1, 1, 1, 1, _\r\n         1, 0, 0, 0, 1, _\r\n         1, 0, 1, 0, 1, _\r\n         1, 0, 0, 0, 1, _\r\n         1, 1, 1, 1, 1)\r\n     <span style=\"color:blue;\">If <\/span>intVersion &gt; 1<span style=\"color:blue;\"> Then<\/span>\r\n         For k = 1 To 7\r\n             intXKoordinaten(k) = DLookup(\"Coord\" & k, \"tblVersions\", \"VersionID = \" & intVersion)\r\n             intYKoordinaten(k) = DLookup(\"Coord\" & k, \"tblVersions\", \"VersionID = \" & intVersion)\r\n             <span style=\"color:blue;\">If <\/span>intXKoordinaten(k) = 0<span style=\"color:blue;\"> Then<\/span>\r\n                 intLetzteKoordinate = intXKoordinaten(k - 1)\r\n                 <span style=\"color:blue;\">Exit For<\/span>\r\n             <span style=\"color:blue;\">Else<\/span>\r\n                 intLetzteKoordinate = intXKoordinaten(k)\r\n             <span style=\"color:blue;\">End If<\/span>\r\n         <span style=\"color:blue;\">Next<\/span> k\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     intZaehler = 1\r\n     For i = 1 To 7\r\n         For j = 1 To 7\r\n             intX(intZaehler) = intXKoordinaten(i)\r\n             intY(intZaehler) = intYKoordinaten(j)\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     intErsteKoordinate = 6\r\n     bolGueltigePosition = <span style=\"color:blue;\">True<\/span>\r\n     For i = 1 To 49\r\n         intZaehler = 1\r\n         <span style=\"color:blue;\">If <\/span>intX(i) = 0 Or intY(i) = 0<span style=\"color:blue;\"> Then<\/span> bolGueltigePosition = <span style=\"color:blue;\">False<\/span>\r\n         <span style=\"color:blue;\">If <\/span>intX(i) = intErsteKoordinate And intY(i) = intErsteKoordinate<span style=\"color:blue;\"> Then<\/span> bolGueltigePosition = <span style=\"color:blue;\">False<\/span>\r\n         <span style=\"color:blue;\">If <\/span>intX(i) = intErsteKoordinate And intY(i) = intLetzteKoordinate<span style=\"color:blue;\"> Then<\/span> bolGueltigePosition = <span style=\"color:blue;\">False<\/span>\r\n         <span style=\"color:blue;\">If <\/span>intX(i) = intLetzteKoordinate And intY(i) = intErsteKoordinate<span style=\"color:blue;\"> Then<\/span> bolGueltigePosition = <span style=\"color:blue;\">False<\/span>\r\n         <span style=\"color:blue;\">If <\/span>bolGueltigePosition = <span style=\"color:blue;\">True<\/span><span style=\"color:blue;\"> Then<\/span>\r\n             For k = intX(i) To intX(i) + 4\r\n                 For l = intY(i) To intY(i) + 4\r\n                     <span style=\"color:blue;\">If <\/span>varAusrichtungsmuster(intZaehler) = 1<span style=\"color:blue;\"> Then<\/span>\r\n                         bolQRBild(l - 1, k - 1) = -1\r\n                         strMaske(l - 1, k - 1) = \"\"\r\n                         intZaehler = intZaehler + 1\r\n                     <span style=\"color:blue;\">Else<\/span>\r\n                         bolQRBild(l - 1, k - 1) = 0\r\n                         strMaske(l - 1, k - 1) = \"\"\r\n                         intZaehler = intZaehler + 1\r\n                     <span style=\"color:blue;\">End If<\/span>\r\n                 <span style=\"color:blue;\">Next<\/span> l\r\n             <span style=\"color:blue;\">Next<\/span> k\r\n         <span style=\"color:blue;\">Else<\/span>\r\n             bolGueltigePosition = <span style=\"color:blue;\">True<\/span>\r\n         <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">Next<\/span> i\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 10: Hinzuf&uuml;gen der Alignmentpatterns<\/span><\/b><\/p>\n<p>Danach ermittelt sie die Koordinaten f&uuml;r die Position der Ausrichtungsmuster. Dabei kann es sich um ein bis sieben St&uuml;ck handeln, wobei jede Koordinate gleichzeitig die Position auf der x- und der y-Achse angibt. Da wir noch nicht wissen, wie viele Ausrichtungsmuster wir ben&ouml;tigen, liest die Prozedur einfach alle sieben Koordinaten ein. Diese befinden sich in der Tabelle <b>tblVersions<\/b>, und zwar in den Feldern <b>Coord1<\/b> bis <b>Coord7 <\/b>(s. Bild 12).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2014_05\/pic_955_019.png\" alt=\"Die Tabelle tblVersions mit den Koordinaten f&uuml;r die Alignmentpatterns\" width=\"575\" height=\"222,2819\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 12: Die Tabelle tblVersions mit den Koordinaten f&uuml;r die Alignmentpatterns<\/span><\/b><\/p>\n<p>Alle Versionen (au&szlig;er der ersten, die gar keine Ausrichtungsmuster verwendet) verwenden als erste Koordinate die Position <b>6<\/b>. Die zweite Version verwendet au&szlig;erdem die Position <b>18<\/b>. Das bedeutet eigentlich, dass vier Ausrichtungsmuster angelegt werden sollen, n&auml;mlich ausgehend von den Koordinaten <b>6|6<\/b>, <b>6|18<\/b>, <b>18|6 <\/b>und <b>18|18<\/b>. Nun befinden sich links oben, links unten und rechts unten aber schon die Finderpattern. Also kann f&uuml;r die zweite Position nur noch das Ausrichtungsmuster mit den Startkoordinaten <b>18|18 <\/b>angelegt werden. Bei den &uuml;brigen Versionen sieht es &auml;hnlich aus &Atilde;&#162;&#8220;&not;&#8220; alle Ausrichtungsmuster, die den Wert <b>6 <\/b>in der x- oder y-Koordinate enthalten, fallen weg.<\/p>\n<p>Die Prozedur liest also die m&ouml;glichen sieben Werte f&uuml;r die Startpunkte der Ausrichtungsmuster in die beiden Arrays <b>intXKoordinaten <\/b>und <b>intYKoordinaten <\/b>ein. Dies geschieht aber nur, wenn <b>intVersion <\/b>einen Wert gr&ouml;&szlig;er als eins aufweist.<\/p>\n<p>Wenn das aktuelle Element des Arrays <b>intXKoordinaten <\/b>den Wert <b>0 <\/b>enth&auml;lt, f&uuml;llt die Prozedur die Variable <b>intLetzteKoordinate <\/b>mit der vorherigen Koordinate (im Falle der Version 2 also etwa mit dem Wert <b>18<\/b>) und verl&auml;sst die Schleife. Werden alle sieben Koordinaten verwendet, landet der Wert der letzten Koordinate in der Variablen <b>intLetzteKoordinate<\/b>. Wir haben also f&uuml;r das einfache Beispiel der zweiten Version nun ein Array namens <b>intXKoordinaten <\/b>mit den Werten <b>6<\/b>, <b>18<\/b>, <b>0<\/b>, <b>0, 0<\/b>, <b>0<\/b>, <b>0 <\/b>und ein zweites Array namens <b>intYArray <\/b>mit den gleichen Werten.<\/p>\n<p>Nun f&uuml;llt die Prozedur in zwei verschachtelten <b>For&#8230;Next<\/b>-Schleifen die Werte der beiden Arrays <b>intXKoordinaten <\/b>und <b>intYKoordinaten <\/b>so in zwei weitere Arrays namens <b>intX <\/b>und <b>intY<\/b>, dass jeweils ein paar aus <b>intX <\/b>und <b>intY <\/b>eine Kombination zweier Koordinaten darstellt.<\/p>\n<p><b>intX <\/b>hat dann beispielsweise die Werte <b>6<\/b>,  <b>6<\/b>,  <b>6<\/b>,  <b>6<\/b>,  <b>6<\/b>,  <b>6<\/b>,  <b>6<\/b>,  <b>18<\/b>, <b>18<\/b>,  <b>18<\/b>,  <b>18<\/b>,  <b>18<\/b>,  <b>18<\/b>,  <b>18<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0 <\/b>und  <b>0<\/b>. <b>intY <\/b>enth&auml;lt die Werte <b>6<\/b>,  <b>18<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>6<\/b>,  <b>18<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>6<\/b>,  <b>18<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>6<\/b>,  <b>18<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>6<\/b>,  <b>18<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>6<\/b>,  <b>18<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>6<\/b>,  <b>18<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0<\/b>,  <b>0 <\/b>und <b>0<\/b>. Betrachtet man nun jeweils die Werte mit gleichem Index als Paar (also etwa die beiden ersten Werte), erh&auml;lt man alle m&ouml;glichen Kombinationen &Atilde;&#162;&#8220;&not;&#8220; aber auch einige doppelte.<\/p>\n<p>Damit macht sich die Prozedur an das Anlegen der Alignmentpatterns. Dies geschieht in einer <b>For&#8230;Next<\/b>-Schleife &uuml;ber die Werte <b>1 <\/b>bis <b>49<\/b>. In dieser Schleife pr&uuml;fen vier If&#8230;Then-Bedingungen jeweils die x- oder die y-Koordinate auf bestimmte Werte, die ein Anlegen verhindern. Die erste Bedingung pr&uuml;ft zum Beispiel, ob eine von beiden Koordinaten den Wert <b>0 <\/b>hat. In diesem Fall gibt es kein Alignmentpattern. Damit die folgenden <b>For&#8230;Next<\/b>-Schleifen nur ausgef&uuml;hrt werden, wenn ein Alignmentpattern gesetzt werden soll, stellen die <b>If&#8230;Then<\/b>-Bedingungen den Wert der <b>Boolean<\/b>-Variablen <b>bolGueltigePosition <\/b>auf False, wenn die jeweilige Bedingung erf&uuml;llt ist.<\/p>\n<p>Die zweite Bedingung pr&uuml;ft, ob die x- und die y-Koordinate den Wert aus <b>int&Atilde;&#8220;-Erste&Atilde;&#8220;-Koordinate <\/b>enth&auml;lt (als <b>6 <\/b>festgelegt &Atilde;&#162;&#8220;&not;&#8220; an dieser Koordinate befinden sich die FinderPatterns). Die dritte und vierte Bedingung pr&uuml;fen, ob entweder die x- oder die y-Koordinate den Wert aus <b>intErsteKoordinate <\/b>enthalten und gleichzeitig die andere Koordinate dem Wert aus <b>intLetzteKoordinate <\/b>entspricht. In allen drei F&auml;llen wird <b>bolGuel&Atilde;&#8220;-tigePosition <\/b>auf <b>False <\/b>eingestellt.<\/p>\n<p>Die folgenden verschachtelten <b>For&#8230;Next<\/b>-Schleifen werden nur ausgef&uuml;hrt, wenn die Variable <b>bol&Atilde;&#8220;-Guelt&Atilde;&#8220;-igePosition <\/b>den Wert <b>True <\/b>hat. Innerhalb der Schleifen, die jeweils von der Koordinate aus <b>intX <\/b>und <b>intY <\/b>aus starten und bei <b>intX + 4 <\/b>beziehungsweise <b>intY + 4 <\/b>enden, wird der Inhalt aus dem Array <b>varAusrichtungsmuster <\/b>in die Variable <b>bolQRBild <\/b>eingef&uuml;gt.<\/p>\n<p>Au&szlig;erdem werden die entsprechenden Bereiche in <b>strMaske <\/b>mit leeren Zeichenketten gef&uuml;llt und somit f&uuml;r das Einf&uuml;llen der eigentlichen Daten des QR-Codes gesperrt.<\/p>\n<p><b>Vorbereitungen zum Einf&uuml;gen des QR-Codes<\/b><\/p>\n<p>Damit w&auml;ren alle Elemente mit Ausnahme des eigentlichen QR-Codes zu den beiden Arrays <b>bolQRBild <\/b>und <b>strMaske <\/b>hinzugef&uuml;gt. Dem Array <b>strMaske <\/b>kommt nun eine besondere Bedeutung zu, denn nun wird unter anderem anhand der Werte in den Feldern festgelegt, wie der eigentliche QR-Code in das Array <b>bolQRBild <\/b>eingef&uuml;gt wird.<\/p>\n<p>Die erste Regel lautet dabei: &uuml;berall, wo sich eine leere Zeichenkette befindet, darf der Code nicht untergebracht werden, da dort schon Finderpatterns und andere Informationen untergebracht sind.<\/p>\n<p>Die zweite Regel betrifft die Reihenfolge, in welcher die Bits des QR-Codes im Array <b>bolQRBild<\/b> landen. Der Code darf n&auml;mlich nicht einfach zeilenweise von links nach rechts in die nicht durch leere Zeichenketten gesperrte Elemente eingetragen werden.<\/p>\n<p>Stattdessen startet das F&uuml;llen der Matrix rechts unten. Grunds&auml;tzlich werden die beiden ersten Spalten von rechts von unten nach oben gef&uuml;llt, dann die beiden n&auml;chsten Spalten von oben nach unten und so weiter (s. Bild 13).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2014_05\/pic_955_022.png\" alt=\"Die Belegung mit dem QR-Code startet rechts unten.\" width=\"500\" height=\"510,929\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 13: Die Belegung mit dem QR-Code startet rechts unten.<\/span><\/b><\/p>\n<p>Da die Spalten paarweise gef&uuml;llt werden, stellt sich die Frage, in welcher Reihenfolge die linke und die rechte Spalte bef&uuml;llt werden. Dies erfolgt durch abwechselndes F&uuml;llen der rechten und der linken Spalte. Als Erstes wird also beispielsweise das Element der ganz rechten Spalte ganz unten gef&uuml;llt, dann das Element links daneben, dann das zweite Element der rechten Spalte, dann wieder das benachbarte Element.<\/p>\n<p>Einige Beispiele hierf&uuml;r finden Sie in Bild 14. Rechts unten etwa k&ouml;nnen Sie erkennen, wie das F&uuml;llen ganz rechts unten beginnt und dann immer abwechselnd von rechts nach links und dann eine Zeile nach oben erfolgt.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2014_05\/pic_955_023.png\" alt=\"Einige Beispiele f&uuml;r das Einf&uuml;gen des QR-Codes im Detail\" width=\"500\" height=\"510,929\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 14: Einige Beispiele f&uuml;r das Einf&uuml;gen des QR-Codes im Detail<\/span><\/b><\/p>\n<p>Wenn der Algorithmus beim Schreiben auf ein Hindernis st&ouml;&szlig;t, sprich: einen gesperrten Bereich, geht es entweder hinter dem Bereich weiter oder die Richtung wird gewechselt.<\/p>\n<p>Das ist etwa rechts der Fall, wenn beim F&uuml;llen die Formatinformationen und dar&uuml;ber das rechte, obere Finderpattern im Weg ist &Atilde;&#162;&#8220;&not;&#8220; dann geht es einfach weiter zu den n&auml;chsten beiden Spalten links von den aktuellen beiden Spalten und in die andere Richtung, hier also nach unten.<\/p>\n<p>Wenn ein Hindernis auftaucht, hinter dem sich noch weitere freie Elemente befinden, dann werden die gesperrten Elemente einfach &uuml;bersprungen.<\/p>\n<p>Ein weiterer Spezialfall liegt vor, wenn auf dem Weg nach oben oder unten nur die linke oder rechte der jeweils durchlaufenen beiden Spalten gesperrt ist. Dann wird der QR-Code einfach in die Spalte geschrieben, die gerade frei ist. Hinter dem Hindernis geht es dann normal &uuml;ber beide Spalten weiter.<\/p>\n<p>Im Code sieht dies folgenderma&szlig;en aus: Eine erste Prozedur namens <b>Koor&Atilde;&#8220;-di&Atilde;&#8220;-na&Atilde;&#8220;-ten&Atilde;&#8220;-Ermitteln <\/b>durchl&auml;uft die Elemente des Arrays <b>strMaske <\/b>und merkt sich dabei die durchlaufenen Koordinaten in zwei weiteren Arrays namens <b>intXKoordinate <\/b>und <b>intYKoordinate<\/b>. Danach f&uuml;llt eine weitere Prozedur die Elemente des Arrays <b>bolQRBild<\/b>, indem es diese beiden Arrays durchl&auml;uft, pr&uuml;ft, welcher Wert aufgrund der Maske und des aktuellen Wertes des QR-Codes eingetragen werden muss, und tr&auml;gt diesen Wert schlie&szlig;lich ein.<\/p>\n<p>Doch schauen wir uns zuerst die Prozedur an, welche den Pfad durch das Array <b>strMaske <\/b>ermittelt (Wenn ich es mir an dieser Stelle recht &uuml;berlege, m&uuml;sste der Pfad eigentlich f&uuml;r jede Version gleich aussehen. Man h&auml;tte die Koordinaten also auch f&uuml;r jede Version einmal durchlaufen und in einer weiteren Tabelle speichern k&ouml;nnen. Aber sparen wir uns doch diese zus&auml;tzliche Tabelle &#8230;).<\/p>\n<p>Die Prozedur <b>KoordinatenErmitteln<\/b> finden Sie in Listing 11. Die Prozedur legt mit <b>intZeile <\/b>zun&auml;chst die Startzeile fest, also die unterste &Atilde;&#162;&#8220;&not;&#8220; dies entspricht dem Wert der als Parameter &uuml;bergebenen Variablen <b>intVersionWidth<\/b>. Die Variable <b>intSpalteRechts <\/b>erh&auml;lt die Startspalte, also die ganz rechte Spalte, ebenfalls aus <b>intVersionWidth<\/b>. <b>intSpalteLinks <\/b>kennzeichnet die Spalte der linken der beiden aktuell bearbeiteten Spalten. Dieser Wert entspricht dem Wert aus <b>intSpalteRechts <\/b>minus eins. Die Variable <b>bolRechteSpalte <\/b>wird auf <b>True<\/b> eingestellt. Diese Variable legt fest, ob wir uns gerade in der linken oder rechten der beiden aktuellen Spalten befinden &Atilde;&#162;&#8220;&not;&#8220; <b>bolRechteSpalte = True <\/b>hei&szlig;t, dass es die rechte Spalte ist. Schlie&szlig;lich initialisiert die Prozedur die Z&auml;hlervariable <b>intZaehler <\/b>mit dem Wert <b>1<\/b> und legt mit <b>bolNachOben <\/b>und dem Wert <b>True <\/b>fest, dass es erstmal nach oben geht.<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>KoordinatenErmitteln(intVersionWidth<span style=\"color:blue;\"> As Integer<\/span>, _\r\n         strMaske()<span style=\"color:blue;\"> As Variant<\/span>, intXKoordinate()<span style=\"color:blue;\"> As Integer<\/span>, _\r\n         intYKoordinate()<span style=\"color:blue;\"> As Integer<\/span>, intModulesToPack<span style=\"color:blue;\"> As Integer<\/span>)\r\n     <span style=\"color:blue;\">Dim <\/span>intZeile<span style=\"color:blue;\"> As Integer<\/span>, intSpalteRechts<span style=\"color:blue;\"> As Integer<\/span>, intSpalteLinks<span style=\"color:blue;\"> As Integer<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>bolRechteSpalte<span style=\"color:blue;\"> As Boolean<\/span>, bolNachOben<span style=\"color:blue;\"> As Boolean<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strBitMaske<span style=\"color:blue;\"> As String<\/span>, intZaehler<span style=\"color:blue;\"> As Integer<\/span>\r\n     intZeile = intVersionWidth\r\n     intSpalteRechts = intVersionWidth\r\n     intSpalteLinks = intSpalteRechts - 1\r\n     bolRechteSpalte = <span style=\"color:blue;\">True<\/span>\r\n     intZaehler = 1\r\n     bolNachOben = <span style=\"color:blue;\">True<\/span>\r\n     Do\r\n         <span style=\"color:blue;\">If <\/span>bolRechteSpalte = <span style=\"color:blue;\">True<\/span> And bolNachOben = <span style=\"color:blue;\">True<\/span><span style=\"color:blue;\"> Then<\/span>\r\n             strBitMaske = strMaske(intZeile, intSpalteRechts)\r\n             <span style=\"color:blue;\">If <\/span>strBitMaske &lt;&gt; \"\" And intZeile &gt; 0<span style=\"color:blue;\"> Then<\/span>\r\n                 intXKoordinate(intZaehler) = intSpalteRechts\r\n                 intYKoordinate(intZaehler) = intZeile\r\n                 bolRechteSpalte = <span style=\"color:blue;\">False<\/span>\r\n                 intZaehler = intZaehler + 1\r\n             <span style=\"color:blue;\">Else<\/span>\r\n                 bolRechteSpalte = <span style=\"color:blue;\">False<\/span>\r\n             <span style=\"color:blue;\">End If<\/span>\r\n         <span style=\"color:blue;\">Else<\/span>If bolRechteSpalte = <span style=\"color:blue;\">False<\/span> And bolNachOben = <span style=\"color:blue;\">True<\/span> Then\r\n             strBitMaske = strMaske(intZeile, intSpalteLinks)\r\n             <span style=\"color:blue;\">If <\/span>strBitMaske &lt;&gt; \"\" And intZeile &gt; 0<span style=\"color:blue;\"> Then<\/span>\r\n                 intXKoordinate(intZaehler) = intSpalteLinks\r\n                 intYKoordinate(intZaehler) = intZeile\r\n                 bolRechteSpalte = <span style=\"color:blue;\">True<\/span>\r\n                 intZaehler = intZaehler + 1\r\n                 intZeile = intZeile - 1\r\n             <span style=\"color:blue;\">Else<\/span>\r\n                 bolRechteSpalte = <span style=\"color:blue;\">True<\/span>\r\n                 intZeile = intZeile - 1\r\n             <span style=\"color:blue;\">End If<\/span>\r\n         <span style=\"color:blue;\">Else<\/span>If bolRechteSpalte = <span style=\"color:blue;\">True<\/span> And bolNachOben = <span style=\"color:blue;\">False<\/span> Then\r\n             strBitMaske = strMaske(intZeile, intSpalteRechts)\r\n             <span style=\"color:blue;\">If <\/span>strBitMaske &lt;&gt; \"\" And intZeile &lt; intVersionWidth + 1<span style=\"color:blue;\"> Then<\/span>\r\n                 intXKoordinate(intZaehler) = intSpalteRechts\r\n                 intYKoordinate(intZaehler) = intZeile\r\n                 bolRechteSpalte = <span style=\"color:blue;\">False<\/span>\r\n                 intZaehler = intZaehler + 1\r\n             <span style=\"color:blue;\">Else<\/span>\r\n                 bolRechteSpalte = <span style=\"color:blue;\">False<\/span>\r\n             <span style=\"color:blue;\">End If<\/span>\r\n         <span style=\"color:blue;\">Else<\/span>If bolRechteSpalte = <span style=\"color:blue;\">False<\/span> And bolNachOben = <span style=\"color:blue;\">False<\/span> Then\r\n             strBitMaske = strMaske(intZeile, intSpalteLinks)\r\n             <span style=\"color:blue;\">If <\/span>strBitMaske &lt;&gt; \"\" And intZeile &lt; intVersionWidth + 1<span style=\"color:blue;\"> Then<\/span>\r\n                 intXKoordinate(intZaehler) = intSpalteLinks\r\n                 intYKoordinate(intZaehler) = intZeile\r\n                 bolRechteSpalte = <span style=\"color:blue;\">True<\/span>\r\n                 intZaehler = intZaehler + 1\r\n                 intZeile = intZeile + 1\r\n             <span style=\"color:blue;\">Else<\/span>\r\n                 bolRechteSpalte = <span style=\"color:blue;\">True<\/span>\r\n                 intZeile = intZeile + 1\r\n             <span style=\"color:blue;\">End If<\/span>\r\n         <span style=\"color:blue;\">End If<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 11: Ermitteln der Koordinaten zum Hinzuf&uuml;gen des QR-Codes (Teil I)<\/span><\/b><\/p>\n<p>Und auf geht es in die erste Schleife &Atilde;&#162;&#8220;&not;&#8220; eine <b>Do While<\/b>-Schleife, die erst endet, wenn die Variable <b>intZaehler <\/b>die Anzahl der abzubildenden Elemente erreicht hat.<\/p>\n<p>In einer ersten <b>If&#8230;Then<\/b>-Bedingung pr&uuml;ft die Prozedur vier F&auml;lle, die alle m&ouml;glichen Werte der beiden Variablen <b>bolRechteSpalte <\/b>und <b>bolNachOben <\/b>kombinieren. Im ersten Fall m&uuml;ssen <b>bolRechteSpalte <\/b>und <b>bolNachOben <\/b>beiden Wert <b>True <\/b>haben. Bedeutet: Wir befinden uns in der rechten der beiden Spalten und bewegen uns nach oben.<\/p>\n<p>Die Variable <b>strBitMaske <\/b>nimmt den Wert des Arrays <b>strMaske <\/b>f&uuml;r die aktuellen Koordinaten aus <b>intZeile <\/b>und <b>intSpalteRechts <\/b>auf. Dies kann entweder der Wert <b>1<\/b>, <b>0 <\/b>oder eine leere Zeichenkette sein. Haben wir keine leere Zeichenkette und der Wert von <b>intZeile <\/b>ist gr&ouml;&szlig;er <b>0 <\/b>(wir haben noch nicht die oberste Zeile erreicht), wird das erste Feld des Arrays <b>intXKoordinate <\/b>auf den Wert von <b>intSpalteRechts <\/b>und das erste Feld des Arrays <b>intYKoordinate <\/b>auf den Wert von <b>intZeile <\/b>eingestellt. <b>bolRechteSpalte <\/b>erh&auml;lt nun den Wert <b>False<\/b>, da wir die rechte der beiden Spalten in der aktuellen Zeile abgearbeitet haben und uns nun die linke Spalte ansehen. Die Z&auml;hlervariable <b>intZaehler <\/b>wird um eins erh&ouml;ht.<\/p>\n<p>Liefert die <b>If&#8230;Then<\/b>-Bedingung, die das aktuelle Element aus <b>strMaske<\/b> pr&uuml;ft, eine leere Zeichenkette, wird einfach nur der Wert von <b>bolRechteSpalte <\/b>auf False eingestellt, damit die Prozedur sich im n&auml;chsten Durchlauf die linke der beiden Spalten f&uuml;r die aktuelle Zeile ansieht.<\/p>\n<p>Der zweite Teil der <b>If&#8230;Then<\/b>-Bedingung untersucht den Fall, dass <b>bolRechteSpalte <\/b>den Wert <b>False <\/b>hat und <b>bolNachOben <\/b>den Wert <b>True<\/b>, was bedeutet: Wir befinden uns auf dem Weg nach oben und untersuchen die linke der beiden aktuellen Spalten. In diesem Fall geschehen prinzipiell die gleichen Schritte wie zuvor, mit kleinen Unterschieden: Falls das aktuelle Element aus <b>strMaske <\/b>den Wert <b>1 <\/b>oder <b>0 <\/b>hat, wird je ein weiteres Element in <b>intXKoordinate <\/b>und <b>intYKoordinate <\/b>mit der aktuellen Zeile und Spalte gef&uuml;llt,  <b>bolRechteSpalte <\/b>wird wieder auf <b>True <\/b>eingestellt und diesmal wird der Wert von <b>intZeile <\/b>um eins verkleinert, weil wir uns ja im n&auml;chsten Schritt weiter nach oben bewegen wollen.<\/p>\n<p>Die beiden weiteren Bedingungen des <b>If&#8230;Then<\/b>-Konstrukts untersuchen noch die beiden entsprechenden F&auml;lle daf&uuml;r, dass <b>bolNachOben <\/b>den Wert <b>False <\/b>enth&auml;lt und die Untersuchung somit von oben nach unten geschieht.<\/p>\n<p>Damit h&auml;tten wir schon einmal alle Koordinaten festlegt: Wir haben alle Elemente des Arrays <b>strMaske <\/b>in der vorgegebenen Reihenfolge durchlaufen und die Koordinaten der Felder gespeichert, die nicht mit einer leeren Zeichenfolge belegt und somit f&uuml;r das Hinzuf&uuml;gen des QR-Codes gesperrt sind.<\/p>\n<p>Nun gibt es noch ein paar Spezialf&auml;lle, die wir behandeln m&uuml;ssen &Atilde;&#162;&#8220;&not;&#8220; zum Beispiel die Richtungsumkehr, wenn wir am oberen Rand ankommen (s. Listing 12). Die notwendige Bedingung lautet, dass <b>intZeile <\/b>den Wert <b>0 <\/b>hat, wir noch nicht an der ersten Spalte angelangt sind (<b>intSpalteRechts > 1<\/b>), <b>bolNachOben <\/b>den Wert <b>True <\/b>hat und wir uns in der rechten Spalte befinden (<b>bolRechteSpalte = True<\/b>).<\/p>\n<pre>        <span style=\"color:blue;\">If <\/span>intZeile = 0 And intSpalteRechts &gt; 1 And bolNachOben = <span style=\"color:blue;\">True<\/span> And bolRechteSpalte = <span style=\"color:blue;\">True<\/span><span style=\"color:blue;\"> Then<\/span>\r\n             intZeile = 1\r\n             bolRechteSpalte = <span style=\"color:blue;\">True<\/span>\r\n             bolNachOben = <span style=\"color:blue;\">False<\/span>\r\n             intSpalteRechts = intSpalteRechts - 2\r\n             <span style=\"color:blue;\">If <\/span>intSpalteRechts = 7<span style=\"color:blue;\"> Then<\/span> intSpalteRechts = 6\r\n             intSpalteLinks = intSpalteRechts - 1\r\n         <span style=\"color:blue;\">Else<\/span>If intZeile = intVersionWidth + 1 And intSpalteRechts &gt; 1 _\r\n                 And bolNachOben = <span style=\"color:blue;\">False<\/span> And bolRechteSpalte = <span style=\"color:blue;\">True<\/span> Then\r\n             intZeile = intVersionWidth\r\n             bolRechteSpalte = <span style=\"color:blue;\">True<\/span>\r\n             bolNachOben = <span style=\"color:blue;\">True<\/span>\r\n             intSpalteRechts = intSpalteRechts - 2\r\n             <span style=\"color:blue;\">If <\/span>intSpalteRechts = 7<span style=\"color:blue;\"> Then<\/span> intSpalteRechts = 6\r\n             intSpalteLinks = intSpalteRechts - 1\r\n         <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">Loop<\/span> Until intZaehler = intModulesToPack + 1\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 12: Ermitteln der Koordinaten zum Hinzuf&uuml;gen des QR-Codes (Teil II)<\/span><\/b><\/p>\n<p>In diesem Fall lenken wir die Richtung um (<b>bolNachOben = False<\/b>), stellen die Zeile wieder auf die erste ein (<b>intZeile = 1<\/b>), beginnen mit der rechten Spalte (<b>bolRechteSpalte = True<\/b>) und verschieben die aktuelle Spalte um zwei Spalten nach links. Au&szlig;erdem wird an dieser Stelle gepr&uuml;ft, ob wir uns aktuell in der siebten Spalte befinden. Diese enth&auml;lt das vertikale Timingpattern, diese Spalte nimmt also gar keine Werte auf &Atilde;&#162;&#8220;&not;&#8220; wir k&ouml;nnen also direkt um eine Zeile weiter nach links rutschen. Da alle Versionen eine ungerade Anzahl von Spalten enthalten, landet die Prozedur auch immer mit der rechten Spalte in der siebten Spalte, sodass wir einfach eine Spalte weiter links fortfahren.<\/p>\n<p>Der zweite Sonderfall ist, dass wir an der untersten Spalte angekommen sind (<b>intZeile = intVersionWidth + 1<\/b>), wir noch nicht die erste Spalte erreicht haben (<b>intSpalteRechts > 1<\/b>), wir uns nach unten bewegen (<b>bolNachOben = False<\/b>) und aktuell die rechte der beiden Spalten bearbeiten.<\/p>\n<p>Dann kehren wir wieder um und wechseln die Richtung nach oben &Atilde;&#162;&#8220;&not;&#8220; die &uuml;brigen Einstellungen stimmen mit denen aus dem vorherigen Sonderfall &uuml;berein. Auf diese Weise f&uuml;llen wir die beiden Variablen <b>intXKoordinate <\/b>und <b>intYKoordinate <\/b>mit den Koordinaten f&uuml;r das Einf&uuml;gen des QR-Codes. Diese geben also den Pfad vor, in dem wir nun die Daten des QR-Codes einf&uuml;llen m&uuml;ssen.<\/p>\n<p><b>QR-Code schreiben<\/b><\/p>\n<p>Im letzten Schritt schreiben wir den QR-Code in das Array <b>bolQRBild<\/b>. Dabei ben&ouml;tigen wir die beiden zuvor gef&uuml;llten Arrays <b>intXKoordinaten <\/b>und <b>intYKoordinaten<\/b>, die angeben, auf welchem Pfad wir die Werte in das Array eintragen. Au&szlig;erdem brauchen wir das Array <b>strMaske<\/b>, da die Werte des QR-Codes ja noch &#8222;maskiert&#8220; werden sollen.<\/p>\n<p>Die Prozedur <b>CodeHinzufuegen<\/b> aus Listing 13 erledigt diese Aufgabe. Sie pr&uuml;ft zun&auml;chst, ob der mit dem Parameter <b>strCode <\/b>gelieferte QR-Code k&uuml;rzer ist als die Anzahl der zu f&uuml;llenden Elemente. In diesem Fall f&uuml;llt die Prozedur die Variable <b>strCode <\/b>mit der entsprechenden Anzahl des Zeichens <b>1 <\/b>auf.<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>CodeHinzufuegen(strcode<span style=\"color:blue;\"> As String<\/span>, intModulesToPack<span style=\"color:blue;\"> As Integer<\/span>, bolQRBild()<span style=\"color:blue;\"> As Boolean<\/span>, _\r\n         strMaske()<span style=\"color:blue;\"> As Variant<\/span>, intXKoordinate()<span style=\"color:blue;\"> As Integer<\/span>, intYKoordinate()<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;\">Dim <\/span>strBit<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Len<\/span>(strcode) &lt; intModulesToPack<span style=\"color:blue;\"> Then<\/span>\r\n         Do\r\n             strcode = strcode + \"1\"\r\n         <span style=\"color:blue;\">Loop<\/span> Until <span style=\"color:blue;\">Len<\/span>(strcode) = intModulesToPack\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     For intZaehler = 1 To intModulesToPack\r\n         strBit = Val(<span style=\"color:blue;\">Mid<\/span>(strcode, intZaehler, 1))\r\n         <span style=\"color:blue;\">If <\/span>strMaske(intXKoordinate(intZaehler), intYKoordinate(intZaehler)) = 0 And strBit = 0<span style=\"color:blue;\"> Then<\/span>\r\n             bolQRBild(intXKoordinate(intZaehler), intYKoordinate(intZaehler)) = -1\r\n         <span style=\"color:blue;\">Else<\/span>If strMaske(intXKoordinate(intZaehler), intYKoordinate(intZaehler)) = 0 And strBit = 1 Then\r\n             bolQRBild(intXKoordinate(intZaehler), intYKoordinate(intZaehler)) = 0\r\n         <span style=\"color:blue;\">Else<\/span>If strMaske(intXKoordinate(intZaehler), intYKoordinate(intZaehler)) = 1 And strBit = 0 Then\r\n             bolQRBild(intXKoordinate(intZaehler), intYKoordinate(intZaehler)) = 0\r\n         <span style=\"color:blue;\">Else<\/span>If strMaske(intXKoordinate(intZaehler), intYKoordinate(intZaehler)) = 1 And strBit = 1 Then\r\n             bolQRBild(intXKoordinate(intZaehler), intYKoordinate(intZaehler)) = -1\r\n         <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">Next<\/span> intZaehler\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 13: F&uuml;llen des Arrays bolQRBild mit den Daten des QR-Codes<\/span><\/b><\/p>\n<p>Dann durchl&auml;uft sie in einer <b>For&#8230;Next<\/b>-Schleife alle in der Zeichenkette <b>strCode <\/b>enthaltenen Zeichen. Als Erstes schreibt sie das Zeichen der aktuellen Position der Zeichenkette <b>strCode <\/b>in die Variable <b>strBit<\/b>. Danach folgt eine <b>If&#8230;Then<\/b>-Bedingung, die vier verschiedene F&auml;lle abdeckt:<\/p>\n<ul>\n<li>Der Wert des Arrays <b>strMaske <\/b>f&uuml;r den in <b>intXKoordinate <\/b>und <b>intYKoordinate <\/b>angegebenen Wert ist <b>0 <\/b>und <b>strBit <\/b>ist ebenfalls <b>0<\/b>, dann wird dem Array <b>strQRBild <\/b>der Wert <b>-1 <\/b>f&uuml;r das entsprechende Element zugewiesen.<\/li>\n<li><b>strMaske <\/b>liefert f&uuml;r die aktuellen Koordinaten den Wert <b>0 <\/b>und <b>strBit <\/b>den Wert <b>1<\/b>, dann erh&auml;lt <b>strQRBild <\/b>den Wert <b>0<\/b>.<\/li>\n<li><b>strMaske <\/b>liefert den Wert <b>1 <\/b>und <b>strBit <\/b>den Wert <b>0<\/b>, dann ist <b>strQRBild <\/b>f&uuml;r die aktuellen Koordinaten ebenfalls <b>0<\/b>.<\/li>\n<li>Fehlt noch der Fall, dass <b>strMaske <\/b>den Wert <b>1 <\/b>liefert und <b>strBit <\/b>ebenfalls den Wert <b>1<\/b>. Dann erh&auml;lt <b>strQRBild <\/b>den Wert <b>-1<\/b>.<\/li>\n<\/ul>\n<p>Auf diese Weise durchl&auml;uft die Schleife alle in den Arrays <b>intXKoordinate <\/b>und <b>intYKoordinate <\/b>und tr&auml;gt f&uuml;r die dort gespeicherten Koordinaten die aus <b>strCode <\/b>und <b>strBit <\/b>ermittelten Werte in das Array <b>bolQRBild <\/b>ein.<\/p>\n<p>Damit sind alle in der Funktion <b>BasisErzeugen <\/b>durchgef&uuml;hrten Schritte erledigt. <\/p>\n<p><b>Bilder erzeugen<\/b><\/p>\n<p>Fehlt noch das Erzeugen der Bilder. Dies geschieht, wenn man die Ausgabe der beiden Zwischenst&auml;nde des Bildes im Formular <b>frmQRCode <\/b>ausl&auml;sst, in zwei Schritten am Ende der Prozedur <b>ImageErzeugen<\/b>. Der erste ist der Aufruf der Prozedur <b>CreatePicture<\/b>. Diese erwartet als Parameter die H&ouml;he und Breite des zu erstellenden Bildes und liefert ein <b>StdPicture<\/b>-Objekt zur&uuml;ck, das genau die gew&uuml;nschen Ma&szlig;e aufweist. Die zweite hei&szlig;t <b>SetQRCode <\/b>und erwartet das soeben erzeugte <b>StdPicture<\/b>-Objekt, das <b>Boolean<\/b>-Array mit den auszugebenden Werten sowie die Dimension des Bildes. Die Prozedur &auml;ndert die Bilddatei so, dass diese die gew&uuml;nschten schwarzen und wei&szlig;en Elemente anzeigt. Das Ergebnis wird in Form des <b>StdPicture<\/b>-Objekts an die aufrufende Prozedur zur&uuml;ckgegeben.<\/p>\n<p>Dies ist die Prozedur <b>cmdImageErzeugen_Click<\/b>, die nun das Bild speichert und die verschiedenen Varianten des Bildes im Formular <b>frmQRCodes <\/b>anzeigt.<\/p>\n<p><b>QR-Code-Erzeugung in eigene Anwendungen einbauen<\/b><\/p>\n<p>Interessant ist nun nat&uuml;rlich, einen QR-Code etwa mit einer Datensatz-ID oder anderen Daten zu erzeugen, die in Zusammenhang mit einem Datensatz einer Datenbank stehen, und diesen dann beispielsweise in einem Bericht auszugeben.<\/p>\n<p>Wichtig ist hier, dass man zuvor pr&uuml;ft, wie viele Zeichen in dem QR-Code untergebracht werden sollen, welche Fehlerkorrektur eingesetzt werden soll und welchen Modus Sie verwenden m&ouml;chten. Ausgehend von diesen Informationen k&ouml;nnen Sie mit dem Formular <b>frmQRCodes <\/b>feststellen, welche Version verwendet werden soll.<\/p>\n<p>Wenn Sie einmal die Parameter ermittelt haben, k&ouml;nnen Sie f&uuml;r Texte, welche die Anzahl der m&ouml;glichen Zeichen nicht &uuml;berschreiten, die Bilddateien mit dem entsprechenden QR-Code durch einen einfachen Funktionsaufruf erstellen. Dieser sieht beispielsweise wie folgt aus:<\/p>\n<pre>QRCodeBildErstellen \"Hallo Welt\", 2, 1, 1, CurrentProject.Path & \"\\pic.png\"<\/pre>\n<p>Die dadurch aufgerufene Funktion <b>QRCodeBildErstellen <\/b>finden Sie in Listing 14. Die Funktion erwartet die folgenden Parameter:<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>QRCodeBildErstellen(strText<span style=\"color:blue;\"> As String<\/span>, lngModeID<span style=\"color:blue;\"> As Long<\/span>, lngVersionID<span style=\"color:blue;\"> As Long<\/span>, _\r\n     lngErrorCorrectionLevelID<span style=\"color:blue;\"> As Long<\/span>, strBildname<span style=\"color:blue;\"> As String<\/span>)<span style=\"color:blue;\"> As Boolean<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strCode<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>objQRCode<span style=\"color:blue;\"> As <\/span>StdPicture\r\n     strCode = QRCodeErstellen(strText, lngModeID, lngVersionID, lngErrorCorrectionLevelID)\r\n     <span style=\"color:blue;\">Set<\/span> objQRCode = ImageErzeugen(lngVersionID, lngErrorCorrectionLevelID, strCode)\r\n     <span style=\"color:blue;\">If <\/span>objQRCode Is Nothing<span style=\"color:blue;\"> Then<\/span>\r\n         <span style=\"color:blue;\">Exit Function<\/span>\r\n     <span style=\"color:blue;\">Else<\/span>\r\n         <span style=\"color:blue;\">If <\/span>SavePicGDIPlus(objQRCode, strBildname, pictypePNG) = <span style=\"color:blue;\">True<\/span><span style=\"color:blue;\"> Then<\/span>\r\n             QRCodeBildErstellen = <span style=\"color:blue;\">True<\/span>\r\n         <span style=\"color:blue;\">End If<\/span>\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 14: Diese Funktion dient der Steuerung des Vorgangs von au&szlig;erhalb des Formulars frmQRCodes<\/span><\/b><\/p>\n<ul>\n<li><b>strText<\/b>: Text, der codiert werden soll<\/li>\n<li><b>lngModeID<\/b>: Zahlenwert f&uuml;r den zu verwendender Mode, also beispielsweise <b>2 <\/b>f&uuml;r <b>Alphanumeric<\/b><\/li>\n<li><b>lngVersionID<\/b>: Zahlenwert f&uuml;r die Version, also etwa <b>2 <\/b>f&uuml;r die Version 25&#215;25 Pixel<\/li>\n<li><b>lngErrorCorrectionLevelID<\/b>: Grad der Fehlerkorrektur entsprechend der Werte der Tabelle <b>tblErrorCorrectionLevels<\/b><\/li>\n<li><b>strBildname<\/b>: Name der zu erzeugenden Bilddatei, muss auf <b>.png <\/b>enden<\/li>\n<\/ul>\n<p>Die Prozedur ermittelt zun&auml;chst den darzustellenden Code, und zwar durch einen Aufruf der Funktion <b>QRCodeErstellen <\/b>mit den gleichen Parametern (au&szlig;er <b>strBildname<\/b>). Danach erzeugt die Funktion <b>ImageErzeugen <\/b>die entsprechende Bilddatei und liefert ein <b>StdPicture<\/b>-Objekt zur&uuml;ck. Sollte dies nicht gelingen, wird die Funktion beendet und liefert als Ergebnis den Wert <b>False <\/b>zur&uuml;ck.<\/p>\n<p>Anderenfalls speichert die Funktion mit der Routine <b>SavePicGDIPlus <\/b>den Inhalt des <b>StdPicture<\/b>-Objekts in eine Datei mit dem Namen aus dem Parameter <b>strBildname<\/b>. Gelingt dies, liefert die Funktion <b>QRBildErstellen <\/b>den Wert <b>True <\/b>zur&uuml;ck und die Bilddatei kann f&uuml;r den gew&uuml;nschten Zweck eingesetzt werden.<\/p>\n<p><b>Zusammenfassung und Ausblick<\/b><\/p>\n<p>Die drei Teile dieser Beitragsreihe haben gezeigt, wie Sie per VBA QR-Codes f&uuml;r Texte erstellen und diese in Form einer <b>.png<\/b>-Datei speichern. Man k&ouml;nnte dies noch so weiterentwickeln, dass man die Daten der Tabellen in Form von Arrays im VBA-Code speichert. Auf diese Weise lie&szlig;e sich die komplette Funktionalit&auml;t in einem einzigen Modul unterbringen, das Sie leicht in eigene Anwendungen einf&uuml;gen und weiterverwenden k&ouml;nnen. Aktuell ist dazu noch das Kopieren der zw&ouml;lf Tabellen sowie der drei Module <b>mdlImageErzeugen, mdlOGL0713 <\/b>und <b>mdlQRCodes <\/b>n&ouml;tig.<\/p>\n<\/p>\n<h2>Downloads zu diesem Beitrag<\/h2>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>QRCodesIII.mdb<\/p>\n<p>QRCodesIII_64.mdb<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/4913BCAF-553F-437D-BACB-09BF2A08F65B\/aiu_955.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Im dritten und letzten Teil der Beitragsreihe zum Thema QR-Codes wollen wir den in den ersten beiden Teilen ermittelten Code zusammen mit den ben&ouml;tigten Markierungen in eine Bilddatei gie&szlig;en und den dabei eingeschlagenen Weg zur besseren Nachvollziehbarkeit Schritt f&uuml;r Schritt in einer Excel-Datei darstellen. Die entstandenen Bilder k&ouml;nnen Sie dann entweder als Bilddatei speichern oder aber direkt in Formularen und Berichten einsetzen.<\/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,66052014,44000027],"tags":[],"class_list":["post-55000955","post","type-post","status-publish","format-standard","hentry","category-662014","category-66052014","category-Loesungen"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.9 (Yoast SEO v27.4) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>QR-Codes mit Access erzeugen, Teil III - 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_III\/\" \/>\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 III\" \/>\n<meta property=\"og:description\" content=\"Im dritten und letzten Teil der Beitragsreihe zum Thema QR-Codes wollen wir den in den ersten beiden Teilen ermittelten Code zusammen mit den ben&ouml;tigten Markierungen in eine Bilddatei gie&szlig;en und den dabei eingeschlagenen Weg zur besseren Nachvollziehbarkeit Schritt f&uuml;r Schritt in einer Excel-Datei darstellen. Die entstandenen Bilder k&ouml;nnen Sie dann entweder als Bilddatei speichern oder aber direkt in Formularen und Berichten einsetzen.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/QRCodes_mit_Access_erzeugen_Teil_III\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2022-03-30T17:32:17+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/vg07.met.vgwort.de\/na\/b0f848c8c23b4d28a2ca5b9348d8713d\" \/>\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=\"39\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_III\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/QRCodes_mit_Access_erzeugen_Teil_III\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"QR-Codes mit Access erzeugen, Teil III\",\"datePublished\":\"2022-03-30T17:32:17+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/QRCodes_mit_Access_erzeugen_Teil_III\\\/\"},\"wordCount\":6399,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/QRCodes_mit_Access_erzeugen_Teil_III\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg07.met.vgwort.de\\\/na\\\/b0f848c8c23b4d28a2ca5b9348d8713d\",\"articleSection\":[\"2014\",\"5\\\/2014\",\"L\u00f6sungen\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/QRCodes_mit_Access_erzeugen_Teil_III\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/QRCodes_mit_Access_erzeugen_Teil_III\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/QRCodes_mit_Access_erzeugen_Teil_III\\\/\",\"name\":\"QR-Codes mit Access erzeugen, Teil III - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/QRCodes_mit_Access_erzeugen_Teil_III\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/QRCodes_mit_Access_erzeugen_Teil_III\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg07.met.vgwort.de\\\/na\\\/b0f848c8c23b4d28a2ca5b9348d8713d\",\"datePublished\":\"2022-03-30T17:32:17+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/QRCodes_mit_Access_erzeugen_Teil_III\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/QRCodes_mit_Access_erzeugen_Teil_III\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/QRCodes_mit_Access_erzeugen_Teil_III\\\/#primaryimage\",\"url\":\"http:\\\/\\\/vg07.met.vgwort.de\\\/na\\\/b0f848c8c23b4d28a2ca5b9348d8713d\",\"contentUrl\":\"http:\\\/\\\/vg07.met.vgwort.de\\\/na\\\/b0f848c8c23b4d28a2ca5b9348d8713d\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/QRCodes_mit_Access_erzeugen_Teil_III\\\/#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 III\"}]},{\"@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 III - 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_III\/","og_locale":"de_DE","og_type":"article","og_title":"QR-Codes mit Access erzeugen, Teil III","og_description":"Im dritten und letzten Teil der Beitragsreihe zum Thema QR-Codes wollen wir den in den ersten beiden Teilen ermittelten Code zusammen mit den ben&ouml;tigten Markierungen in eine Bilddatei gie&szlig;en und den dabei eingeschlagenen Weg zur besseren Nachvollziehbarkeit Schritt f&uuml;r Schritt in einer Excel-Datei darstellen. Die entstandenen Bilder k&ouml;nnen Sie dann entweder als Bilddatei speichern oder aber direkt in Formularen und Berichten einsetzen.","og_url":"https:\/\/access-im-unternehmen.de\/QRCodes_mit_Access_erzeugen_Teil_III\/","og_site_name":"Access im Unternehmen","article_published_time":"2022-03-30T17:32:17+00:00","og_image":[{"url":"http:\/\/vg07.met.vgwort.de\/na\/b0f848c8c23b4d28a2ca5b9348d8713d","type":"","width":"","height":""}],"author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"39\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/QRCodes_mit_Access_erzeugen_Teil_III\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/QRCodes_mit_Access_erzeugen_Teil_III\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"QR-Codes mit Access erzeugen, Teil III","datePublished":"2022-03-30T17:32:17+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/QRCodes_mit_Access_erzeugen_Teil_III\/"},"wordCount":6399,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/QRCodes_mit_Access_erzeugen_Teil_III\/#primaryimage"},"thumbnailUrl":"http:\/\/vg07.met.vgwort.de\/na\/b0f848c8c23b4d28a2ca5b9348d8713d","articleSection":["2014","5\/2014","L\u00f6sungen"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/QRCodes_mit_Access_erzeugen_Teil_III\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/QRCodes_mit_Access_erzeugen_Teil_III\/","url":"https:\/\/access-im-unternehmen.de\/QRCodes_mit_Access_erzeugen_Teil_III\/","name":"QR-Codes mit Access erzeugen, Teil III - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/QRCodes_mit_Access_erzeugen_Teil_III\/#primaryimage"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/QRCodes_mit_Access_erzeugen_Teil_III\/#primaryimage"},"thumbnailUrl":"http:\/\/vg07.met.vgwort.de\/na\/b0f848c8c23b4d28a2ca5b9348d8713d","datePublished":"2022-03-30T17:32:17+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/QRCodes_mit_Access_erzeugen_Teil_III\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/QRCodes_mit_Access_erzeugen_Teil_III\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/QRCodes_mit_Access_erzeugen_Teil_III\/#primaryimage","url":"http:\/\/vg07.met.vgwort.de\/na\/b0f848c8c23b4d28a2ca5b9348d8713d","contentUrl":"http:\/\/vg07.met.vgwort.de\/na\/b0f848c8c23b4d28a2ca5b9348d8713d"},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/QRCodes_mit_Access_erzeugen_Teil_III\/#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 III"}]},{"@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\/55000955","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=55000955"}],"version-history":[{"count":0,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55000955\/revisions"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55000955"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55000955"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55000955"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}