Neuigkeiten:

Wenn ihr euch für eine gute Antwort bedanken möchtet, im entsprechenden Posting einfach den Knopf "sag Danke" drücken!

Mobiles Hauptmenü

Adobe Reader aus Access heraus schließen

Begonnen von Salvation, Mai 26, 2011, 08:49:01

⏪ vorheriges - nächstes ⏩

Hondo

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

Salvation

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

Hondo

Hallo,
du willst ein Dokument öffnen und sofort wieder schließen?
Macht das Sinn?

Erzähl doch mal genau was du vorhast.

Salvation

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

Hondo

Hallo,
na dann zuerst drucken danach die Prozedur zum Schließen aufrufen.

Andreas

Salvation

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

bahasu

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
Servus


Salvation

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


daolix

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.

Salvation

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

daolix

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.

Salvation

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

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

database

#29
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