{"id":55000300,"date":"2022-02-01T00:00:00","date_gmt":"2024-03-03T19:36:04","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=300"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"EPCQRCode_fuer_Rechnungen","status":"publish","type":"post","link":"https:\/\/vbentwickler.de\/EPCQRCode_fuer_Rechnungen\/","title":{"rendered":"EPC-QR-Code f&uuml;r Rechnungen"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg02.met.vgwort.de\/na\/8af4ed3265244b13a1c83f39d04f22b8\" width=\"1\" height=\"1\" alt=\"\"><\/p>\n<p><b>Was f&uuml;r eine Erl&ouml;sung! Nach jahrelanger Qu&auml;lerei beim Eintippen ewig langer IBANs und Rechnungsnummern in die Banking-App im Smartphone gibt es mittlerweile nicht nur ein Format f&uuml;r einen QR-Code, der alle notwendigen Daten bereitstellt, sondern auch Banken, deren Banking-App das Einlesen von Rechnungsdaten wie den Zahlungsempf&auml;nger, IBAN, BIC, Verwendungszweck und Zahlungsbetrag aus einem QR-Code erlauben. Noch sch&ouml;ner: Das Format ist &uuml;berschaubar und mithilfe einfacher Erweiterungen zum Erstellen von QR-Codes bauen wir uns unsere eigenen EPC-QR-Codes, die wir unseren Rechnungen hinzuf&uuml;gen k&ouml;nnen. Auf dass unsere Kunden uns feiern, weil sie viel Zeit und Nerven beim Bezahlen unserer Rechnungen sparen!<\/p>\n<p><b>Video passend zu diesem Artikel:<\/b><\/p>\n<div class=\"BorlabsCookie _brlbs-cb-youtube\"><div class=\"_brlbs-content-blocker\"> <div class=\"_brlbs-embed _brlbs-video-youtube\"> <img class=\"_brlbs-thumbnail\" src=\"https:\/\/vbentwickler.de\/wp-content\/plugins\/borlabs-cookie\/assets\/images\/cb-no-thumbnail.png\" alt=\"YouTube\"> <div class=\"_brlbs-caption\"> <p>Mit dem Laden des Videos akzeptieren Sie die Datenschutzerkl\u00e4rung von YouTube.<br><a href=\"https:\/\/policies.google.com\/privacy\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Mehr erfahren<\/a><\/p> <p><a class=\"_brlbs-btn _brlbs-icon-play-white\" href=\"#\" data-borlabs-cookie-unblock role=\"button\">Video laden<\/a><\/p> <p><label><input type=\"checkbox\" name=\"unblockAll\" value=\"1\" checked> <small>YouTube immer entsperren<\/small><\/label><\/p> <\/div> <\/div> <\/div><div class=\"borlabs-hide\" data-borlabs-cookie-type=\"content-blocker\" data-borlabs-cookie-id=\"youtube\"><script type=\"text\/template\">PHA+PGlmcmFtZSBsb2FkaW5nPSJsYXp5IiB3aWR0aD0iNTYwIiBoZWlnaHQ9IjMxNSIgc3JjPSJodHRwczovL3d3dy55b3V0dWJlLW5vY29va2llLmNvbS9lbWJlZC9jWW94b2xmdktKOCIgdGl0bGU9IllvdVR1YmUgdmlkZW8gcGxheWVyIiBmcmFtZWJvcmRlcj0iMCIgYWxsb3c9ImFjY2VsZXJvbWV0ZXI7IGF1dG9wbGF5OyBjbGlwYm9hcmQtd3JpdGU7IGVuY3J5cHRlZC1tZWRpYTsgZ3lyb3Njb3BlOyBwaWN0dXJlLWluLXBpY3R1cmU7IHdlYi1zaGFyZSIgYWxsb3dmdWxsc2NyZWVuPjwvaWZyYW1lPg==<\/script><\/div><\/div><\/b><\/p>\n<h2>Der EPC-QR-Code oder GiroCode<\/h2>\n<p>Der EPC-QR-Code, der auch als GiroCode bekannt ist, wurde vom European Payments Council standardisiert. Der QR-Code enth&auml;lt alle notwendigen Informationen f&uuml;r eine SEPA-&Uuml;berweisung, also beispielsweise f&uuml;r &Uuml;berweisungen im deutschen Zahlungsraum. Der QR-Code erfasst neben einigen technischen Daten die folgenden Informationen.<\/p>\n<p>Es gibt zwei Versionen, deren Anforderungen sich unwesentlich unterscheiden &#8211; hier ist die von uns verwendete mit BIC als Pflichtangabe:<\/p>\n<ul>\n<li>BIC der Empf&auml;ngerbank: Verpflichtend nur in Version 1.<\/li>\n<li>Name des Zahlungsempf&auml;ngers (maximal 70 Zeichen)<\/li>\n<li>IBAN des Empf&auml;ngerkontos<\/li>\n<li>Zahlungsbetrag im Format <b>EUR#.##<\/b><\/li>\n<li>Zweck nach dem DTA-Verfahren (optional)<\/li>\n<li>Referenz als 35-Zeichen-Code gem&auml;&szlig; ISO 116 RF Creditor Reference (optional)<\/li>\n<li>Verwendungszweck: maximal 140 Zeichen langer Text (optional)<\/li>\n<\/ul>\n<p>Ein Beispiel f&uuml;r einen EPC-QR-Code mit den relevanten Informationen sieht wie in Bild 1 aus.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2022_01\/pic_300_003.png\" alt=\"Beispiel f&uuml;r einen EPC-QR-Code\" width=\"374,6267\" height=\"427,7996\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Beispiel f&uuml;r einen EPC-QR-Code<\/span><\/b><\/p>\n<p>Der in diesem EPC-QR-Code kodierte Text lautet wie folgt:<\/p>\n<pre>BCD\r\n001\r\n1\r\nSCT\r\nBFSWDE33BER\r\nSpende fuer Wikipedia\r\nDE33100205000001194700\r\nEUR10.00\r\nWikimedia Foerdergesellschaft<\/pre>\n<h2>In diesem Artikel<\/h2>\n<p>In diesem Artikel erstellen wir eine L&ouml;sung, mit der wir die Daten, die im EPC-QR-Code abgebildet werden sollen, eingeben und das Ergebnis direkt als Bilddatei im Fenster der Anwendung anzeigen k&ouml;nnen.<\/p>\n<p>In einem weiteren Artikel namens <b>EPC-QR-Code per DLL <\/b>(<b>www.datenbankentwickler.net\/301<\/b>) schauen wir uns an, wie wir eine handliche DLL programmieren k&ouml;nnen, die wir unter anderem per VBA nutzen k&ouml;nnen &#8211; beispielsweise, um Access-Rechnungsberichte mit diesem EPC-QR-Code zu versehen.<\/p>\n<h2>Win-Win<\/h2>\n<p>Dadurch, dass der Rechnungsempf&auml;nger keine Daten mehr manuell von der Rechnung ablesen und in das Onlineformular einer &Uuml;berweisung eingeben muss, entstehen zwei wesentliche Vorteile: der Empf&auml;nger spart sehr viel Zeit und Empf&auml;nger und Rechnungsersteller profitieren davon, dass keine Fehler mehr beim Eingeben der &Uuml;berweisungsdaten entstehen.<\/p>\n<h2>Anlegen des Projekts<\/h2>\n<p>Wir erstellen das Projekt als WPF-App mit Visual Basic als Sprache und speichern es unter dem Namen <b>QRUeberweisung<\/b>.<\/p>\n<h2>NuGet-Paket zum Erstellen von QR-Codes hinzuf&uuml;gen<\/h2>\n<p>Mit einem Klick auf den Men&uuml;befehl <b>Projekt|NuGet-Pakete verwalten&#8230; <\/b>&ouml;ffnen wir den <b>NuGet-Paket-Manager<\/b>. Hier suchen wir im Bereich <b>Durchsuchen <\/b>nach Eintr&auml;gen, die dem Suchbegriff <b>qr code <\/b>entsprechen und finden zum Beispiel den Eintrag <b>QrCode.Net<\/b>, den wir f&uuml;r dieses Projekt nutzen wollen.<\/p>\n<p>Ein Klick auf die Schaltfl&auml;che <b>Installieren<\/b> f&uuml;gt das NuGet-Paket zum Projekt hinzu (siehe Bild 2).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2022_01\/pic_300_001.png\" alt=\"NuGet-Paket zum Erstellen von QR-Codes hinzuf&uuml;gen\" width=\"700\" height=\"417,6292\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 2: NuGet-Paket zum Erstellen von QR-Codes hinzuf&uuml;gen<\/span><\/b><\/p>\n<h2>Fenster zur Eingabe der ben&ouml;tigten Daten programmieren<\/h2>\n<p>Die Daten wie BIC, IBAN, Empf&auml;nger, Verwendungszweck und Betrag wollen wir &uuml;ber ein Fenster eingeben k&ouml;nnen. Neben den entsprechenden Textfeldern soll das Fenster noch eine Schaltfl&auml;che enthalten, mit der wir den QR-Code erstellen.<\/p>\n<p>Au&szlig;erdem m&ouml;chten wir zu Testzwecken schnell ein paar Testdaten in die Textfelder f&uuml;llen. Das Beispielformular soll schlie&szlig;lich wie in Bild 3 aussehen.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2022_01\/pic_300_002.png\" alt=\"Beispielfenster zum Eingeben und Erstellen von EPC-QR-Codes\" width=\"649,627\" height=\"380,2422\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 3: Beispielfenster zum Eingeben und Erstellen von EPC-QR-Codes<\/span><\/b><\/p>\n<p>Schlie&szlig;lich wollen wir noch eine Schaltfl&auml;che bereitstellen, mit welcher der Benutzer eine Datei mit dem erzeugten EPC-QR-Code auf der Festplatte speichern k&ouml;nnen soll.<\/p>\n<p>Der XAML-Code f&uuml;r das Fenster sieht wie folgt aus, wobei wir hier f&uuml;r eine h&uuml;bschere Optik ein Icon namens <b>qr_code.ico <\/b>hinzugef&uuml;gt haben, das im Projekt in einem Ordner namens <b>images <\/b>gespeichert ist:<\/p>\n<pre>&lt;Window x:Class=\"MainWindow\" ... Title=\"Beispiel EPC-QR-Code\" Height=\"350\" Width=\"600\" WindowStartupLocation=\"CenterScreen\" Icon=\"Images\/qr_code.ico\"&gt;<\/pre>\n<p>Damit wir einige Einstellungen nicht f&uuml;r jedes Textfeld und jeden Button definieren m&uuml;ssen, haben wir diese im Bereich <b>Window.Resources <\/b>definiert:<\/p>\n<pre>     &lt;Window.Resources&gt;\r\n         &lt;Style TargetType=\"TextBox\"&gt;\r\n             &lt;Setter Property=\"Margin\" Value=\"5\"&gt;&lt;\/Setter&gt;\r\n             &lt;Setter Property=\"Padding\" Value=\"5\"&gt;&lt;\/Setter&gt;\r\n             &lt;Setter Property=\"HorizontalAlignment\" Value=\"Left\"&gt;&lt;\/Setter&gt;\r\n         &lt;\/Style&gt;\r\n         &lt;Style TargetType=\"Button\"&gt;\r\n             &lt;Setter Property=\"Margin\" Value=\"5\"&gt;&lt;\/Setter&gt;\r\n             &lt;Setter Property=\"Padding\" Value=\"5\"&gt;&lt;\/Setter&gt;\r\n             &lt;Setter Property=\"HorizontalAlignment\" Value=\"Left\"&gt;&lt;\/Setter&gt;\r\n         &lt;\/Style&gt;\r\n     &lt;\/Window.Resources&gt;<\/pre>\n<p>Die Zeilen und Spalten des Grids haben wir wie folgt definiert, um die Steuerelemente strukturiert anlegen zu k&ouml;nnen:<\/p>\n<pre>     &lt;Grid&gt;\r\n         &lt;Grid.RowDefinitions&gt;\r\n             &lt;RowDefinition Height=\"Auto\"&gt;&lt;\/RowDefinition&gt;\r\n             &lt;RowDefinition Height=\"Auto\"&gt;&lt;\/RowDefinition&gt;\r\n             &lt;RowDefinition Height=\"Auto\"&gt;&lt;\/RowDefinition&gt;\r\n             &lt;RowDefinition Height=\"Auto\"&gt;&lt;\/RowDefinition&gt;\r\n             &lt;RowDefinition Height=\"Auto\"&gt;&lt;\/RowDefinition&gt;\r\n             &lt;RowDefinition Height=\"Auto\"&gt;&lt;\/RowDefinition&gt;\r\n             &lt;RowDefinition Height=\"*\"&gt;&lt;\/RowDefinition&gt;\r\n         &lt;\/Grid.RowDefinitions&gt;\r\n         &lt;Grid.ColumnDefinitions&gt;\r\n             &lt;ColumnDefinition Width=\"Auto\"&gt;&lt;\/ColumnDefinition&gt;\r\n             &lt;ColumnDefinition Width=\"Auto\"&gt;&lt;\/ColumnDefinition&gt;\r\n             &lt;ColumnDefinition Width=\"Auto\"&gt;&lt;\/ColumnDefinition&gt;\r\n             &lt;ColumnDefinition Width=\"*\"&gt;&lt;\/ColumnDefinition&gt;\r\n         &lt;\/Grid.ColumnDefinitions&gt;<\/pre>\n<h2>Steuerelemente des Fensters<\/h2>\n<p>Danach folgen bereits die Definitionen f&uuml;r die Steuerelemente.<\/p>\n<p>Das erste ist das Eingabefeld f&uuml;r den Bank Identifier Code (BIC) und wird samt Bezeichnungsfeld wie folgt definiert, wobei wir die maximale Anzahl Zeichen auf 11 Zeichen begrenzt haben:<\/p>\n<pre>         &lt;Label&gt;BIC:&lt;\/Label&gt;\r\n         &lt;TextBox x:Name=\"txtBIC\" Grid.Column=\"1\" Width=\"100\" MaxLength=\"11\"&gt;&lt;\/TextBox&gt;<\/pre>\n<p>Das Textfeld <b>txtZahlungsempfaenger<\/b> f&uuml;r den Zahlungsempf&auml;nger darf bis zu 70 Zeichen lang sein:<\/p>\n<pre>         &lt;Label Grid.Row=\"1\"&gt;Zahlungsempf&auml;nger:&lt;\/Label&gt;\r\n         &lt;TextBox x:Name=\"txtZahlungsempfaenger\" Grid.Row=\"1\" Grid.Column=\"1\" Width=\"250\" MaxLength=\"70\"&gt;&lt;\/TextBox&gt;<\/pre>\n<p>Die <b>International Bank Account Number <\/b>(<b>IBAN<\/b>) darf maximal 34 Zeichen enthalten und wird in dem wie folgt definierten Textfeld <b>txtIBAN <\/b>eingegeben:<\/p>\n<pre>         &lt;Label Grid.Row=\"2\"&gt;IBAN:&lt;\/Label&gt;\r\n         &lt;TextBox x:Name=\"txtIBAN\" Grid.Row=\"2\" Grid.Column=\"1\" Width=\"250\" MaxLength=\"34\"&gt;&lt;\/TextBox&gt;<\/pre>\n<p>F&uuml;r die Eingabe des Betrags haben wir eine Validierung eingebaut, die lediglich die Eingabe von Zahlen und maximal einem Komma erlaubt. Die Validierung erfolgt in der Methode <b>PreviewTextInput<\/b> und die Definition des Textfeldes sieht wie folgt aus, die Methode f&uuml;r das <b>PreviewTextInput<\/b>-Attribut schauen wir uns weiter unten an:<\/p>\n<pre>         &lt;Label Grid.Row=\"3\"&gt;Betrag:&lt;\/Label&gt;\r\n         &lt;TextBox x:Name=\"txtBetrag\" Grid.Row=\"3\" Grid.Column=\"1\" Width=\"100\"             PreviewTextInput=\"txtBetrag_PreviewTextInput\"&gt;&lt;\/TextBox&gt;<\/pre>\n<p>Auch der Verwendungszweck hat eine begrenzte Zeichenzahl, n&auml;mlich 140. Hier k&ouml;nnen Sie allerdings Zeilenumbr&uuml;che einf&uuml;gen, in diesem Fall per Eingabetaste. Damit die Eingabetaste als Zeilenumbruch erkannt wird, stellen wir f&uuml;r das Textfeld <b>txtVerwendungszweck <\/b>das Attribut <b>AccepptReturns <\/b>auf <b>True <\/b>ein. Auch sollen Zeilen, die &uuml;ber die Textfeldbreite hinausragen, umgebrochen werden, was wir durch den Wert <b>Wrap <\/b>f&uuml;r das Attribut <b>Wrapping <\/b>erreichen:<\/p>\n<pre>         &lt;Label Grid.Row=\"4\"&gt;Verwendungszweck:&lt;\/Label&gt;\r\n         &lt;TextBox x:Name=\"txtVerwendungszweck\" Grid.Row=\"4\" Grid.Column=\"1\" Height=\"100\" Width=\"250\" TextWrapping=\"Wrap\" AcceptsReturn=\"True\" MaxLength=\"140\"&gt;&lt;\/TextBox&gt;<\/pre>\n<h2>Schaltfl&auml;chen des Fensters<\/h2>\n<p>Damit kommen wir zu den beiden unteren Schaltfl&auml;chen, die wir in einem <b>StackPanel<\/b>-Element organisieren, das sich in der f&uuml;nften Zeile befindet und zwei Spalten umfasst. Die erste Schaltfl&auml;che hei&szlig;t <b>btnErstellen<\/b>, die zweite <b>btnBeispieldaten<\/b>. Auch ihre Ereignismethoden stellen wir weiter unten vor:<\/p>\n<pre>         &lt;StackPanel Orientation=\"Horizontal\" Grid.Row=\"5\" Grid.Column=\"0\" Grid.ColumnSpan=\"2\"&gt;\r\n             &lt;Button x:Name=\"btnErstellen\" Click=\"btnErstellen_Click\"&gt;QR Code erstellen&lt;\/Button&gt;\r\n             &lt;Button x:Name=\"btnBeispieldaten\" Click=\"btnBeispieldaten_Click\"&gt;Beispieldaten einf&uuml;gen&lt;\/Button&gt;\r\n         &lt;\/StackPanel&gt;<\/pre>\n<h2>Image-Steuerelement und Speichern-Schaltfl&auml;che<\/h2>\n<p>Schlie&szlig;lich folgen noch Steuerelemente, die einen Bereich einnehmen, der sich in der dritten Spalte &uuml;ber die oberen f&uuml;nf Zeilen erstreckt, wobei diese wiederum in einem <b>StackPanel<\/b>-Element zusammengefasst werden. Das Image-Steuerelement zur Anzeige des EPC-QR-Codes hei&szlig;t <b>imgQRCode <\/b>und die Schaltfl&auml;che zum Speichern nennen wir <b>btnSpeichern<\/b>:<\/p>\n<pre>         &lt;StackPanel Orientation=\"Vertical\" Grid.Column=\"3\" Grid.Row=\"0\" Grid.RowSpan=\"5\"&gt;\r\n             &lt;Label&gt;QR-Code:&lt;\/Label&gt;\r\n             &lt;Border BorderBrush=\"#FFABADB3\"  BorderThickness=\"1\" VerticalAlignment=\"Top\"                     HorizontalAlignment=\"Left\" Margin=\"5\"&gt;\r\n                 &lt;Image x:Name=\"imgQRCode\" Stretch=\"None\" Margin=\"5\" Width=\"180\" Height=\"180\" &gt;&lt;\/Image&gt;\r\n             &lt;\/Border&gt;\r\n             &lt;Button x:Name=\"btnSpeichern\" Click=\"btnSpeichern_Click\"&gt;Speichern unter ...&lt;\/Button&gt;\r\n         &lt;\/StackPanel&gt;\r\n     &lt;\/Grid&gt;\r\n&lt;\/Window&gt;<\/pre>\n<p>Der Entwurf sieht schlie&szlig;lich wie in Bild 4 aus.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2022_01\/pic_300_004.png\" alt=\"Entwurf des Fensters\" width=\"649,627\" height=\"386,2645\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 4: Entwurf des Fensters<\/span><\/b><\/p>\n<h2>Validierung des Betrags<\/h2>\n<p>Damit der Benutzer nur Zahlen und maximal ein Komma in das Feld <b>txtBetrag <\/b>eingeben kann, haben wir eine Ereignismethode erstellt, die durch das Ereignis <b>PreviewTextInput <\/b>ausgel&ouml;st wird, also bevor der eingegebene Text im Textfeld erscheint.<\/p>\n<p>Die Methode referenziert als Erstes den mit dem Parameter <b>sender <\/b>gelieferten Verweis auf das <b>TextBox<\/b>-Element. Der zweite Parameter liefert &uuml;brigens &uuml;ber die Eigenschaft <b>e.Text<\/b> den soeben eingegebenen Text.<\/p>\n<p>Die Methode weist der Variablen <b>bolKomma <\/b>einen Wert zu, der von drei verschachtelten Bedingungen rund um die Eingabe von Kommas abh&auml;ngt. Die erste schaut, ob noch kein Komma vorhanden ist (<b>txt.Text.IndexOf(&#8220;,&#8221;) < 0<\/b>), die zweite, ob das aktuell eingegebene Zeichen ein Komma ist (<b>e.Text.Equals(&#8220;,&#8221;)<\/b>) und die dritte, ob das Textfeld &uuml;berhaupt schon ein Zeichen enth&auml;lt (<b>txt.Text.Length > 0<\/b>). Sind alle drei <b>True<\/b>, wurde ein Komma korrekterweise hinzugef&uuml;gt und <b>bolKomma <\/b>erh&auml;lt ebenfalls den Wert <b>True<\/b>.<\/p>\n<p>Die folgende <b>If&#8230;Then<\/b>-Bedingung pr&uuml;ft dann zwei mit dem Operator <b>OrElse <\/b>verkn&uuml;pfte Bedingungen. Pr&uuml;fen wir mit <b>OrElse<\/b>, reicht es schon aus, wenn die erste der beiden Bedingungen <b>True <\/b>ist &#8211; dann wird die zweite gar nicht mehr gepr&uuml;ft.<\/p>\n<p>Die erste Bedingung pr&uuml;ft, ob es sich bei dem eingegebenen Zeichen um eine Zahl handelt. Falls ja, ist der gesamte Ausdruck in den Klammern <b>True <\/b>und mit dem vorangestellten <b>Not <\/b>ist die Bedingung <b>False<\/b>. Dann wird <b>e.Handled <\/b>nicht auf <b>True <\/b>eingestellt, was sonst bewirken w&uuml;rde, dass das Zeichen nicht geschrieben wird.<\/p>\n<p>Ist das Zeichen keine Zahl, kann es beispielsweise ein Buchstabe oder ein Komma sein. Ob es ein Komma ist, haben wir oben gepr&uuml;ft und das Ergebnis in <b>bolKomma <\/b>geschrieben. Ist der Text also keine Zahl, aber ein Komma, ist das Ergebnis der <b>If&#8230;Then<\/b>-Bedingung immer noch <b>False <\/b>und <b>e.Handled <\/b>bleibt auch <b>False<\/b>. Ist <b>bolKomma <\/b>hingegen <b>False<\/b>, dann hat der Benutzer offensichtlich weder eine Zahl noch ein Komma eingegeben und <b>e.Handled <\/b>wird auf <b>True <\/b>eingestellt. Damit wird das eingegebene Zeichen nicht in das Textfeld &uuml;bertragen:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>txtBetrag_PreviewTextInput(sender<span style=\"color:blue;\"> As Object<\/span>, e<span style=\"color:blue;\"> As <\/span>TextCompositionEventArgs)\r\n     <span style=\"color:blue;\">Dim <\/span>result<span style=\"color:blue;\"> As Decimal<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>txt<span style=\"color:blue;\"> As <\/span>TextBox\r\n     <span style=\"color:blue;\">Dim <\/span>bolKomma<span style=\"color:blue;\"> As Boolean<\/span>\r\n     txt = CType(sender, TextBox)\r\n     bolKomma = txt.Text.IndexOf(\",\") &lt; 0 AndAlso e.Text.Equals(\",\") AndAlso txt.Text.Length &gt; 0\r\n     <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> (Decimal.TryParse(e.Text, result) OrElse bolKomma)<span style=\"color:blue;\"> Then<\/span>\r\n         e.Handled = <span style=\"color:blue;\">True<\/span>\r\n     <span style=\"color:blue;\">End If<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Auf diese Weise pr&uuml;fen wir zuverl&auml;ssig, dass der Benutzer nur Zahlen und maximal ein Komma eingibt, also beispielsweise <b>12,95<\/b>.<\/p>\n<h2>Beispieldaten in die Textfelder schreiben<\/h2>\n<p>Wenn man solche Beispiele programmiert, m&ouml;chte man nicht bei jedem Neustart des Projekts die Daten erneut eingeben. Also haben wir f&uuml;r die Schaltfl&auml;che <b>btnBeispieldaten <\/b>eine kleine Methode hinterlegt, welche die Felder automatisch mit Beispieldaten f&uuml;llt &#8211; hier mit den Daten von Wikipedia:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>btnBeispieldaten_Click(sender<span style=\"color:blue;\"> As Object<\/span>, e<span style=\"color:blue;\"> As <\/span>RoutedEventArgs)\r\n     txtBetrag.Text = \"10\"\r\n     txtBIC.Text = \"BFSWDE33BER\"\r\n     txtIBAN.Text = \"DE33100205000001194700\"\r\n     txtVerwendungszweck.Text = \"Wikimedia Foerdergesellschaft\"\r\n     txtZahlungsempfaenger.Text = \"Spende fuer Wikipedia\"\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<h2>EPC-QR-Code zusammenstellen<\/h2>\n<p>Die zweite Schaltfl&auml;che stellt nun endlich den Code zusammen, den wir f&uuml;r das Erstellen des EPC-QR-Codes auf Basis der eingegebenen Daten ben&ouml;tigen. Bevor wir diesen beschreiben, f&uuml;gen wir noch die ben&ouml;tigten <b>Namespace<\/b>-Verweise hinzu:<\/p>\n<pre>Imports Gma.QrCodeNet.Encoding\r\nImports Gma.QrCodeNet.Encoding.Windows.Render\r\nImports System.Drawing<\/pre>\n<p>Au&szlig;erdem deklarieren wir innerhalb der Klasse <b>MainWindow <\/b>die folgende Variable, mit der wir das zu erstellende <b>Bitmap<\/b>-Element referenzieren. Dieses referenzieren wir nicht in der nachfolgend beschriebenen Methode, weil wir noch in einer weiteren Methode auf dieses zugreifen wollen:<\/p>\n<pre><span style=\"color:blue;\">Dim <\/span>objBMP<span style=\"color:blue;\"> As <\/span>Bitmap<\/pre>\n<p>Die Methode <b>btnErstellen<\/b> deklariert einige Variablen:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>btnErstellen_Click(sender<span style=\"color:blue;\"> As Object<\/span>, e<span style=\"color:blue;\"> As <\/span>RoutedEventArgs)\r\n     <span style=\"color:blue;\">Dim <\/span>objQREncoder<span style=\"color:blue;\"> As <\/span>QrEncoder\r\n     <span style=\"color:blue;\">Dim <\/span>objQRCode<span style=\"color:blue;\"> As <\/span>QrCode\r\n     <span style=\"color:blue;\">Dim <\/span>objFixedModuleSize<span style=\"color:blue;\"> As <\/span>FixedModuleSize\r\n     <span style=\"color:blue;\">Dim <\/span>objGraphics<span style=\"color:blue;\"> As <\/span>Graphics\r\n     <span style=\"color:blue;\">Dim <\/span>strText<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>objGraphicsRenderer<span style=\"color:blue;\"> As <\/span>GraphicsRenderer<\/pre>\n<p>Danach stellt sie den Text zusammen, der im QR-Code kodiert werden soll. Einige Elemente sind fix, andere beziehen wir aus den verschiedenen Textfeldern:<\/p>\n<pre>     strText = \"BCD\" & <span style=\"color:blue;\">vbCrLf<\/span>\r\n     strText = strText & \"001\" & <span style=\"color:blue;\">vbCrLf<\/span>\r\n     strText = strText & \"1\" & <span style=\"color:blue;\">vbCrLf<\/span>\r\n     strText = strText & \"SCT\" & <span style=\"color:blue;\">vbCrLf<\/span>\r\n     strText = strText & txtBIC.Text & <span style=\"color:blue;\">vbCrLf<\/span>\r\n     strText = strText & txtZahlungsempfaenger.Text & <span style=\"color:blue;\">vbCrLf<\/span>\r\n     strText = strText & txtIBAN.Text & <span style=\"color:blue;\">vbCrLf<\/span>\r\n     strText = strText & \"EUR\" & String.Format(\"{0:0.00}\", CDec(txtBetrag.Text)).<span style=\"color:blue;\">Replace<\/span>(\",\", \".\") & <span style=\"color:blue;\">vbCrLf<\/span>\r\n     strText = strText & \"\" & <span style=\"color:blue;\">vbCrLf<\/span>\r\n     strText = strText & \"\" & <span style=\"color:blue;\">vbCrLf<\/span>\r\n     strText = strText & txtVerwendungszweck.Text & <span style=\"color:blue;\">vbCrLf<\/span><\/pre>\n<p>Danach folgen die interessanten Schritte. Als Erstes legen wir fest, wie gro&szlig; die einzelnen Module des QR-Codes sein sollen, also wieviele Pixel Breite und H&ouml;he eines der wei&szlig;en oder schwarzen Quadrate im QR-Code einnehmen soll. Diese Information hinterlegen wir in einem Objekt des Typs <b>FixedModuleSize<\/b>.<\/p>\n<p>Wir w&auml;hlen den Wert <b>2 <\/b>aus, was bedeutet, dass eines der wei&szlig;en oder schwarzen Elemente 2&#215;2 Pixel gro&szlig; ist:<\/p>\n<pre>     objFixedModuleSize = <span style=\"color:blue;\">New<\/span> FixedModuleSize(2, QuietZoneModules.Two)<\/pre>\n<p>Dann legen wir fest, wie der QR-Code gerendert werden soll, also mit welcher Modulgr&ouml;&szlig;e und mit welchen Farben. Statt den mit dem zweiten und dritten Parameter beim Initialisieren der <b>GraphicsRenderer<\/b>-Klasse angegebenen Farben <b>Brushes.Black <\/b>und <b>Brushes.White <\/b>k&ouml;nnen Sie auch andere Farben angeben (Sie fragen sich, ob der QR-Code anschlie&szlig;end gelesen werden kann? Wir haben es mit einem invertierten QR-Code probiert und es hat funktioniert!):<\/p>\n<pre>     objGraphicsRenderer = <span style=\"color:blue;\">New<\/span> GraphicsRenderer(objFixedModuleSize, Brushes.Black, Brushes.White)<\/pre>\n<p>Danach erstellt die Methode ein neues <b>QrEncode<\/b>-Element, dem wir lediglich den zu verwendenden Fehlerkorrekturlevel mitgeben. F&uuml;r EPC-QR-Codes ist immer der Fehlerkorrekturlevel <b>M <\/b>zu verwenden:<\/p>\n<pre>     objQREncoder = <span style=\"color:blue;\">New<\/span> QrEncoder(ErrorCorrectionLevel.M)<\/pre>\n<p>Damit k&ouml;nnen wir nun die Kodierung vornehmen. Achtung: Damit haben wir noch nicht die Matrix erstellt &#8211; das geschieht erst im Anschluss:<\/p>\n<pre>     objQRCode = objQREncoder.Encode(strText)<\/pre>\n<p>Die Matrix wollen wir in irgendeinem Objekt als Bild abbilden, daher definieren wir nun ein neues Bitmap-Element. Diesem &uuml;bergeben wir beim Erstellen die H&ouml;he und die Breite. Diese berechnen wir aus der Breite und H&ouml;he der Matrix, die wir jeweils mit 2 multipilizieren und dann noch 8 acht hinzu addieren.<\/p>\n<p>Warum das? Weiter oben haben wir festgelegt, dass wir jedes Modul des Codes auf 2&#215;2 Pixeln abbilden wollen. Also m&uuml;ssen wir im Bitmap entsprechenden Platz vorsehen. Die Addition des Wertes 8 f&uuml;hren wir durch, damit wir auf jeder Seite noch vier Pixel Rand erhalten. Wenn Sie keinen Rand w&uuml;nschen, entfernen Sie einfach die Addition von 8:<\/p>\n<pre>     objBMP = <span style=\"color:blue;\">New<\/span> Bitmap(objQRCode.Matrix.Width * 2 + 8, objQRCode.Matrix.Height * 2 + 8)<\/pre>\n<p>Dann erstellen wir ein <b>Graphics<\/b>-Element auf Basis des <b>Bitmap<\/b>-Elements und referenzieren es mit <b>objGraphics<\/b>:<\/p>\n<pre>     objGraphics = Graphics.FromImage(objBMP)<\/pre>\n<p>Die Matrix des QR-Codes &uuml;bertragen wir schlie&szlig;lich mit der <b>Draw<\/b>-Methode von <b>objGraphicsRenderer <\/b>in <b>objGraphics<\/b>, wodurch automatisch das davon referenzierte <b>Bitmap<\/b>-Element aus <b>objBMP <\/b>damit gef&uuml;llt wird:<\/p>\n<pre>     objGraphicsRenderer.Draw(objGraphics, objQRCode.Matrix)<\/pre>\n<p>Dieses wollen wir nun noch im <b>Image<\/b>-Steuerelement <b>imgQRCode <\/b>abbilden. Dazu wandeln wir es mit der Funktion <b>BitmapToImageSource <\/b>in ein entsprechendes Format um und weisen es der Eigenschaft <b>Source <\/b>des <b>Image<\/b>-Elements <b>imgQRCode <\/b>zu:<\/p>\n<pre>     imgQRCode.Source = BitmapToImageSource(objBMP)\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<h2>Funktion zum Umwandeln des Bitmap in ein ImageSource-Element<\/h2>\n<p>Der Vollst&auml;ndigkeit halber hier der Code der Funktion <b>BitmapToImageSource<\/b>. Diese erwartet einen Verweis auf ein <b>Bitmap<\/b>-Element und liefert ein <b>BitmapImage<\/b>-Element zur&uuml;ck. Dabei speichert sie das <b>Bitmap<\/b>-Element zun&auml;chst in ein <b>MemoryStream<\/b>-Objekt. Dann legt sie ein neues <b>BitmapImage<\/b>-Element an und f&uuml;llt dieses mit den Informationen aus objMemoryStream. Das Ergebnis gibt sie als Funktionswert zur&uuml;ck:<\/p>\n<pre><span style=\"color:blue;\">Private Function <\/span>BitmapToImageSource(ByVal objBitmap<span style=\"color:blue;\"> As <\/span>Bitmap)<span style=\"color:blue;\"> As <\/span>BitmapImage\r\n     Using objMemoryStream<span style=\"color:blue;\"> As <\/span>MemoryStream = <span style=\"color:blue;\">New<\/span> MemoryStream()\r\n         objBitmap.Save(objMemoryStream, Imaging.ImageFormat.Bmp)\r\n         objMemoryStream.Position = 0\r\n         <span style=\"color:blue;\">Dim <\/span>objBitmapimage<span style=\"color:blue;\"> As <\/span>BitmapImage = <span style=\"color:blue;\">New<\/span> BitmapImage()\r\n         objBitmapimage.BeginInit()\r\n         objBitmapimage.StreamSource = objMemoryStream\r\n         objBitmapimage.CacheOption = BitmapCacheOption.OnLoad\r\n         objBitmapimage.EndInit()\r\n         Return objBitmapimage\r\n     End Using\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p>F&uuml;r die Verwendung des MemoryStream-Objekts ben&ouml;tigen wir noch einen Verweis auf den folgenden Namespace:<\/p>\n<pre>Imports System.IO<\/pre>\n<h2>Speichern des Bitmaps in einer .bmp-Datei<\/h2>\n<p>Nun wollen wir dem Benutzer noch erm&ouml;glichen, das erstellte <b>Bitmap<\/b>-Element mit dem QR-Code auf der Festplatte zu speichern, damit er es weiterverwenden kann &#8211; beispielsweise, um dieses in ein Word-Dokument oder ein mit einer anderen Anwendung erstelltes Rechnungsdokument einzubinden. Der <b>Speichern unter<\/b>-Dialog soll anschlie&szlig;end wie in Bild 5 aussehen.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2022_01\/pic_300_005.png\" alt=\"Speichern des erstellten QR-Codes\" width=\"549,6265\" height=\"436,9052\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 5: Speichern des erstellten QR-Codes<\/span><\/b><\/p>\n<p>Dazu haben wir die Schaltfl&auml;che <b>btnSpeichern <\/b>angelegt, die beim Anklicken die folgende Methode ausl&ouml;st:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>btnSpeichern_Click(sender<span style=\"color:blue;\"> As Object<\/span>, e<span style=\"color:blue;\"> As <\/span>RoutedEventArgs)\r\n     <span style=\"color:blue;\">Dim <\/span>objSaveFileDialog<span style=\"color:blue;\"> As <\/span>SaveFileDialog = <span style=\"color:blue;\">New<\/span> SaveFileDialog()\r\n     <span style=\"color:blue;\">Dim <\/span>strDateiname<span style=\"color:blue;\"> As String<\/span>\r\n     objSaveFileDialog.DefaultExt = \".bmp\"\r\n     objSaveFileDialog.Filter = \"Bitmap|*.bmp\"\r\n     objSaveFileDialog.FileName = \"BeispielEPCCode\"\r\n     <span style=\"color:blue;\">If <\/span>objSaveFileDialog.ShowDialog() = <span style=\"color:blue;\">True<\/span><span style=\"color:blue;\"> Then<\/span>\r\n         strDateiname = objSaveFileDialog.FileName\r\n         objBMP.Save(strDateiname)\r\n     <span style=\"color:blue;\">End If<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>F&uuml;r die hier verwendete <b>SaveFileDialog<\/b>-Klasse ben&ouml;tigen wir noch diesen <b>Namespace<\/b>-Verweis:<\/p>\n<pre>Imports Microsoft.Win32<\/pre>\n<h2>Zusammenfassung und Ausblick<\/h2>\n<p>Mit der hier vorgestellten L&ouml;sung finden Sie eine praktische M&ouml;glichkeit, eigene EPC-QR-Codes zu erstellen und zu speichern, sodass Sie diese in eigene Rechnungen integrieren k&ouml;nnen. Wenn Sie umfangreichere Rechnungsl&auml;ufe planen, wollen Sie die QR-Codes sicher aus den Daten einer Datenbank f&uuml;ttern. Zu diesem Zweck erstellen wir in einem weiteren Artikel namens <b>EPC-QR-Codes per DLL <\/b>(<b>www.datenbankentwickler.net\/301<\/b>) noch eine DLL, die Sie nach Wunsch in andere Anwendungen einbinden k&ouml;nnen.<\/p>\n<h2>Downloads zu diesem Beitrag<\/h2>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>Fotoueberweisung.zip<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/5AF208FD-93EB-4A76-A533-9985FC732A0E\/vbe_300.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Was f&uuml;r eine Erl&ouml;sung! Nach jahrelanger Qu&auml;lerei beim Eintippen ewig langer IBANs und Rechnungsnummern in die Banking-App im Smartphone gibt es mittlerweile nicht nur ein Format f&uuml;r einen QR-Code, der alle notwendigen Daten bereitstellt, sondern auch Banken, deren Banking-App das Einlesen von Rechnungsdaten wie den Zahlungsempf&auml;nger, IBAN, BIC, Verwendungszweck und Zahlungsbetrag aus einem QR-Code erlauben. Noch sch&ouml;ner: Das Format ist &uuml;berschaubar und mithilfe einfacher Erweiterungen zum Erstellen von QR-Codes bauen wir uns unsere eigenen EPC-QR-Codes, die wir unseren Rechnungen hinzuf&uuml;gen k&ouml;nnen. Auf dass unsere Kunden uns feiern, weil sie viel Zeit und Nerven beim Bezahlen unserer Rechnungen sparen!<\/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":[66012022,662022,44000004,44000028],"tags":[],"yst_prominent_words":[],"class_list":["post-55000300","post","type-post","status-publish","format-standard","hentry","category-66012022","category-662022","category-Loesungen","category-Word_programmieren"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000300","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/comments?post=55000300"}],"version-history":[{"count":0,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000300\/revisions"}],"wp:attachment":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/media?parent=55000300"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/categories?post=55000300"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/tags?post=55000300"},{"taxonomy":"yst_prominent_words","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/yst_prominent_words?post=55000300"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}