Hi,
ich habe wieder mal ein kleines Probelm und das Internet war da nicht grade hilfreich. Ich hab nun nochmehr Fragezeichen vor meinem Kopf als vorher. Aber zu meinem Problem.
Ich habe es ja nun hinbekommen, dass ich PDFs aus Access herraus drucke. Dafür startet im Hintergrund - das Fenster erscheint nur in der Taskleiste und nicht groß, so dass ich automatisch einen Blickdaruf werfe - und druckt dann die Datei. Das Fenster bleibt grau, also ich bekomme den Inhalt nicht angezeigt.
So weit so gut, nun möchte ich jedoch, dass sich der Adobe Reader nach dem Drucken - bzw. nachdem er den Druckbefehl geschickt hat - wieder schließt.
Ich hab wohl den Befehl WM_Close gefunden, aber dieser hilft mir so, ohne das ich weiss, wie und wo ich ihn anwenden muss, nicht weiter.
Kann mir da vielleicht jemand weiterhelfen?
Vielen Dank schonmal.
LG Salvation
Hi,
folgenden Code hab ich nun ausprobiert:
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, _
ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Const WM_CLOSE = &H10
Public Sub Kill()
Dim Ergebnis
Ergebnis = Shell("C:\Dokumente und Einstellungen\prakedv2\Eigene Dateien\TestPDF.pdf", vbNormalFocus)
Dim WinWnd As Long
WinWnd = FindWindow(vbNullString, "TestPDF.pdf") ' Name in "" muss passen!
If WinWnd <> 0 Then
PostMessage WinWnd, WM_CLOSE, 0&, 0&
Else
MsgBox "No window of that name exists."
End If
End Sub
Die PDF wird geöffnet, jedoch bekommen ich folgende Fehlermeldung:
Laufzeitfehler '5':
Ungültiger Prozeduraufruf oder ungültiges Aggument
Und dabei wird mir folgender Codeteil gelb makiert:
Ergebnis = Shell("C:\Dokumente und Einstellungen\prakedv2\Eigene Dateien\TestPDF.pdf", vbNormalFocus)
LG Salvation
Erweitert, bzw verändert, dennoch ein Problem
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, _
ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Const WM_CLOSE = &H10
Public Sub Kill()
'Dim Ergebnis
'Ergebnis = Shell("", vbNormalFocus)
Dim WinWnd As Long
WinWnd = FindWindow(vbNullString, "TestPDF - Adobe Reader") ' Name in "" muss passen!
If WinWnd <> 0 Then
PostMessage WinWnd, WM_CLOSE, 0&, 0&
Else
MsgBox "No window of that name exists."
End If
End Sub
Ich bekomme die Meldung "No window of that name exist." Dabei hab ich genau den Title der PDF eingegeben, so wie es auch im Kopf steht.
LG Salvation
Hallo,
Prinzipiell ist das der richtige Weg, den Fensterhandle suchen und per API das Fenster schließen.
Mach doch mal eine Schleife über alle offenen Fenster und sieh dir die Namen an, eventuell wird er anderst geschrieben?
Andreas
Hi,
okay, auch wenn ich einige koriouse Fragen stelle und mir irgendwie alles zusammen suche, weiss ich leider nicht alles. *schäm*
Wie kann ich eine Schleife basteln, die mir dann die Namen der offenen Fenster rausgibt?
LG Salvation
Hallo,
googeln hilft zuweilen:
http://www.herber.de/forum/archiv/1160to1164/t1161929.htm#1161929
Gruß Andreas
Hi,
also, mit diesem netten Code bekomme ich es hin, dass ich eingeben kann ob das Fenster geöffnet ist, oder nicht, aber nicht, welchen Namen die Datei trägt.
Option Explicit
'Listet alle aktiven Fenter / Applikation auf
Private Declare Function GetWindow Lib "User32" _
(ByVal appWnd As Long, ByVal wCmd As Long) As Long
Private Declare Function GetWindowLong Lib "User32" Alias "GetWindowLongA" _
(ByVal appWnd As Long, ByVal wIndx As Long) As Long
Private Declare Function GetWindowTextLength Lib "User32" Alias "GetWindowTextLengthA" _
(ByVal appWnd As Long) As Long
Private Declare Function GetWindowText Lib "User32" Alias "GetWindowTextA" _
(ByVal appWnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare Function FindWindow Lib "User32" Alias "FindWindowA" _
(ByVal lpClassName As Long, ByVal lpWindowName As Long) As Long
Const GW_HWNDFIRST = 0
Const GW_HWNDNEXT = 2
Const GWL_STYLE = (-16)
Const WS_VISIBLE = &H10000000
Const WS_BORDER = &H800000
Sub Start_Test_Run()
Dim chkName As String
chkName = InputBox _
("Geben Sie den Fenstertitel ein." & Chr$(13) & _
"ACHTUNG: Case Sensitiv !!", "Suche Application", "Excel")
If chkName = "" Then Exit Sub
If Check_Open_Application(chkName) = True Then
MsgBox chkName & ": Geöffnet"
Else
MsgBox chkName & ": Nicht Geöffnet"
End If
End Sub
Function Check_Open_Application(AppName As String) As Boolean
'Test Function
'Parameter 0: Es wird jedes Fenster explicit nach dem String überprüft
'Parameter 1: Alle geöffneten Programme werden in einer MsgBox angezeigt.
If GetWindowList(AppName, 0) Then
Check_Open_Application = True
Else
Check_Open_Application = False
End If
End Function
Public Function GetWindowList(findApp As String, kindMsg As Integer) As Boolean
'Gibt True zurück wenn die Applikation aktiv ist
Dim app() As Long
Dim appWnd As Long, appTitle As String, appStyle As Long, appTask_name() As String
Dim appCount As Integer, appIndex As Integer, appFound As Boolean
Dim msgTxt As String
appWnd = FindWindow(ByVal 0&, ByVal 0&)
appWnd = GetWindow(appWnd, GW_HWNDFIRST)
'1. Initialisierung
GetWindowList = False
Do
'Loop starten durch alle geöffneten Fenster
appFound = False
appStyle = GetWindowLong(appWnd, GWL_STYLE)
appStyle = appStyle And (WS_VISIBLE Or WS_BORDER)
appTitle = GetWindowTitle(appWnd)
'Alle gefundenen Applicationen in einen Array aufnehmen
If (appStyle = (WS_VISIBLE Or WS_BORDER)) = True Then
If Trim(appTitle) <> "" Then
For appIndex = 1 To appCount
If appTask_name(appIndex) = appTitle Then
appFound = True
Exit For
End If
Next appIndex
If Not appFound Then
appCount = appCount + 1
ReDim Preserve appTask_name(1 To appCount)
appTask_name(appCount) = appTitle
ReDim Preserve app(1 To appCount)
app(appCount) = appWnd
End If
End If
End If
appWnd = GetWindow(appWnd, GW_HWNDNEXT)
Loop Until appWnd = 0
'Durchsuchen des erstellten Arrays nach der Application
If kindMsg = 0 Then
For appIndex = 1 To appCount
'Es wird nur der übergebene String in "appTask_Name" gesucht
'Die Instanz selbst wird nicht identifiziert.
'Dazu müsste noch der String "Microsoft" geprüft werden
If InStr(1, appTask_name(appIndex), findApp) > 1 Then
'Application gefunden = Ende der Schleife
GetWindowList = True
Exit Function
End If
Next appIndex
ElseIf kindMsg = 1 Then
For appIndex = 1 To appCount
msgTxt = msgTxt & "Aktiv: " & appTask_name(appIndex) & Chr$(13)
Next appIndex
MsgBox msgTxt
GetWindowList = True
End If
End Function
Private Function GetWindowTitle(ByVal appWnd As Long) As String
Dim appResult As Long, appTempStr As String
appResult = GetWindowTextLength(appWnd) + 1
appTempStr = Space(appResult)
appResult = GetWindowText(appWnd, appTempStr, appResult)
GetWindowTitle = Left(appTempStr, Len(appTempStr) - 1)
End Function
Und mit dem Code auf dieser Seite http://www.herber.de/forum/archiv/1156to1160/t1158568.htm bekomme ich nur die Ausgabe vom Access Fenster, aber keine weitere.
LG Salvation
Hallo,
setzt mal ein Haltepunkt bei If kindMsg = 0 Then und starte den Code indem du "Start_Test_Run" ausführst.
Also bei mir hat er zumindest mal Outlook gefunden.
Andreas
Hi,
finden kann ers bei mir auch. Dann bis meldung, ob geöffnet oder nicht. Also geöffnet, wenn ich auch in der Taskleiste habe. Da findet er bei mir den Adobe Reader, wie aich den Internet Explorer.
Nur wie soll ich mir dann die Fensternamen anzeigen lassen? Das geht mit dem zweiten Quellcode, jedoch hat der immer Focus auf Access und sieht damit die anderen Fenster nicht, slebst wenn ich sie hoch habe.
*im Moment leicht verwirrt ist*
Salvation
Das steht doch im Code:
Es wird nur der übergebene String in "appTask_Name" gesucht
appTask_name(appIndex) liefert dann den Namen bzw. den Fenstertitel der Aplikation.
Was ist daran verwirrend?
Andreas
Hi,
Weil, wenn ich da eingebe, wonach er suchen soll zwei Versionen bekomme
Gebe ich Adobe Reader ein, bekomme ich ein Geöffnet und
gebe ich Reader ein, bekomme ich auch ein Geöffnet.
Genaue Ausgabe:
Adobe Reader : Geöffnet
Reader : Geöffnet
Das verwirrt mich.
Dieser Code:
Option Compare Database
Option Explicit
Private Declare Function GetForegroundWindow Lib "user32.dll" () As Long
Private Declare Function GetWindowText Lib "user32.dll" Alias "GetWindowTextA" ( _
ByVal hwnd As Long, _
ByVal lpString As String, _
ByVal cch As Long) As Long
Private Declare Function GetWindowTextLength Lib "user32.dll" Alias "GetWindowTextLengthA" ( _
ByVal hwnd As Long) As Long
Public Sub test()
Dim lngHwnd As Long, lngReturn As Long
Dim strCaption As String
lngHwnd = GetForegroundWindow
lngReturn = GetWindowTextLength(lngHwnd)
strCaption = Space$(lngReturn)
Call GetWindowText(lngHwnd, strCaption, lngReturn + 1)
MsgBox strCaption
End Sub
Gibt mir mehr aus. Sprich auch, was genau ich davon geöffnet habe. nur dieser bezieht sich NUR aufs Access Fenster und ignoriert alle anderen.
LG Salvation
Hallo,
na klar weil das Wort Reader auch in Acrobat Reader drinsteckt.
Sieh dir doch mal den Code an. Wieviel Ahnung von VBA hast du eigentlich?
If InStr(1, appTask_name(appIndex), findApp) > 1 Then
Sucht doch die Eingabe findApp innerhalb des Strings appTask_name(appIndex)
Andreas
Hi,
ZitatWieviel Ahnung von VBA hast du eigentlich?
Hm... ich stufe mich selbst mit "Null Erfahrung" ein. Warum? Sagen wir es so. Access als Datenbankprogramm hab ich schon oft genutzt, nur VBA nicht. Da ich nun in einer Umschulung bin, mache ich mein Praktikum in einem Krankenhaus, die gerne Programme mit Access und VBA haben möchten. Ich habe hier fertige Programme, die ich mir anschauen kann, nur - sorry, falls ich nun jemanden zu nahe trete - wenn ich mit Null erfahrung reingehe, man von mir erwartet, dass ists hinbekomme, aber ich weder Bücher, noch Hilfe von jemanden bekomme, der es mir erklärt, versteh ich nicht die Funktionen.
Ich beiss mich durch, bzw. wie ichs sage, schummel mich durch. Ich hab leider nur einige Foren, wo ich schauen kann und versuch mich selbst erstmal im Netz schlau zu machen. Nur wie gesagt, wenn man zum Teil nicht mal den Code versteht, ist es nicht immer einfach.
Sorry.
Hallo,
OK, dann ist deine Frage verständlich.
Ich werd mal schauen ob ich für dich die Anwendung umstricken kann.
Andreas
Hi,
danke. Echt nett von dir.
Wenn ichs mir aussuchen könnte, würde ich auch eher eine Programmiersprache nehmen, wo ich wenigstens einen Ansprechpartner habe. Ich kann es mir nur leider nicht aussuchen und lernen muss ich es irgendwann. Nur dass ich es auf diese Weise lernen musst, das hätte ich mir auch anders vorgestellt.
LG Salvation
OK, hier der Code:
Option Compare Database
Option Explicit
Private Declare Function GetWindow Lib "user32" _
(ByVal appWnd As Long, ByVal wCmd As Long) As Long
Private Declare Function FindWindow Lib "user32" _
Alias "FindWindowA" ( _
ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" _
(ByVal appWnd As Long, ByVal wIndx As Long) As Long
Private Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" _
(ByVal appWnd As Long) As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
(ByVal appWnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare Function SendMessage Lib "user32.dll" Alias _
"SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, _
ByVal wParam As Long, lParam As Any) As Long
Const WM_CLOSE = &H10
Const GW_HWNDFIRST = 0
Const GW_HWNDNEXT = 2
Const GWL_STYLE = (-16)
Const WS_VISIBLE = &H10000000
Const WS_BORDER = &H800000
Sub Start_Test_Run()
Dim chkName As String
Dim winName As String
Dim hwnd As Long
chkName = "Adobe Reader"
winName = Nz(GetWindowName(chkName), "")
If Len(winName) = 0 Then
MsgBox "Die Anwendung wurde nicht gefunden!"
Else
hwnd = FindWindowHandle(winName)
If hwnd <> 0 Then
SendMessage hwnd, WM_CLOSE, ByVal 0&, ByVal 0&
MsgBox "Fenster geschlossen"
End If
End If
End Sub
Public Function GetWindowName(findApp As String) As String
Dim app() As Long
Dim appWnd As Long, appTitle As String, appStyle As Long, appTask_name() As String
Dim appCount As Integer, appIndex As Integer, appFound As Boolean
Dim msgTxt As String
appWnd = FindWindow(vbNullString, vbNullString)
appWnd = GetWindow(appWnd, GW_HWNDFIRST)
Do
appFound = False
appStyle = GetWindowLong(appWnd, GWL_STYLE)
appStyle = appStyle And (WS_VISIBLE Or WS_BORDER)
appTitle = GetWindowTitle(appWnd)
If (appStyle = (WS_VISIBLE Or WS_BORDER)) = True Then
If Trim(appTitle) <> "" Then
For appIndex = 1 To appCount
If appTask_name(appIndex) = appTitle Then
appFound = True
Exit For
End If
Next appIndex
If Not appFound Then
appCount = appCount + 1
ReDim Preserve appTask_name(1 To appCount)
appTask_name(appCount) = appTitle
ReDim Preserve app(1 To appCount)
app(appCount) = appWnd
End If
End If
End If
appWnd = GetWindow(appWnd, GW_HWNDNEXT)
Loop Until appWnd = 0
For appIndex = 1 To appCount
If InStr(1, " " & appTask_name(appIndex), findApp) > 1 Then
GetWindowName = appTask_name(appIndex)
Exit Function
End If
Next appIndex
End Function
Public Function FindWindowHandle(ByVal sTitle As String) As Long
Dim lngHWnd As Long
Dim sText As String
' alle Fenster durchlaufen
lngHWnd = FindWindow(vbNullString, vbNullString)
Do While lngHWnd <> 0
' Fensterttitel ermitteln
sText = GetWindowTitle(lngHWnd)
If Len(sText) > 0 And LCase$(sText) Like LCase$(sTitle) Then
FindWindowHandle = lngHWnd: Exit Do
End If
' Nächstes Fenster
lngHWnd = GetWindow(lngHWnd, GW_HWNDNEXT)
Loop
End Function
Private Function GetWindowTitle(ByVal appWnd As Long) As String
Dim appResult As Long, appTempStr As String
appResult = GetWindowTextLength(appWnd) + 1
appTempStr = Space(appResult)
appResult = GetWindowText(appWnd, appTempStr, appResult)
GetWindowTitle = Left(appTempStr, Len(appTempStr) - 1)
End Function
Einfach in ein Modul kopieren und die Startprozedur ausführen (vorher Adobe Reader Fenster öffnen)
Gruß Andreas
Hi,
erstmal nochmal vielen lieben dank.
Nun hab ich dennoch eine Frage. Kann ich den Code von dir auch mit diesen hier zusammen fügen?
Private Sub Internet_Click()
Dim Pfad As String
'Pfad der gewünschten PDF
Pfad = "C:\Dokumente und Einstellungen\prakedv2\Eigene Dateien\TestPDF.pdf"
DateiOeffnen "print", Pfad, SW_MAXIMIZE
End Sub
Mit einem CALL in dem Code hab ichs schon versucht, dann findet er das Dokument nicht. Verständlicher weise, we läuft ja schon, bevor das Dokument geöffnet wurde.
LG Salvation
Hallo,
du willst ein Dokument öffnen und sofort wieder schließen?
Macht das Sinn?
Erzähl doch mal genau was du vorhast.
Hi,
also das Programm, bzw. die Prozedur, soll eine PDF ausdrucken. Die brauch dabei nicht mal geöffnet werden, wes muss ledigklich ein Druckbefehl rausgehen, wenn ich auf den Button klicke. Das was ich nutze, öffnet den Reader, sendet den Befehl zum drucken und schließt das Dokument, aber nicht den Reader selbst.
Damit dieser nicht in der Taskleiste bleibt und die User irritiert, soll er eben geschlossenw erden, sobald der Druckbefehl raus ist.
Das ist der Sinn hinter dem Vorhaben.
LG Salvation
Hallo,
na dann zuerst drucken danach die Prozedur zum Schließen aufrufen.
Andreas
Hi,
sorry, dass ich mich nun erst melde, hatte am Wochenende einiges zu tun.
Meine Prozedur zum Drucken hat ja folgendes Modul:
Option Explicit
Public Declare Function ShellExecute Lib "shell32.dll" Alias _
"ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String _
, ByVal lpFile As String, ByVal lpParameters As String _
, ByVal lpDirectory As String _
, ByVal nshowcmd As Long) As Long
Public hwnd As Long
Public Const SW_HIDE = 0 ' Versteckt öffnen
Public Const SW_MAXIMIZE = 3 ' Maximiert öffnen
Public Const SW_MINIMIZE = 6 ' Minimiert öffnen
Public Const SW_NORMAL = 1
Public Const SW_RESTORE = 9
Public Const SW_SHOWMAXIMIZED = 3
Public Const SW_SHOWMINIMIZED = 2
Public Const SW_SHOWMINNOACTIVE = 7
Public Const SW_SHOWNOACTIVATE = 4
Public Function DateiOeffnen(Aktion As String, Pfad As String _
, Ansicht As Long) As Boolean
Call ShellExecute(hwnd, Aktion, Pfad, "", "", Ansicht)
End Function
Und wird dann wie folgt aufgerufen:
Private Sub Internet_Click()
Dim Pfad As String
'Anmerkung: Gedruckt wird auf dem Drucker, der Standartmässig in Access eingestellt ist
'Siehe ggf: Datei -> Drucken -> Drucken
'Pfad der gewünschten PDF
Pfad = "C:\Dokumente und Einstellungen\prakedv2\Eigene Dateien\TestPDF.pdf"
DateiOeffnen "print", Pfad, SW_MAXIMIZE
End Sub
Ich hab nun schon versucht gehabt, so wie ich es kenne, mit einem CALL nach dem, dass er Drucken soll. Wenn ich dann den Button anklicke, läuft die Prozedur durch, ich bekomme die Meldung, dass er kein Dokument zum Schließen gefunden hat und öffnet dann erst den Reader.
Kann es damit zusammenhängen, dass ich mir das Dokument nur öffnen lasse im Test? Weil immer wieder Papier durch den Drucker jagen, für einen Test, obs geht, wollte ich nun auch nicht, darum hab ich das ,,print" durch ,,open" in meinem Code getauscht und lasse es mir nur anzeigen. Eigentlich kanns daran, so denke ich, nicht liegen, vielleicht irre ich mich auch.
Oder gibt es neben dem CALL, welches ich als einziges kenne, noch eine Aufruf-Form?
LG Salvation
N'abend Andreas
Zitat von: Hondo am Mai 27, 2011, 09:02:29
OK, hier der Code:
Danke, hat zum Schließen für etwas anderes als Adobe gut geholfen.
Harald
Hallo,
hier stehen noch ein paar interessante Dinge:
http://www.team-moeller.de/?Tipps_und_Tricks:Access_und_Adobe_Reader_7
Hi,
aufgrund dessen, dass ich eine Weile Krankgeschrieben war, konnte ich nicht weiter an meinem Problem arbeiten. Nun jedoch will ich es nochmal in Angriff nehmen.
Wie schon angemerkt, funktioniert dir Prozedur von Hondo – danke nochmal – als eigenständige Prozedur. OHNE das ich es irgendwo einbinde. Derzeit zum Probieren, hat es einen eigenen Button. Kein Problem!
Wenn ich es nun mir der vorhergehenden Prozedur – die des PDF drucken – verbinde, geht es nicht. Weder wenn ich den CALL-Aufruf im Formular
Private Sub Internet_Click()
Dim Pfad As String
'Anmerkung: Gedruckt wird auf dem Drucker, der Standartmässig in Access eingestellt ist
'Siehe ggf: Datei -> Drucken -> Drucken
'Pfad der gewünschten PDF
Pfad = "C:\Dokumente und Einstellungen\prakedv2\Eigene Dateien\TestPDF.pdf"
DateiOeffnen "print", Pfad, SW_MAXIMIZE
End Sub
noch im Modul
Option Compare Database
Option Explicit
Public Declare Function ShellExecute Lib "shell32.dll" Alias _
"ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String _
, ByVal lpFile As String, ByVal lpParameters As String _
, ByVal lpDirectory As String _
, ByVal nshowcmd As Long) As Long
Public hwnd As Long
Public Const SW_HIDE = 0 ' Versteckt öffnen
Public Const SW_MAXIMIZE = 3 ' Maximiert öffnen
Public Const SW_MINIMIZE = 6 ' Minimiert öffnen
Public Const SW_NORMAL = 1
Public Const SW_RESTORE = 9
Public Const SW_SHOWMAXIMIZED = 3
Public Const SW_SHOWMINIMIZED = 2
Public Const SW_SHOWMINNOACTIVE = 7
Public Const SW_SHOWNOACTIVATE = 4
Public Function DateiOeffnen(Aktion As String, Pfad As String _
, Ansicht As Long) As Boolean
Call ShellExecute(hwnd, Aktion, Pfad, "", "", Ansicht)
Call Start_Test_RunEnd Function
einbinde. Die Prozedur wird komplett durchlaufen, ich become die Meldung, dass er das Programm, was geschlossen werden soll, nicht finden kann und DANN geht Adobe Reader erst auf.
Was das ,,Drucken mit ShellExecute" angeht, fiel mir dieser hinweis auf:
ZitatMit einem Update auf die Version 7.0.5 oder höher ist dieses Problem beseitigt und der Adobe Reader verhält sich wieder wie gewohnt.
Ich denke es bezieht sich alles auf den Adobe Reader. Ich hab auf dem Rechner die Version 9.1.0, also höher als 7.0.5 und damit sollte es dann ja behoben sein, oder habe ich da was falsch verstanden?
LG Salvation
ZitatDie Prozedur wird komplett durchlaufen, ich become die Meldung, dass er das Programm, was geschlossen werden soll, nicht finden kann und DANN geht Adobe Reader erst auf.
Liegt daran das der Befehl in ShellExecute asyncron angeschoben wird, dein AccessVBA-Code geht weiter während ShellExecute gerade erst initialisiert wird ( eigener Prozess/Thread ). Mittels einer Do/Loop schleife könnte man eine Warte-Routine einbringen die vorher prüft ob der betreffende Adobeprozess gestartet ist und dann weitergeht.
Nur frage ich mich gerade was das mit dem Adobe starten und gleich wieder schließen beim Druckvorgang auf sich hat, für den eigentlichen Druckvorgang macht das eigentlich keinen Sinn.
Hi,
wusste ich doch, dass ich was übersehen habe *schäm* Sorry.
Ich schau mal, ob ich eine Do/Loop einbinden kann. Dass wird aber nicht unmittelbar nun sein, sondern in einigen Tagen, je nachdem, wie lange ich mit der neuen Aufgabe beschäftigt bin. Im Moment hab ich es nun erstmal so, dass sich der Adobe Reader einfach öffnet und man dann daraus dann manuell druckt.
ZitatNur frage ich mich gerade was das mit dem Adobe starten und gleich wieder schließen beim Druckvorgang auf sich hat, für den eigentlichen Druckvorgang macht das eigentlich keinen Sinn.
Soweit wie ich gekommen bin, kann ich aus Access heraus eine PDF drucken. Dabei öffnet sich im Hintergrund der Adobe Reader. Nach dem Drucken schließt er nicht, sondern bleibt in der Taskleiste. Wenn ich ihn anzeigen lasse, wird kein Dokument angezeigt.
Da es 'nervig' sein kann, einen leeren Reader in der Taskleiste zu haben - bzw. einige User nicht verstehen würden, warum der auf einmal da ist und damit irritiert, ggf. überfordert sind (hab ich auch schon erlebt) - und daher möchte ich ihn nach dem drucken wieder schließen. So dass er nur für einen Moment offen ist, damit der Druckbefehl rausgeht.
Sollte es eine Möglickeit geben, eine PDF zu drucken, ohne das der Reader startet, bin ich für jede lösung dankbar. Ich hab leider nur die gefunden, bzw. Zwei, wobei die erste meinen Reader nich finden konnte und damit dann auch nicht geschlossen werden konnte. Was das Drucken angeht, habe ich nur die eine Lösung gefunden.
LG Salvation
ZitatSoweit wie ich gekommen bin, kann ich aus Access heraus eine PDF drucken. Dabei öffnet sich im Hintergrund der Adobe Reader. Nach dem Drucken schließt er nicht, sondern bleibt in der Taskleiste. Wenn ich ihn anzeigen lasse, wird kein Dokument angezeigt.
Ich vermute jetzt mal das dein Standard-Drucker evtl. ein PDF-Druckertreiber ist, der dafür verantwortlich ist. Eine vorhandene PDF mit ShellExecute an einen physischen Drucker gesendet öffnet bei mir zumindest keinen PDF-Reader, sondern druckt nur die PDF. Ggf. solltest du mal deine Standarddruckertreiber - einstellungen überprüfen.
Hi,
soweit ich weiss, ist es kein PDF-Drucker. Aber da ich ja nur in einer Umgebung gestezt wurde und ich dmait dann arbeite, kann es vielleicht doch sein. Da der gute Herr, der dafür zuständig ist, im Moment nicht da ist, werde ich mich da Morgen mal hinter klemmen.
Danke schonmal. Werde morgen berichten, was los ist.
Salvation
So Informationen bekommen,
der Standard-Drucker ist kein PDF-Drucker. Es ist jedoch auf den Rechnern jeweils einer Installiert, den man dann auswählen kann. Da ich keine Druckerauswahl mache, gehe ich davon aus, dass der Drucker genommen wird, der im Windows als Standart-Drucker ausgewählt ist. Zudem Druckt er auch die Unterlagen auf genau dem Rechner. Wenn ich da Falsch liege, belehrt mich gerne eines besseren. Aber ich kann mir nicht vorstellen, dass der den PDF-Drucker da auch noch irgendwie zwischen schaltet und dennoch auf dem Standard-Drucker druckt.
Salvation
Hallo,
noch ein Versuch ;D
Per Button-Klick PDF-Datei öffnen, drucken und Acrobat-Reader danach schließen (Deine bisherigen Codes in Verwendung):
Private Sub Internet_Click()
Dim Pfad As String
'Anmerkung: Gedruckt wird auf dem Drucker, der Standartmässig in Access eingestellt ist
'Siehe ggf: Datei -> Drucken -> Drucken
'Pfad der gewünschten PDF
Pfad = "C:\Dokumente und Einstellungen\prakedv2\Eigene Dateien\TestPDF.pdf"
DateiOeffnen "print", Pfad, SW_MAXIMIZE
'---------NEU--------------------------------------
DoCmd.Hourglass True ' Sanduhr muss nicht sein....
Sleep 5000 ' ---> hier sind z.B 5 sec Wartezeit bis zum Beenden des Readers eingetragen (abhängig von der jeweiligen Geschwindigkeit)
DoCmd.Hourglass False
Call beendeAcro
'---------------------------------------------------
End Sub
.... zum Beenden des (z.B.) Adobe-Reader 9
Private Sub beendeAcro()
On Error Resume Next
Dim strComputer, PID, objWSHShell, objWMIService, colItems, objItem, ra, WScript
strComputer = "."
PID = 0
Set objWSHShell = CreateObject("WScript.Shell")
Do
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_Process", , 48)
If PID = 0 Then
For Each objItem In colItems
ra = objItem.Caption
If InStr(1, ra, "AcroRd32.exe") Then ' ---> Prozessnamen aus dem Taskmanager ermitteln!
PID = objItem.ProcessId
objItem.Terminate
Exit For
End If
Next
Else
Exit Do
End If
Loop
End Sub
.... und die Aufrufe in einem Modul ...
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Public Declare Function ShellExecute Lib "shell32.dll" Alias _
"ShellExecuteA" (ByVal hWnd As Long, ByVal lpOperation As String _
, ByVal lpFile As String, ByVal lpParameters As String _
, ByVal lpDirectory As String _
, ByVal nshowcmd As Long) As Long
Public hWnd As Long
Public Const SW_HIDE = 0 ' Versteckt öffnen
Public Const SW_MAXIMIZE = 3 ' Maximiert öffnen
Public Const SW_MINIMIZE = 6 ' Minimiert öffnen
Public Const SW_NORMAL = 1
Public Const SW_RESTORE = 9
Public Const SW_SHOWMAXIMIZED = 3
Public Const SW_SHOWMINIMIZED = 2
Public Const SW_SHOWMINNOACTIVE = 7
Public Const SW_SHOWNOACTIVATE = 4
Public Function DateiOeffnen(Aktion As String, Pfad As String _
, Ansicht As Long) As Boolean
Call ShellExecute(hWnd, Aktion, Pfad, "", "", Ansicht)
End Function
Damit wird aufgerufen, gedruckt und beendet
HTH