37414
28.01.2015, aktualisiert am 29.01.2015
3955
31
0
Druckername per VBA-Script über externe Textdatei auswählen
Hallo,
vor ein paar Tagen hatte ich mit Eurer Hilfe den unten eingesetzten Code genutzt, um automatisch 2 Textzeilen aus einer extern auf dem Server abgelegten Textdatei (daten.txt) auszulesen und diesen in ein Dokument einzusetzen. Hierbei sucht der Code nach den Namen der jeweiligen User und setzt den passenden Text ein.
Nun würde ich dieses Script gerne so erweitern, dass in dieser Textdatei "daten.txt" auch die zu den Mitarbeitern passenden Druckernamen mit ausgelesen werden können. Es müßten also 2 weitere Strings dort eingesetzt werden können (a: Drucker zum drucken des aktuellen Dokumentes // b: Standarddrucker wieder aktivieren).
Das neue Script soll dann im Einzelnen folgendes machen:
1) In der Datei "daten.txt" nach dem angemeldeten User suchen (wie es ja auch bereits unten in dem Code für die Text-Einsätze gemacht wird)
2) Dann soll der dritte String (also der jew. Druckername) gewählt werden und das Dokument dann darauf ausgedruckt werden
3) Am Ende soll wieder der Standarddrucker gewählt werden. Am besten (sichersten) wäre es, wenn dieser vielleicht in der Textdatei "daten.txt" als vierter String eingesetzt werden könnte.
Zur Info:
Mit dem bisher im unten eingesetzten Code verwendeten "strPrintername = "MV_" & strUsername & "_Blanko"" funktioniert es nicht, da die jeweiligen Drucker der Mitarbeiter unterschiedliche Namen haben.
Ich wollte dazu den hier eingesetzten Code verwenden... habe das aber nicht hinbekommen, da ich u.a. nicht sicher war, wo ich was einsetzen muss.
Wahrscheinlich muss in Zeile 4 des Codes der Zusatz "strText3 As String" und "strText4 As String" zusätzlich eingetragen werden.
Weiterhin in der Textdatei "daten.txt" die Angaben der beiden Drucker in dieser Art: --> User-Name;i. A.;Dienstbezeichnung;Druckername1;Standarddrucker
Am Ende vermute ich mal, dass für die Drucker eine Variable eingesetzt werden muss...
Wäre schön, wenn Ihr mir hierbei helfen könntet.
Danke und Gruss,
imebro
Hier der Code aus dem vorherigen Thread:
vor ein paar Tagen hatte ich mit Eurer Hilfe den unten eingesetzten Code genutzt, um automatisch 2 Textzeilen aus einer extern auf dem Server abgelegten Textdatei (daten.txt) auszulesen und diesen in ein Dokument einzusetzen. Hierbei sucht der Code nach den Namen der jeweiligen User und setzt den passenden Text ein.
Nun würde ich dieses Script gerne so erweitern, dass in dieser Textdatei "daten.txt" auch die zu den Mitarbeitern passenden Druckernamen mit ausgelesen werden können. Es müßten also 2 weitere Strings dort eingesetzt werden können (a: Drucker zum drucken des aktuellen Dokumentes // b: Standarddrucker wieder aktivieren).
Das neue Script soll dann im Einzelnen folgendes machen:
1) In der Datei "daten.txt" nach dem angemeldeten User suchen (wie es ja auch bereits unten in dem Code für die Text-Einsätze gemacht wird)
2) Dann soll der dritte String (also der jew. Druckername) gewählt werden und das Dokument dann darauf ausgedruckt werden
3) Am Ende soll wieder der Standarddrucker gewählt werden. Am besten (sichersten) wäre es, wenn dieser vielleicht in der Textdatei "daten.txt" als vierter String eingesetzt werden könnte.
Zur Info:
Mit dem bisher im unten eingesetzten Code verwendeten "strPrintername = "MV_" & strUsername & "_Blanko"" funktioniert es nicht, da die jeweiligen Drucker der Mitarbeiter unterschiedliche Namen haben.
Ich wollte dazu den hier eingesetzten Code verwenden... habe das aber nicht hinbekommen, da ich u.a. nicht sicher war, wo ich was einsetzen muss.
Wahrscheinlich muss in Zeile 4 des Codes der Zusatz "strText3 As String" und "strText4 As String" zusätzlich eingetragen werden.
Weiterhin in der Textdatei "daten.txt" die Angaben der beiden Drucker in dieser Art: --> User-Name;i. A.;Dienstbezeichnung;Druckername1;Standarddrucker
Am Ende vermute ich mal, dass für die Drucker eine Variable eingesetzt werden muss...
Wäre schön, wenn Ihr mir hierbei helfen könntet.
Danke und Gruss,
imebro
Hier der Code aus dem vorherigen Thread:
Sub Druck()
'
Dim img As InlineShape, posImage As Range, posAbteilung As Range, posImAuftrag As Range
Dim objShell As Object, fso As Object, regex As Object, matches, strText1 As String, strText2 As String
'Pfad zur Textdatei mit den Namen und Dienstbezeichnungen der Mitarbeiter der MV:
Const FILEPATH = "S:\ARCHIV\Mittelvergabe\Daten_MV\daten.txt"
'Objekte:
Set objShell = CreateObject("Wscript.Shell")
Set fso = CreateObject("Scripting.FileSystemObject")
Set regex = CreateObject("vbscript.regexp")
' Zuweisung der einzelnen Pfade:
strUsername = objShell.ExpandEnvironmentStrings("%username%")
strUserprofile = objShell.ExpandEnvironmentStrings("%userprofile%")
'Druckernamen
strPrintername = "MV_" & strUsername & "_Blanko"
'Regex Settings:
regex.Global = False: regex.IgnoreCase = True: regex.MultiLine = True
'Regex Pattern für Zeilen - Hier wird der Inhalt der Textdatei "daten.txt" ausgelesen:
regex.Pattern = "^" & strUsername & ";(.*);(.*)"
'Regex auf Inhalt der Textdatei anwenden (Usernamen suchen):
Set matches = regex.Execute(fso.OpenTextFile(FILEPATH, 1).ReadAll())
'Wurde ein Treffer gefunden setze die Variablen:
If matches.Count > 0 Then
strText1 = matches(0).Submatches(0)
strText2 = matches(0).Submatches(1)
Else 'es wurde kein passender User gefunden, (Werte der Variablen auf Defaultwerte setzen)
strText1 = ""
strText2 = ""
End If
'Beginn einsetzen von "i. A." und der passenden Dienstbezeichnung des Mitarbeiters:
Selection.GoTo wdGoToPage, wdGoToFirst
With ActiveDocument.Content.Find
.Text = "Mit freundlichen Grüßen"
.Forward = True
.Wrap = wdFindContinue
.MatchWildcards = True
.Execute
If .Found Then
'Erstellen der benötigten Anzahl Absätze
For i = 1 To 7
.Parent.InsertParagraphAfter
Next
' setze die Position 5 Absätze hinter das "Mit freundlichen Grüßen"
Set posImAuftrag = .Parent.GoTo(wdGoToLine, wdGoToNext, 5)
With posImAuftrag
.End = .Paragraphs(1).Range.End
.Font.Name = Arial
.Font.Size = 11
.Text = strText1 'einsetzen des 2. Textteils aus der Datei "daten.txt"
End With
' Setze die Position einen Absatz weiter als die "posImAuftrag" Zeile
Set posAbteilung = posImAuftrag.GoTo(wdGoToLine, wdGoToNext, 1)
With posAbteilung
.End = .Paragraphs(1).Range.End
.Font.Name = Arial
.Font.Size = 9
.Text = strText2 'einsetzen des 3. Textteils aus der Datei "daten.txt"
End With
End If
End With
Set objShell = Nothing
Set fso = Nothing
Set regex = Nothing
End Sub
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-Key: 261388
Url: https://administrator.de/contentid/261388
Ausgedruckt am: 28.03.2024 um 19:03 Uhr
31 Kommentare
Neuester Kommentar
Hello again imebro,
ich würde den Standarddrucker nicht in der Textdatei hinterlegen (falls du das wider erwarten doch willst kannst du dir jetzt abschauen wie der Regex-Pattern dazu angepasst werden muss), sondern direkt aus Word ermitteln. Die zusätzliche Spalte für den persönlichen Drucker für das Dokument habe ich dir hier ergänzt.
Kommentare findest du im Code.
Deine Druckroutine musst du noch ergänzen (s.Kommentare im Code)
Es sei dir nochmal das Regular Expressions Tutorial empfohlen damit du Regular Expression auch verstehst
Grüße Uwe
p.s. so langsam ist mal eine Spende für die Beteiligten angesagt !
ich würde den Standarddrucker nicht in der Textdatei hinterlegen (falls du das wider erwarten doch willst kannst du dir jetzt abschauen wie der Regex-Pattern dazu angepasst werden muss), sondern direkt aus Word ermitteln. Die zusätzliche Spalte für den persönlichen Drucker für das Dokument habe ich dir hier ergänzt.
Kommentare findest du im Code.
Deine Druckroutine musst du noch ergänzen (s.Kommentare im Code)
Sub Druck()
Dim img As InlineShape, posImage As Range, posAbteilung As Range, posImAuftrag As Range
Dim objShell As Object, fso As Object, regex As Object, matches, strText1 As String, strText2 As String, strPrinter As String, strPrinterDefault As String
'Pfad zur Textdatei mit den Namen und Dienstbezeichnungen der Mitarbeiter der MV:
Const FILEPATH = "S:\ARCHIV\Mittelvergabe\Daten_MV\daten.txt"
'Objekte:
Set objShell = CreateObject("Wscript.Shell")
Set fso = CreateObject("Scripting.FileSystemObject")
Set regex = CreateObject("vbscript.regexp")
' Zuweisung der einzelnen Pfade:
strUsername = objShell.ExpandEnvironmentStrings("%username%")
strUserprofile = objShell.ExpandEnvironmentStrings("%userprofile%")
'aktuellen Drucker ermitteln
strPrinterDefault = ActivePrinter
'Regex Settings:
regex.Global = False: regex.IgnoreCase = True: regex.MultiLine = True
'Regex Pattern für Zeilen - Hier wird der Inhalt der Textdatei "daten.txt" ausgelesen:
regex.Pattern = "^" & strUsername & ";(.*);(.*);(.*)"
'Regex auf Inhalt der Textdatei anwenden (Usernamen suchen):
Set matches = regex.Execute(fso.OpenTextFile(FILEPATH, 1).ReadAll())
'Wurde ein Treffer gefunden setze die Variablen:
If matches.Count > 0 Then
' i.A.
strText1 = matches(0).Submatches(0)
' Dienstbezeichnung
strText2 = matches(0).Submatches(1)
' Zieldrucker
strPrinter = matches(0).Submatches(2)
Else 'es wurde kein passender User gefunden, (Werte der Variablen auf Defaultwerte setzen)
strText1 = ""
strText2 = ""
strPrinter = strPrinterDefault
End If
'Beginn einsetzen von "i. A." und der passenden Dienstbezeichnung des Mitarbeiters:
Selection.GoTo wdGoToPage, wdGoToFirst
With ActiveDocument.Content.Find
.Text = "Mit freundlichen Grüßen"
.Forward = True
.Wrap = wdFindContinue
.MatchWildcards = True
.Execute
If .Found Then
'Erstellen der benötigten Anzahl Absätze
For i = 1 To 7
.Parent.InsertParagraphAfter
Next
' setze die Position 5 Absätze hinter das "Mit freundlichen Grüßen"
Set posImAuftrag = .Parent.GoTo(wdGoToLine, wdGoToNext, 5)
With posImAuftrag
.End = .Paragraphs(1).Range.End
.Font.Name = Arial
.Font.Size = 11
.Text = strText1 'einsetzen des 2. Textteils aus der Datei "daten.txt"
End With
' Setze die Position einen Absatz weiter als die "posImAuftrag" Zeile
Set posAbteilung = posImAuftrag.GoTo(wdGoToLine, wdGoToNext, 1)
With posAbteilung
.End = .Paragraphs(1).Range.End
.Font.Name = Arial
.Font.Size = 9
.Text = strText2 'einsetzen des 3. Textteils aus der Datei "daten.txt"
End With
End If
End With
'Ziel-Drucker für das Dokument setzen
ActivePrinter = strPrinter
' ===============================
' Hier deine Druckroutine aufrufen
' .....
' ===============================
'Alten Standarddrucker wieder setzen
ActivePrinter = strPrinterDefault
Set objShell = Nothing
Set fso = Nothing
Set regex = Nothing
End Sub
Grüße Uwe
p.s. so langsam ist mal eine Spende für die Beteiligten angesagt !
Warum schaust du nicht einfach mal nach was das ActivePrinter bedeutet, dann verstehst du es auch und musst nicht jede Kleinigkeit nachfragen.
ActivePrinter = "Druckername"
setzt den aktiven Drucker und
ActivePrinter = strPrinterDefault
setzt ihn auf den Wert zurück den er zu beginn hatte. Nicht schwer oder ?
wie man Variablen verwendet solltest du doch inzwischen wissen, denn dein Konstrukt
"strPrinter" ist so keine Variable sondern ein String...
wenn dann verwendet man die Variable natürlich so !!
ActivePrinter = "Druckername"
setzt den aktiven Drucker und
ActivePrinter = strPrinterDefault
setzt ihn auf den Wert zurück den er zu beginn hatte. Nicht schwer oder ?
wie man Variablen verwendet solltest du doch inzwischen wissen, denn dein Konstrukt
"strPrinter" ist so keine Variable sondern ein String...
wenn dann verwendet man die Variable natürlich so !!
ActivePrinter = strPrinter
Woran könnte das liegen?
Falscher Druckername wurde angegeben ...http://support.microsoft.com/kb/209722
https://msdn.microsoft.com/de-de/library/office/ff821995%28v=office.15%2 ...
Bei Netzwerkdruckern muss das anders lauten
Application.ActivePrinter = "HP LaserJet IIISi on \\printers\laser"
je nach System auch auf Deutsch ... kannst du die ja anzeigen lassen indem du den Drucker als Standard setzt und dann via Msgbox den Namen ausgeben lässt.
Gruß jodel
dann sind die Umlaute dran Schuld, weil es aus einer Textdatei ausgelesen wird.
Wenn du die Zeile so anpasst müssten diese richtig interpretiert werden, da ansonsten nur als ASCII ausgelesen wird:
Wenn du die Zeile so anpasst müssten diese richtig interpretiert werden, da ansonsten nur als ASCII ausgelesen wird:
Set matches = regex.Execute(fso.OpenTextFile(FILEPATH, 1,false,2).ReadAll())
Zitat von @37414:
...beim Test mit Deiner Code-Zeile wird genau diese beim debuggen markiert mit folgender Fehlermeldung:
"Ungültiger Prozeduraufruf oder ungültiges Argument"
Die Parameter stimmen alle, siehe:...beim Test mit Deiner Code-Zeile wird genau diese beim debuggen markiert mit folgender Fehlermeldung:
"Ungültiger Prozeduraufruf oder ungültiges Argument"
https://msdn.microsoft.com/en-us/library/aa265347(v=vs.60).aspx
eventuell sind ja Leerzeichen am Ende deines Druckernamens, oder Zeilenumbrüche. Dann musst du diese entweder mit trim() entfernen oder eben aus der Textdatei oder den Pattern auch mal so schreiben:
regex.Pattern = "^" & strUsername & ";(.*)$"
Was steht im gelben Tooltip wenn du mit der Maus über strPrinter fährst, während die Zeile gelb markiert ist ?
Schon mal was von Debugging gehört
Schon mal was von Debugging gehört
Hallo imebro!
Grüße Dieter
hmmm... verstehe ich jetzt gar nicht mehr.
Das Beispiel mit Max-Müller ist auch nur ein Beispiel.
In Wirklichkeit ist in dem Namen, mit dem ich teste, gar kein Umlaut drin...
Das Beispiel mit Max-Müller ist auch nur ein Beispiel.
In Wirklichkeit ist in dem Namen, mit dem ich teste, gar kein Umlaut drin...
Hier mal der Code des funktionierenden Druck-Makros:
ActivePrinter = "\\dasfile\Max-Müller_Brief"
Dort ist der Eintrag im Moment so angegeben:
Max-Müller;Max-Müller_Brief
Lutz-Schneider;Lutz-Schneider_Brief
Vielleicht klappts dann ja so:Max-Müller;Max-Müller_Brief
Lutz-Schneider;Lutz-Schneider_Brief
ActivePrinter = "\\dasfile\" & strPrinter
Grüße Dieter
Wie gesagt das liegt zu 99% daran das deine Druckernamen nicht exakt stimmen, da reicht schon ein hinein gerutschtes Leerzeichen am Ende aus. Das lässt sich aber mit einem Trim(strPrinter) umgehen, welches führende oder nachfolgende Leerzeichen entfernt.
Eine andere Methode den Standarddrucker zu setzen ist es via WMI zu machen.
Methode zum Auslesen des aktuellen Standarddruckers via WMI:
Methode um den Standarddrucker zurückzusetzen (oder einen anderen Drucker als Default zu deklarieren)
Das nutzt dir aber alles nichts wenn deine Namen nicht absolut korrekt sind.
Und überhaupt, was seit Ihr für eine Firma die einen Programmierneuling an solch eine Sache heran lassen ??
Ich empfehle dir dringend dich mal eingehend einzulesen und vor allem das Debugging im VBA-Editor (Breakpoints, etc) zu beherrschen. Programmieren besteht nun mal aus vielen Variablen,da zeigt es es sich meist erst in der Praxis wo es zu Problemen kommt. Office 2000 auf einem Terminalserver ist ja auch schon ein wenig irre .
Ohne mehr Infos zu den aktuellen Werten der Variablen auf der betreffenden Station und Umgebung wird das hier wieder zu einer ellenlangen Diskussion, und dir hier VBA von Grund auf beizubringen ist eigentlich nicht unsere Aufgabe, sorry...
Grüße Uwe
Eine andere Methode den Standarddrucker zu setzen ist es via WMI zu machen.
Methode zum Auslesen des aktuellen Standarddruckers via WMI:
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
Set colPrinters = objWMIService.ExecQuery("Select * from Win32_Printer Where Default = True")
For Each objPrinter in colInstalledPrinters
strPrinterDefault = objPrinter.Name
Next
strPrinterDefault = Replace(strPrinterDefault,"\","\\")
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
'Alten Standarddrucker wieder setzen
Set colPrinters = objWMIService.ExecQuery("Select * from Win32_Printer Where Name = '" & strPrinterDefault & "'")
For Each objPrinter in colPrinters
objPrinter.SetDefaultPrinter()
Next
Das nutzt dir aber alles nichts wenn deine Namen nicht absolut korrekt sind.
Und überhaupt, was seit Ihr für eine Firma die einen Programmierneuling an solch eine Sache heran lassen ??
Ich empfehle dir dringend dich mal eingehend einzulesen und vor allem das Debugging im VBA-Editor (Breakpoints, etc) zu beherrschen. Programmieren besteht nun mal aus vielen Variablen,da zeigt es es sich meist erst in der Praxis wo es zu Problemen kommt. Office 2000 auf einem Terminalserver ist ja auch schon ein wenig irre .
VBA/VBS/WSH/Office Developer Referenzen
- Visual Basic-Referenz
- Windows Script Host -Referenz
- Office 2010 Developer References
- Office 2013 Developer References
- Bücher zu VBA
Ohne mehr Infos zu den aktuellen Werten der Variablen auf der betreffenden Station und Umgebung wird das hier wieder zu einer ellenlangen Diskussion, und dir hier VBA von Grund auf beizubringen ist eigentlich nicht unsere Aufgabe, sorry...
Grüße Uwe
Zitat von @37414:
Da hatte ich doch schon den folgenden Tipp erhalten, mit dem $-Zeichen zusätzlich:
Das hast du aber falsch Interpretiert, das Dollarzeichen bezeichnet das Ende einer Zeile und soll verhindern das Zeilenumbrüche mit in die Variable wandern, das tun sie aber trotzdem nicht.Da hatte ich doch schon den folgenden Tipp erhalten, mit dem $-Zeichen zusätzlich:
Meintest Du mit "Leerzeichen am Ende..." in meiner Textdatei "druck.txt"?
Ich meine jegliche Leerezeichen die vor und hinter den Semikolons stehen, denn diese sind ja die Trenner der Spalten.Ich könnte das Regex-Pattern jetzt natürlich auch noch so erweitern das das alles egal wäre. Aber wenn du weißt worauf es ankommt ist das ja nicht nötig.
Die habe ich überprüft - und da sind keine Leerzeichen drin.
Die Namen stimmen zu 100% überein.
Aber... könnte es auch mit Groß-/Kleinschreibung zusammenhängen?
In einem Test tut es das hier nicht.Die Namen stimmen zu 100% überein.
Aber... könnte es auch mit Groß-/Kleinschreibung zusammenhängen?
Wo müßte ich das "Trim(strPrinter)" denn im Code einsetzen?
das kannst du schon ganz zu Beginn hier machen:strPrinter = Trim(matches(0).Submatches(0))
Nun habe ich dieses ominöse "NE14" einfach mal in der Textdatei "druck.txt" noch hinter den Druckernamen eingegeben... und zwar so:
hab ich doch schon ganz zu Beginn geschrieben ... aber wer nicht hören will muss fühlen :-PSeltsam finde ich nur, dass es bei mir auch ohne das "NE14" (oder einen ähnlichen Ausdruck) funktioniert...
Du sagst ja auch kein Wort wie sich dein System vom anderen unterscheidet (Server/Client/ etc. pp)
Benutze die WMI-Variante von @colinardo die ist in dieser Hinsicht Systemübergreifend sowieso die bessere Variante. Bei ActivePrinter gibt es je nachdem wie der Drucker eingerichtet wurde eben ab und zu mal Probleme.
Gruß jodel32
Gruß jodel32
Hallo zusammen!
Beim Umstellen des Standarddruckers per WMI ändert sich leider nix an der ActivePrinter-Einstellung in Word...
Hier mal ein Code, mit dem es funktionieren sollte:
Wobei die Vollständigkeit des Druckernamens unvollständig sein darf, da der Druckername anhand des angegebenen Teilnamens ermittelt wird z.B.
reicht "MX850" als Angabe für "Canon MX850 series Printer auf Ne02:"
Grüße Dieter
Beim Umstellen des Standarddruckers per WMI ändert sich leider nix an der ActivePrinter-Einstellung in Word...
Hier mal ein Code, mit dem es funktionieren sollte:
Private Declare Function GetProfileString Lib "kernel32" Alias "GetProfileStringA" ( _
ByVal lpAppName As String, _
ByVal lpKeyName As String, _
ByVal lpDefault As String, _
ByVal lpReturnedString As String, _
ByVal nSize As Long) As Long
Public Sub DeineSub()
Call Printer("Müller_Blanko")
Call Printer("Müller_Brief")
End Sub
Private Sub Printer(ByVal strName As String)
Dim colPrinters As Object
Dim strBuff As String, strPrinter As String, strDefaultPrinter As String
strDefaultPrinter = ActivePrinter
With GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
Set colPrinters = .ExecQuery("Select * From Win32_Printer Where Name Like '%" & strName & "%'")
If colPrinters.Count Then
strBuff = Space(1024)
strPrinter = colPrinters.ItemIndex(0).Name
GetProfileString "PrinterPorts", strPrinter, "", strBuff, Len(strBuff)
If InStr(strBuff, ",") Then
'strPrinter = strPrinter & " auf " & Split(strBuff, ",")(1) 'Deutsch
strPrinter = strPrinter & " on " & Split(strBuff, ",")(1) 'Englisch
End If
On Error Resume Next
ActivePrinter = strPrinter
If Err.Number = 0 Then
Application.PrintOut Filename:="", Range:=wdPrintAllDocument, Item:= _
wdPrintDocumentContent, Copies:=1, Pages:="", PageType:=wdPrintAllPages, _
Collate:=True, Background:=True, PrintToFile:=False, PrintZoomColumn:=0, _
PrintZoomRow:=0, PrintZoomPaperWidth:=0, PrintZoomPaperHeight:=0
ActivePrinter = strDefaultPrinter
Else
MsgBox "Drucker nicht gefunden: " & strName, vbExclamation, "Drucken . . ."
End If
On Error GoTo 0
Else
MsgBox "Drucker nicht gefunden: " & strName, vbExclamation, "Drucken . . ."
End If
End With
End Sub
reicht "MX850" als Angabe für "Canon MX850 series Printer auf Ne02:"
Grüße Dieter