QR Codes mit VBA und Google Chart API erstellen

Im Internet gibt es zahlreiche Webseiten, mit denen man QR-Codes erzeugen kann. Man tippt einfach die zu verschlüsselnde Zeichenkette ein und erhalt eine entsprechende Grafik mit dem QR-Code. Was ist jedoch, wenn man dies nicht per Hand, sondern maschinell erledigen möchte? Hierfür könnte die Google Chart API eine mögliche Lösung sein.

In diesem Tutorial stelle ich ein kleines, von mir entwickeltes, Programm vor und erkläre ausführlich, wie dieses funktioniert. Es ist in der Lage, Texte aus einem Array mit Hilfe der Google Chart API automatisch in QR Codes zu überführen. Mit einer kleinen Anpassung kann auch eine Exceltabelle als Quelle für die umzuwandelnden Texte angebunden werden, sodass die Textpflege noch einfacher wird.

Was ist Google Chart API?

Die Google Chart API ist ein Webdienst von Google, welcher aus übergebenen Daten QR Codes im png-Format erzeugen kann. Dieser Dienst ist nicht neu, er dürfte vor rund 15 Jahren online gegangen und sollte eigentlich vor 3 Jahren abgeschaltet worden sein. Zum Zeitpunkt der Artikelveröffentlichung funktioniert dieser aber noch tadellos.

Erläuterungen zum Quellcode

Schauen wir uns das Programm Zeile für Zeile an und versuchen deren Funktionsweise nachzuvollziehen.

Variablendeklaration

    Dim objWebRequest           As Object
    Dim byteBildArray()         As Byte
    Dim strURL                  As String
    Dim strBildPfad             As String
    Dim strInhalteArray(1 To 3) As String
    Dim bytZaehler              As Byte

    strInhalteArray(1) = "MeinErsterTest"
    strInhalteArray(2) = "VBA"
    strInhalteArray(3) = "Programmierung"

In diesem Block findet die Deklaration benötigter Variablen und die Belegung des Arrays mit umzuwandelnden Beispieltexten statt. Mittlerweile verwende ich ganz gerne die sogenannte ungarische Variablennotation. Diese zeichnet sich dadurch aus, dass sich der Datentyp der jeweiligen Variablen am Variablennamen erkennen lässt.

  • str für String
  • byt für Byte
  • lng für Long
  • obj für Objekt

So (zumindest geht es mir so) vermeide ich größtenteils Flüchtigkeitsfehler, die durch eine falsche Variablenzuweisung entstehen.

WinHttpRequest

Set objWebRequest = CreateObject("WinHttp.WinHttpRequest.5.1")

Damit unser Programm überhaupt mit der API kommunizieren kann, benötigen wir das WinHttpRequest-Objekt, welches hier in der Zeile erzeugt wird.

API-Adresse und die Parameterliste

strURL = "http://chart.apis.google.com/chart?chs=500x500&cht=qr&chld=L&chl="

Was die API genau zu tun hat, „erfährt“ sie durch die übermittelten Parameter. An dieser Stelle setzen wir diese Parameter zu einer Zeichenkette zusammen. Der erste Teil des Strings http://chart.apis.google.com/chart ist die Adresse, unter der die API erreichbar ist. Das darauf folgende Fragezeichen kündigt die Parameterliste an. Diese ist an den Key-Value-Pairs erkennbar chs=500×500&cht=qr&chld=L&chl=. Links des Gleichheitszeichens steht der Attributsname und rechts seine Ausprägung. Die Key-Value-Pairs werden durch das &-Zeichen voneinander getrennt. Die Entwickler dieser API waren bei der Namensgebung richtig sparsam – mir erschließt sich die Attributsbedeutung nur, wenn ich sie zusammen mit Ausprägungen vor Augen habe.

  • chs – hier wird die Größe des QR-Code-Bildes in Pixel angegeben
  • cht – da hinterlegt man, um welchen Grafiktyp es sich handelt, unserenfalls ist es immer qr
  • chld – hier wird der Fehlerkorrekturlevel des QR-Codes hinterlegt, in unserem Fall ist es L(ow). Es gibt noch Ausprägungen M(edium), Q(artil), H(igh), die noch höheren Fehlerkorrekturlevel ermöglichen
  • chl – an der Stelle wird der zu umzuwandelnde Text angegeben

Schleifenverarbeitung

For bytZaehler = LBound(strInhalteArray) To UBound(strInhalteArray)
…
Next bytZaehler

Damit das Programm alle Texte des Arrays umwandeln kann, wird hier eine For-Schleife eingesetzt, die das komplette Array vom ersten bis zum letzten Element durchläuft. Da die Anzahl der Arrayelemente variieren kann, ermittele ich den Start- und Endindex jeweils mit LBound bzw. UBound-Funktion.

Request an die API absetzen

objWebRequest.Open "POST", strURL & strInhalteArray(bytZaehler), False
objWebRequest.send

Um mit der API kommunizieren zu können, müssen wir zuerst die Verbindung vorbereiten. Dafür wird der Methode open der zuvor gebildete String mit der API-Adresse und den Parametern übergeben. Zu diesem festen String geben wir auch den zu verschlüsselnden Text aus dem Array mit. Bei jedem Schleifendurchlauf wird dann der jeweils nächste Text an die Methode übergeben. Der letzte Parameter false teilt der API mit, dass sie synchron aufgerufen wird. Das bedeutet, dass das Aufrufprogramm so lange „wartet“, bis die API das Ergebnis zurück geliefert hat. Lässt sich die Antwort der API jedoch zu lange auf sich warten, bricht die Verarbeitung aufgrund eines Timeouts ab. In der nächsten Zeile wird der eben vorbereitete Request an die API übermittelt.

Response erhalten und verarbeiten

        strBildPfad = ActiveWorkbook.Path & "/bild_" & bytZaehler & ".png"
                
        byteBildArray = objWebRequest.responseBody
        Call byteArrayAlsDateiSpeichern(strBildPfad, byteBildArray)
        
    Next bytZaehler

End Sub

Private Sub byteArrayAlsDateiSpeichern(strDateiKomplettPfad As String, byteArray() As Byte)

    Open strDateiKomplettPfad For Binary As #1
        Put #1, , byteArray()
    Close #1
    
End Sub

In diesem letzten Abschnitt kümmert sich das Programm darum, einen Bildnamen inklusive Pfad zu generieren. Dafür verwenden wir den Index des jeweiligen Textes aus dem Array, um die Eindeutigkeit des Bildnamens sicherzustellen.

Nun ist endlich die Zeit da, das Ergebnis der API abzuholen. Dieses wird durch die Eigenschaft responseBody bereitgestellt. Anschließend wird der Response in ein ByteArray überführt und an die Funktion für die Speicherung als PNG-Bild weitergereicht.

Quellcode des kompletten Programms

Um das Programm laufen lassen zu können, habe ich hier dieses als Quellcode aufgeführt.

 Public Sub qrCodeErzeugen()
   
    Dim objWebRequest           As Object
    Dim byteBildArray()         As Byte
    Dim strURL                  As String
    Dim strBildPfad             As String
    Dim strInhalteArray(1 To 3) As String
    Dim bytZaehler              As Byte

    strInhalteArray(1) = "MeinErsterTest"
    strInhalteArray(2) = "VBA"
    strInhalteArray(3) = "Programmierung"

    Set objWebRequest = CreateObject("WinHttp.WinHttpRequest.5.1")
    strURL = "http://chart.apis.google.com/chart?chs=500x500&cht=qr&chld=L&chl="

    For bytZaehler = LBound(strInhalteArray) To UBound(strInhalteArray)
    
        objWebRequest.Open "POST", strURL & strInhalteArray(bytZaehler), False
        objWebRequest.send
        
        strBildPfad = ActiveWorkbook.Path & "/bild_" & bytZaehler & ".png"
                
        byteBildArray = objWebRequest.responseBody
        Call byteArrayAlsDateiSpeichern(strBildPfad, byteBildArray)
        
    Next bytZaehler

End Sub


Private Sub byteArrayAlsDateiSpeichern(strDateiKomplettPfad As String, byteArray() As Byte)

    Open strDateiKomplettPfad For Binary As #1
        Put #1, , byteArray()
    Close #1
    
End Sub

Notwendige Anpassungen für den produktiven Einsatz

Der hier vorgestellte Quellcode ist voll funktionsfähig und eignet sich gut dazu, die Abläufe nachvollziehen zu können. Um den Quellcode nicht mit Details zu überfrachten, die nichts mit QR-Code-Erstellung zu tun haben, habe ich auf jegliche Fehlerbehandlung verzichtet.

Das bedeutet, dass es für einen echten Produktionsbetrieb noch einiges an Prüfungen zu hinterlegen wäre. Denn bereits eine Kleinigkeit (fehlende Internetverbindung) reicht aus, um den Code mit einem hässlichen Abbruch auf die Nase fallen zu lassen.

Sinnvolle Prüfungen wären zum Beispiel:

  • ob die Erzeugung des Requestobjektes funktioniert hat.
  • ob sich der Response mit dem Statuscode 200 zurückgemeldet hat.
  • ob bei der Speicherung des Bilder Probleme gegeben hat

Fazit

Bei sensiblen Daten, wie Überweisungs-, Personen- oder Rechnungsdaten, sollte man sich ganz genau überlegen, ob man diese durch die halbe Welt schicken möchte. Eine bessere und datenschutzkonforme Variante wäre es, die QR-Codeerzeugung mit einem offline QR-Generator durchzuführen, welches die Generierung lokal durchführt, sodass die Daten den Rechner nicht verlassen. Für Schulungszwecke oder für den „Hausgebrauch“, beispielsweise zur Verschlüsselung von unkritischen Daten wie Artikelnummern ist diese API aber definitiv zu empfehlen und erspart einem eine Installation eines QR Code Generators.

5 thoughts on “QR Codes mit VBA und Google Chart API erstellen

  1. Guten Tag,
    ich habe in den letzten Tagen sehr viele Probleme mit meinen QR-Codes. Excel-Dateien versuchen ständig erfolglos den Server zu erreichen… Das gleiche bei Google Tabellen. Scheinbar hat https://chart.googleapis.com Probleme? Wisst ihr näheres über die Hintergründe? Ich bin schon am überlegen, ob ich auf einen anderen QR-Dienst umstellen muss….

    1. Hallo Sebastian, meine Exceldatei, mit der ich die Google-Chart-API anspreche (mit dem Quellcode aus dem Beitrag), kann nach wie vor problemlos mit der API kommunizieren und erhält die generierten QR-Codes zurück.
      Daher würde ich ehe auf Probleme mit der Internetverbindung / Firewall tippen

      Viele Grüße
      Tony

      1. Hallo Anton,
        das Problem kommt wohl von Google. Aktuell ist die Seite wieder down. Heute morgen bis ca 9:30 ebenfalls. Zwischendurch ging es wieder. Habe in diversen Foren gelesen, dass Google den Dienst stilllegt. Ob das stimmt, weiß ich nicht. Ich bin gespannt, ob Google das Ding echt einstampft. Wäre schade, es hat zwei Jahre verlässlich gefunzt bei mir.
        Erstmal habe ich die Adresse:
        strURL = „http://chart.apis.google.com/chart?chs=500×500&cht=qr&chld=L&chl=“
        ersetzt durch:
        sURL = „https://api.qrserver.com/v1/create-qr-code/?size=500×500&data=“

        Damit funktionieren meine QR-Codes in Excels augenscheinlich wieder. Ich hoffe das hält…
        Lg Sebastian

        1. Hallo Sebastian, scheint wohl ein Problem zu sein, das hin und wieder auftritt? Hab heute die API wieder aufgerufen, funktioniert zwar nach wie vor, allerdings mit sehr schlechten Antwortzeiten (anstelle von Sekundenbruchteilen wie früher, brauchte die API-Send-Methode heute Abend 10 Sekunden)

          Viele Grüße
          Tony

    2. Hallo Sebastian,

      du bist nicht alleine! Wir haben die selben Probleme. Seit ein paar Tagen können wir keine QR Codes mehr erstellen mit den Googleapi.
      Wir sind auf einen Alternativ Anbieter umgestiegen und warten ab, bis GoogleAPI wieder funktioniert. LG

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert