Im Rahmen unseres Projektes zur Generierung von Seriennummern stellte sich das Problem, ein Papierformat eines speziell zum Ausdruck von Typenschildern installierten Druckers anzusprechen. Das dauerhafte Umstellen des Standarddruckers in Windows war keine Lösung, denn zum Einen nutzen die Benutzer unsere Anwendung parallel mit weiteren Excel Arbeitsmappen und zum Anderen sich verschiedene Größen von Typenschildern zu drucken. Auch das ständige Auswählen des Druckers wäre nicht praktikabel.
Im Folgenden werden wir unsere Windows API Lösung vorstellen, die einerseits das Auswählen eines Druckers ermöglicht und andererseits alle verfügbaren Papierformate eines Druckers anbietet. Der Code hierzu den wir an dieser Stelle freigeben ist nur ein Auszug aus der Echtanwendung. Letztere merkt sich pro einer Maschine assoziiertes Typenschild das passende Format und den passenden Drucker. Somit braucht der User nur noch kurz die Angaben prüfen und kann sich auf das Wesentliche konzentrieren.
In der Beispielanwendung – die sie auch herunterladen können – haben wir eine Userform erstellt, die zwei Kombinbationsfelder enthält. Erstere nimmt die Liste der installierten Drucker auf, die zweite Combobox enthält nach Auswahl eines Druckers die passenden Papierformate.
Um nun die Liste der Drucker zu ermitteln, benötigen wir die Windows API Funktion GetProfileString(), welche uns die Liste der verfügbaren Drucker zurückliefert.
Folgend der Code, in welchem wir den Aufruf der API Funktion durchführen.
Da wir die Funktion später in der Initialisierungsfunktion der Userform aufrufen werden, übergeben wir mlfpPrinters() das Handle zur Userform, den Namen des Steuerelementes sowie einen String für den Fall dass keine Auswahl getroffen wurde. Nach dem Aufruf der API Funktion enthält der Parameter r eine durch Nullzeichen separierte Zeichenkette, die die Liste der Drucker darstellt. Wir übergeben r an die Funktion mlfhNames(), die r aufteilt und die gefundenen Drucker im Array mlvhNames ablegt. Um einen Drucker in Excel über die globale Zuweisung Application.ActivePrinter wechseln zu können, muss auch ein Druckerport angegeben werden. Um diese zu ermitteln, rufen wir unsere Funktion mlfhPorts zu, die wiederum einen erneuten Aufruf der API Funktion GetProfileString() ausführt, allerdings mit veränderten Übergabeparametern. Auch hier erhalten wir pro Aufruf einen String, welcher jedoch diesmal die Elemente durch Kommata trennt. Wir zerlegen diesen String und füllen unsere Arrays mlvhPorts und mlvhDrivers, wobei letzteres nur der Vollständigkeit halber gefüllt wird.
Wie bereits erwähnt, verwenden wir ein Kombinationsfeld, um unsere Drucker aufzulisten. Im Code zu mlfpPrinters() löschen wir nach den Aufruf von mlfhPorts zunächst den Inhalt der Combobox und stellen diese auf 5 Spalten ein, wobei alle Spalten ausser der zweiten ausgeblendet werden. Anschließend füllen wir jede Spalte mit den Inhalten unserer Arrays. Besondere Beachtung findet die dritte Spalte. Um den Drucker mit ActivePrinter zu setzen muss auf das Wort auf übergeben werden. Eine gültige Anweisung wäre beispielsweise:
Application.ActivePrinter = "Adobe PDF auf Ne03:"
Nun sind unsere Anwendungen in der Regel auf Systemen mit unterschiedlichen Sprachen installiert, d.h. wir müssen berücksichtigen, dass auf einem englischen System der Zuweisungsstring „Adobe PDF on Ne03:“ und in Französisch „Adobe PDF sur Ne03:“ heißt. Da wir jedoch keine API Funktion gefunden hatten, die uns diesen String ermittelt und um zu vermeiden, dass eine sprachabhängige Liste in der Anwendung mitgeführt wird, bedienen wir uns eines kleinen Tricks. Zunächst suchen wir den in Excel aktiven Drucker aus unserer Gesamtliste heraus und reduzieren dann diesen String, indem wir Port und Druckername entfernen. Übrig bleibt der lokalisierte String, hier also auf. Abschließend füllen wir unser Kombinationsfeld. Folgend der Code zu unserer Userform.
Bei der Initialisierung rufen wir mlfpPrinters(Me, CMB_0001.Name, „?“) auf und setzen den Index von CMB_0001 auf 0. Wählt ein User nun einen Drucker aus CMB_0001, wird mlfpPapersizes(Me, CMB_0001.Name, CMB_0002.Name, „?“) aufgerufen. Diese Funktion ist ähnlich mlfpPrinters() aufgebaut, nur dass zusätzlich der Name einer zweiten Combobox übergeben wird. Die Funktion sieht wie folgt aus:
Hier kommt unsere zweite API Funktion DeviceCapabilities ins Spiel, welche uns die Papierformate des gewählten Druckers zurückliefert. Der erste Aufruf der API Funktion liefert die verfügbare Anzahl der Papierformate zurück. Nach 2 weiteren Aufrufen der Funktion erhalten wir in r einen durch Nullzeichen separierten String, den wir wieder zerlegen und das Kombinationsfeld mit den einzelnen Elementen füllen können. Auch dieses Kombinationsfeld hat zwei Spalten, in erstere wird eine ID zum Papierformat abgelegt.
Schauen wir uns nun abschließend den Code zur Schaltfläche BTN_0009 an. In einem ersten Schritt wird der in Excel aktive Drucker in einer Variable abgelegt, danach die Zeichenkette zur Zuweisung an ActivePrinter aus den Elementen der ersten Combobox zusammengesetzt und zugewiesen. Weitere Einstellungen werden getroffen, das Papierformat übergeben (wichtig, die ID ist zu übergeben, nicht die Bezeichnung) und die Druckvorschau aufgerufen. Abschließend wird der Originaldrucker wieder zugewiesen.
Sie können den Code nach Belieben anpassen und in Ihren Projekten verwenden. Sollten Sie einen Fehler entdecken, würden wir uns über eine Nachricht freuen. Aber auch Anregungen und Kommentare sind willkommen.
Die Beispielanwendung können Sie hier Drucker und Papierformate in VBA ermitteln und verwenden herunterladen. Beachten Sie bitte, dass dieser Link nur angeklickt funktioniert und wenn Ihr Browser einen Referer sendet. Ausserdem übernehmen wir natürlich in keinster Weise irgendeine Haftung für die Richtigkeit der Angaben in der Datei.
Hello !
First of all, thanks of this tutorial. I searched a lot before find this !
I have „juste“ 3 questions :
-> I have different printer in my company and some have a lot of papersize available, like more than 50. Is that normal, because in the settings of the printer in windows, I find 2 or 3 papersize maximum (A3/A4/A5) ?
-> Some name of papersize are very strange like „Tabloid“ or „ARCH E1“, is that normal too ? (But maybe it’s special format for specific things)
-> In some printer, there is 2 or 3 time the papersize with differnent noun (ex : „A4 (210 x 297 mm)“, „A4“). Do you know why ?
If you have the code modification to have only the basic papersize (A3, A4 or A5) available on the printer selected, it would be amazing !
But still this little app help me a lot and is so nice. A big thanks for that. I’m not a begginer in VBA, I know a lot of things, but macro like that, it’s beyond my capabilities. Thank you !
I’m not German but I will keep an eyes on your very informative website !
Thanks and have a good day,
Baboutz