mein Notebook trifft auf der Reise verschiedene Drucker an,
die ich dann über USB anschließe.
Z.B. Brother HL-143ß series
Brother HL-5150D series
HP Laserjet 3300 series
Die entsprechenden Druckertreiber sind auf meinem Notebook
installiert und alles funktioniert auch, wenn ich den
jeweiligen Drucker per Handbetrieb über die Systemsteuerung
als Standarddrucker definiere.
Ich möchte den Handbetrieb per VBA als Shell-Befehl
umstellen auf Command-Button-Klick und frage,
wer kann mir da einen Tipp geben wie der Befehl aussehen muß.
MfG
Robert
Nachtrag:
XL 2002 und Windows XP
Morgen Robert,
mit der Funktion ChangePrinter sollte das funktionieren.
Benutze bei Bedarf * als 'Joker' (siehe VBA-Hilfe zu LIKE), z.B.:
ChangePrinter "*Laserjet 3300*"
ChangePrinter "Brother*143*"
Mit ListAllPrinters kannst Du dir ggf. alle Printer ausgeben lassen.
cu, Bernd
--
Option Explicit
Sub ListAllPrinters()
Dim WshNetwork As Object, objPrinters As Object, i As Integer
Set WshNetwork = CreateObject("WScript.Network")
Set objPrinters = WshNetwork.EnumPrinterConnections
For i = 0 To objPrinters.Count - 1 Step 2
Debug.Print objPrinters.Item(i + 1) & " an " & objPrinters.Item(i)
Next
Set WshNetwork = Nothing
End Sub
Function ChangePrinter(ByVal strPrinter As String) As Boolean
Dim WshNetwork As Object, objPrinters As Object, i As Integer
Set WshNetwork = CreateObject("WScript.Network")
Set objPrinters = WshNetwork.EnumPrinterConnections
For i = 1 To objPrinters.Count Step 2
If objPrinters.Item(i) Like strPrinter Then
WshNetwork.SetDefaultPrinter objPrinters.Item(i)
ChangePrinter = True
Exit For
End If
Next
Set WshNetwork = Nothing
End Function
Sub TestIt()
Debug.Print Application.ActivePrinter
ChangePrinter "FreePDF*"
Debug.Print Application.ActivePrinter
ChangePrinter "*HP LaserJet 5*"
Debug.Print Application.ActivePrinter
End Sub
zunächst besten Dank für Deine Hilfestellung.
Ich habe die Funktion und auch die beiden Prozeduren
wie von Dir gepostet per Kopie übernommen.
Die Kombination Funktion plus TestIt(), natürlich mit
geänderten Druckernamen funktioniert einwandfrei wie
gewünscht.
Die Prozedur ListAllPrinters bringt zwar keine Fehlermeldung,
ein Ergebnis konnte ich allerdings auch nicht feststellen.
Kann es sein, daß da noch was fehlt ?
MfG
Robert
Morgen Robert,
das Ergebnis wird in das VBA-Direktfenster geschrieben.
Öffne das im VBA mal mit STRG-G oder Menu-Ansicht-Direktfenster und
starte die Sub nochmals.
cu, Bernd
Guten Morgen Bernd,
danke für Deinen Hinweis. Im Direktfenster des VBE kann ich sehen
welche Info die Prozedur ListAllPrinters ausgibt. Nun ist das
natürlich etwas umständlich eine Prozedur vom VBE aus zu starten.
Ich möchte diese Prozedur von einem Button aus starten.
Kannst Du mir bitte noch einen Tipp geben wie ich diese Ausgabe,
die im Moment nur im Direktfenster zu sehen ist,
auf eine MSGBox oder noch besser auf einer Userform ausgeben lassen
kann, denn auf der Userform könnte ich dann noch Buttons für eine
evtl. Umstellung des Standarddruckers unterbringen ?
MfG
Robert
schau mal hier rein,
http://www.gruppenrichtlinien.de/index.html?/HowTo/rundll32_printui.htm
http://michael-schwimmer.de/vba099.htm
mfg Herbert
Danke für Deine Hinweise.
Meistens schaue ich erst mal nach was bezüglich meiner Fragen
schon geschrieben wurde, bevor ich einen Thread beginne.
Auch in diesem Fall habe ich das so gemacht und habe natürlich
auch die von Dir geposteten Links gefunden.
Beide Links sind sicherlich sehr empfehlenswert, wenn man weiß
wie man diese benutzen kann. Für mich sind es im Moment noch
"Spanische Dörfer" aber vielleicht kannst Du mir ja auf die
Sprünge helfen.
Aus "gruppenrichtlinien.de" habe ich mir mal die Variante
Liest die Druckereinstellungen:
rundll32 printui.dll,PrintUIEntry /Xg /n "Drucker"
rausgesucht und in ein Modul kopiert.
Der CodeText :rundll32 printui.dll,PrintUIEntry /Xg /n "Drucker"
wurde sofort rot unterlegt, was ich so interpretiert habe,
das damit so nichts anzufangen ist.
Kannst Du mir bitte einen Tipp geben wie man damit was anstellen kann ?
Die Arbeit von Michael Schwimmer hat natürlich auch vieles zu bieten
präsentiert sich bei mir aber im Moment als eine Wissenschaft für
sich.
Ich habe sogar die Bücher Einstieg für Anspruchsvolle von
Michael Schwimmer und auch Excelprogrammierung von Monika Weber und
Michael Schwimmer aber für den konkreten Bedarf ist das alles zu
wissenschaftlich, oder anders gesagt, es fehlt mir der Anschub.
Der Code von Bernd ist ganz brauchbar und funktioniert auch dann
wenn ich im Moment noch nicht verstehe warum der funktioniert.
Nun ist es natürlich immer gut verschiedene Varianten zu kennen und
sicherlich hat die eine oder andere Variante Vorteile oder Nachteile,
daher wäre ich Dir dankbar, wenn Du mir für meinen konkreten Fall
einen kurzen Lösungsansatz nach dem System "gruppenrichtlinien.de"
oder "Michael Schwimmer" erklären würdest, damit ich mich mal grundsätzlich
mit dem einen oder anderen vertraut machen kann.
MfG
Robert
hier ein Beispiel anhand vom Code von Michael
füge dazu in deinem Blatt eine Combobox ein mit
dem Namen Combobox1 und kopiere in das Codefenster
dieses Blattes den untenstehenden Code ganz oben ein
mit dem Code wird bei jedem aktivieren des Blattes
der Inhalt der Combobox gelöscht und neu eingelesen
dort werden alle verfügbaren Drucker angezeigt
und der der ausgewählt wird, wird als Standard definiert
wobei noch zu beachten ist, Verfügbar sind jene die installiert sind
und nicht jene die tatsächlich angeschlossen sind
--------------------------
Option Explicit
Const PRINTER_ENUM_CONNECTIONS = &H4
Const PRINTER_ENUM_LOCAL = &H2
Private Declare Function EnumPrinters Lib "winspool.drv" _
Alias "EnumPrintersA" (ByVal flags As Long, _
ByVal name As String, ByVal Level As Long, _
pPrinterEnum As Long, ByVal cdBuf As Long, _
pcbNeeded As Long, _
pcReturned As Long) As Long
Private Declare Function PtrToStr Lib _
"kernel32" Alias "lstrcpyA" _
(ByVal RetVal As String, ByVal Ptr As Long) _
As Long
Private Declare Function StrLen Lib _
"kernel32" Alias "lstrlenA" _
(ByVal Ptr As Long) As Long
Public Function ListPrinters() As Variant
Dim bSuccess As Boolean
Dim iBufferRequired As Long
Dim iBufferSize As Long
Dim iBuffer() As Long
Dim iEntries As Long
Dim iIndex As Long
Dim strPrinterName As String
Dim iDummy As Long
Dim iDriverBuffer() As Long
Dim StrPrinters() As String
iBufferSize = 3072
ReDim iBuffer((iBufferSize \ 4) - 1) As Long
' EnumPrinters will return a value False
' if the buffer is not big enough
bSuccess = EnumPrinters(PRINTER_ENUM_CONNECTIONS Or _
PRINTER_ENUM_LOCAL, vbNullString, _
1, iBuffer(0), iBufferSize, iBufferRequired, iEntries)
If Not bSuccess Then
If iBufferRequired > iBufferSize Then
iBufferSize = iBufferRequired
Debug.Print "iBuffer too small. Trying again with "; _
iBufferSize & " bytes."
ReDim iBuffer(iBufferSize \ 4) As Long
End If
' Try again with new buffer
bSuccess = EnumPrinters(PRINTER_ENUM_CONNECTIONS Or _
PRINTER_ENUM_LOCAL, vbNullString, _
1, iBuffer(0), iBufferSize, iBufferRequired, iEntries)
End If
If Not bSuccess Then
' Enumprinters returned False
MsgBox "Error enumerating printers."
Exit Function
Else
' Enumprinters returned True,
' use found printers to fill the array
ReDim StrPrinters(iEntries - 1)
For iIndex = 0 To iEntries - 1
' Get the printername
strPrinterName = Space$(StrLen(iBuffer(iIndex * 4 + 2)))
iDummy = PtrToStr(strPrinterName, iBuffer(iIndex * 4 + 2))
ActiveSheet.ComboBox1.AddItem strPrinterName
StrPrinters(iIndex) = strPrinterName
Next iIndex
End If
ListPrinters = StrPrinters
End Function
Public Function IsBounded(vArray As Variant) As Boolean
' If the variant passed to this function is an array,
' the function will return True;
' otherwise it will return False
On Error Resume Next
IsBounded = IsNumeric(UBound(vArray))
End Function
'You could call the function as follows:
Sub Test()
Dim StrPrinters As Variant, x As Long
Dim Txt
StrPrinters = ListPrinters
' First check whether the array is filled with anything,
' by calling another function, IsBounded.
If IsBounded(StrPrinters) Then
For x = LBound(StrPrinters) To UBound(StrPrinters)
Txt = Txt & StrPrinters(x) & vbCrLf
Next x
' MsgBox "Installierte Drucker:" & vbCrLf _
'& vbCrLf & Txt, vbInformation, " Information über Drucker"
Else
MsgBox "No printers found"
End If
End Sub
' Drucker als Standard-Drucker für Ihre Anwendung setzen
Private Sub Combobox1_Click()
Shell "rundll32 printui.dll,PrintUIEntry /y /n """ _
& ComboBox1.Value & """"
End Sub
Private Sub Worksheet_Activate()
ComboBox1.Clear
Test
End Sub
---------------------------
mfg Herbert
um sie in einer Combo anzuzeigen reicht es aus die Zeile:
Debug.Print objPrinters.Item(i + 1) & " an " & objPrinters.Item(i)
in sowas umzuändern:
cboDruckerListe.AddItem objPrinters.Item(i + 1) & " an " &
objPrinters.Item(i)
Wenn Dich der Anschluss nicht interessieren sollte nimm sowas:
cboDruckerListe.AddItem objPrinters.Item(i + 1)
Und, wie Du den Drucker bestimmst / setzt ist M.E. ziemlich egal.
Möglicherweise ist die Win-API etwas schneller, der Code mit
WScript.Network dafür einfacher.
Alternativ ginge das auch noch via WMI oder auch über die win.ini (die
bei 'neuerern' Windows in der Registry 'gemappt' ist).
cu, Bernd
Hallo Herbert,
zunächst einmal vielen Dank für Dein Posting,
gleichzeitig möchte ich mich dafür entschuldigen,
daß ich erst jetzt nach so vielen Tagen antworte.
Leider kenne ich bisher nicht die 35 Stunden-Woche.
Ich hatte in den letzten Tagen so viele dringende
Arbeiten zu erledigen, daß ich einfach keine Zeit
und Muse fand, um die von Dir gepostete Prozedur
zu testen und bitte um Verständnis, daß ich erst
jetzt antworte.
Nun komme ich zur Sache:
Ich habe eine neue Exceldatei mit Namen
Druckerumstellung.XLS angelegt
und dann sowohl den von Dir empfohlenen Code
als auch den Code von Bernd dort untergebracht.
Zur sauberen Trennung habe ich je ein Arbeitsblatt
mit Namen Herbert und ein solches mit Namen Bernd
angelegt. In dem Arbeitsblatt "Herbert" habe ich
zusätzlich noch eine Combobox ins Arbeitsblatt
eingebettet.
Damit der Makrocode auch separat ist, habe ich
2 Module angelegt und die Namen MakroHerbert
und MakroBernd vergeben.
Bei den Formularen habe ich je eine Userform
mit Namen UserFormHerbert und UserFormBernd
angelegt und dann jeweils auf der Userform
eine Combobox angelegt.
Die eine Combobox hat die Adresse
UserFormHerbert.ComboboxHerbert1
und die andere ComboBox hat die Adresse
UserFormBernd.CboDruckerliste
Nun habe ich beide Prozeduren ausprobiert, bekomme
keine Fehlernmeldung aber auch keine Ausgabe in der
jeweiligen Combobox angezeigt.
Ganz offensichtlich habe ich da irgend etwas nicht
ganz nach Plan gemacht.
So rein zum Testen habe ich auf der Userform
jeweils 2 Buttons zum Testen der Combobox eingebaut
und kann dort sowohl einen Text einblenden als auch
wieder entfernen nur, wie schon gesagt die Ergebnisse
Euer beider Prozeduren werden mir dort leider
nicht angezeigt.
Wenn Du möchtest, dann ich in den nächsten Tagen die Datei
per FTP --- ins Netz stellen und dann kannst Du bitte mal
nachsehen, ob ich womöglich alles falsch gemacht habe.
Für heute mächte ich Schluß machen und hoffe,
daß Dich diese Nachricht auch erreicht.
MfG
Robert
Hallo Bernd,
zunächst einmal vielen Dank für Dein Posting,
gleichzeitig möchte ich mich dafür entschuldigen,
daß ich erst jetzt nach so vielen Tagen antworte.
Leider kenne ich bisher nicht die 35 Stunden-Woche.
Ich hatte in den letzten Tagen so viele dringende
Arbeiten zu erledigen, daß ich einfach keine Zeit
und Muse fand um die von Dir gepostete Prozedur
zu testen und bitte um Verständnis, daß ich erst
jetzt antworte.
Nun komme ich zur Sache:
Ich habe eine neue Exceldatei mit Namen
Druckerumstellung.XLS angelegt
und dann sowohl den von Dir empfohlenen Code
als auch den Code von Herbert dort untergebracht.
wie schon letztes mal geschrieben, den Code nicht in ein Modul
sondern in das Codefenster des Blattes und die ComboBox
wie im Code als ComboBox1 in die Tabelle sonst umbenennen
dann springe in ein anderes Blatt und wieder zurück denn wie
im Code schon ersichtlich wird beim aktivieren des Blattes
jedesmal die Combobox neu gefüllt ( falls mal ein Drucker
gelöscht wird oder einer dazukommt hast du damit immer
den aktuellen Stand in der Box
mfg Herbert
Danke für Deinen Hinweis.
Am Mon, 12 Nov 2007 16:09:34 +0100 schrieb Herbert Taferner:
snip --
>
> wie schon letztes mal geschrieben, den Code nicht in ein Modul
> sondern in das Codefenster des Blattes und die ComboBox
> wie im Code als ComboBox1 in die Tabelle sonst umbenennen
>
> dann springe in ein anderes Blatt und wieder zurück denn wie
> im Code schon ersichtlich wird beim aktivieren des Blattes
> jedesmal die Combobox neu gefüllt ( falls mal ein Drucker
> gelöscht wird oder einer dazukommt hast du damit immer
> den aktuellen Stand in der Box
>
> mfg Herbert
Das hatte ich auch so kapiert, obwohl ich diese EventMakros
nicht mag. Man kann daraus ja auch ganz leicht zusätzlich
eine "Buttonversion" machen und das habe ich auch getan.
Nun habe ich festgestellt, die Prozedur läuft aber man kann
nichts sehen, weil die Combobox zunächst keinen Inhalt anzeigt.
Man bekommt erst dann den Inhalt zu sehen, wenn man rechts auf
den Button der Combobox geht. Hier zeigt sich, daß ich eigentlich
überhaupt keine Erfahrung mit einer Combobox hatte weil ich eine
solche bisher noch nie verwendet habe.
Kann man die Eigenschaften der Combobox so verändern, daß der
Inhalt angezeigt wird ohne die Taste anzuklicken ?
Noch eine Sache habe ich nicht verstanden:
Mit dem Code ComboBox1.Clear
kann ich den Inhalt der Combobox löschen.
Mit ActiveSheet.ComboBox1.Value = Empty
dagegen wird mur ein Textinhalt gelöscht
Was ist da der Unterschied, ich glaube ich verstehe noch
nicht die Arbeitsweise der Combobox.
Also wie ich jetzt festgestellt habe, läuft die Prozedur
von Anfang an. Nur weil ich halt ein großes Fenster für
die Combobox aufgezogen hatte, dachte ich, daß da was
angezeigt werden müßte wenn die Prozedur beendet ist.
Es wird aber nur was angezeigt, wenn ich den Button der
Combobox anklicke.
Kannst Du mir dazu bitte mal so ein bischen auf die
Spünge helfen und erklären wie ich die Combobox zu verstehen
und zu handhaben habe.
MfG
Robert
> snip --
>>
>> wie schon letztes mal geschrieben, den Code nicht in ein Modul
>> sondern in das Codefenster des Blattes und die ComboBox
>> wie im Code als ComboBox1 in die Tabelle sonst umbenennen
>>
>> dann springe in ein anderes Blatt und wieder zurück denn wie
>> im Code schon ersichtlich wird beim aktivieren des Blattes
>> jedesmal die Combobox neu gefüllt ( falls mal ein Drucker
>> gelöscht wird oder einer dazukommt hast du damit immer
>> den aktuellen Stand in der Box
>>
>> mfg Herbert
>
> Das hatte ich auch so kapiert, obwohl ich diese EventMakros
> nicht mag. Man kann daraus ja auch ganz leicht zusätzlich
> eine "Buttonversion" machen und das habe ich auch getan.
>
> Nun habe ich festgestellt, die Prozedur läuft aber man kann
> nichts sehen, weil die Combobox zunächst keinen Inhalt anzeigt.
>
> Man bekommt erst dann den Inhalt zu sehen, wenn man rechts auf
> den Button der Combobox geht. Hier zeigt sich, daß ich eigentlich
> überhaupt keine Erfahrung mit einer Combobox hatte weil ich eine
> solche bisher noch nie verwendet habe.
>
> Kann man die Eigenschaften der Combobox so verändern, daß der
> Inhalt angezeigt wird ohne die Taste anzuklicken ?
ergänze den Code nach dem befüllen der Box mit der Zeile
ComboBox1.ListIndex = 0
damit wird der erste sofort angezeigt, dies solltest du aber
noch in eine Fehlerauswertung einbinden, denn wenn die Box leer ist
bzw. kein Drucker installiert ist wird daraus ein Fehler und der Code
bleibt dann hier stehen
> Noch eine Sache habe ich nicht verstanden:
>
> Mit dem Code ComboBox1.Clear
> kann ich den Inhalt der Combobox löschen.
damit wird die ganze Box geleert
> Mit ActiveSheet.ComboBox1.Value = Empty
> dagegen wird mur ein Textinhalt gelöscht
damit wird nur der momentan ausgewählte Wert entfernt
was ja auch der Code genau aussagt
> Was ist da der Unterschied, ich glaube ich verstehe noch
> nicht die Arbeitsweise der Combobox.
>
> Also wie ich jetzt festgestellt habe, läuft die Prozedur
> von Anfang an. Nur weil ich halt ein großes Fenster für
> die Combobox aufgezogen hatte, dachte ich, daß da was
> angezeigt werden müßte wenn die Prozedur beendet ist.
> Es wird aber nur was angezeigt, wenn ich den Button der
> Combobox anklicke.
>
> Kannst Du mir dazu bitte mal so ein bischen auf die
> Spünge helfen und erklären wie ich die Combobox zu verstehen
> und zu handhaben habe.
das ist offensichtlich Geschmacksache, der eine will die Box zuerst
leer haben, der andere will den ersten Eintrag sehen, andere möchten
vielleicht einen Eintrag aus der Liste als Vorgabe schon ausgewählt
haben, wenn dieser vorhanden ist
da ist der Phantasie keine Grenze gesetzt, da kann jeder wie er möchte
wobei noch anzumerken ist, daß die Eigenschaften nicht gleich sind
wenn die Box in der Tabelle ist oder wenn sie in einer Userform ist
mfg Herbert
Dankeschön für Deine Hilfestellung, es hat alles so geklappt
wie Du es beschrieben hast.
Mit Deinen Hinweisen habe ich auch das Ergebnis der Prozedur
von Bernd in der Combobox auf der Userform anzeigen können.
Nun muß ich mit diesen Comboboxen mal bischen rumspielen und
dann werde ich wohl die Möglichkeiten der Comboboxen herausfinden.
MfG
Robert
Am Mon, 12 Nov 2007 20:05:56 +0100 schrieb Herbert Taferner:
>> snip --
>>
> Dankeschön für Deine Hilfestellung, es hat alles so geklappt
> wie Du es beschrieben hast.
Bitte gern !
> Mit Deinen Hinweisen habe ich auch das Ergebnis der Prozedur
> von Bernd in der Combobox auf der Userform anzeigen können.
>
> Nun muß ich mit diesen Comboboxen mal bischen rumspielen und
> dann werde ich wohl die Möglichkeiten der Comboboxen herausfinden.
genau so !
mfg Herbert