Edition PDF

PERRINFAB

XLDnaute Nouveau
Bonjour

J'ai trouvé sur le forum des codes pour éditer une feuille excel en format pdf.
Cependant, le programme fonctionne 1 fois puis renvoie l'erreur :

can't initialize PDFcréator

En effet le processus reste ouvert.

J'ai tenté la fonction Taskkill trouvée sur le forum mais sans succès car elle n'est pas présente sur mon PC.

J'ai alors essayé avec TSkill mais le PC ne comprend pas non plus.
J'ai téléchargé le programme TSKILL mais je ne sais pas où l'enregistrer et la méthode de codage.

Pouvez-vous m'éclairer sur la méthodologie à appliquer :
- lieu de stockage de tskill.exe
- type de codification : tskill pdfcreator
- ou bien toute solution qui me permette de flinguer ce porcessus avant de relancer ma macro

Merci de votre contribution

A+




Ci contre la partie de mon programme :

Sheets("BSI").Select

Dim pdfjob As Object
Dim sPDFName As String
Dim sPDFPath As String
'/// Changer le nom du fichier de sortie sur la ligne ci dessous: ///
sPDFName = Range("H2")
sPDFPath = ThisWorkbook.Path & "\Edition\" & Range("I2") & "\" & Range("J2") & "\"
'Check if worksheet is empty and exit if so

'Kill "PDFCreator.exe"
If IsEmpty(ActiveSheet.UsedRange) Then Exit Sub
Set pdfjob = CreateObject("PDFCreator.clsPDFCreator")
With pdfjob
If .cStart("/NoProcessingAtStartup") = False Then
MsgBox "Can't initialize PDFCreator.", vbCritical + _
vbOKOnly, "PrtPDFCreator"
Exit Sub
End If
.cOption("UseAutosave") = 1
.cOption("UseAutosaveDirectory") = 1
.cOption("AutosaveDirectory") = sPDFPath
.cOption("AutosaveFilename") = sPDFName
.cOption("AutosaveFormat") = 0 ' 0 = PDF
.cClearCache
End With
'Imprime le document en PDF
ActiveSheet.PrintOut copies:=1, ActivePrinter:="PDFCreator sur Ne00:"
'Attend que le document soit entré dans la file d'impression
Do Until pdfjob.cCountOfPrintjobs = 1
DoEvents
Loop
pdfjob.cPrinterStop = False
'Attend que l'impression du document soit terminée
Do Until pdfjob.cCountOfPrintjobs = 0
DoEvents
Loop
tsKill PDFCreator
 

ngogoisidore

XLDnaute Occasionnel
Re : Edition PDF

Bonjour Fab,

Je vois que tu as presque résolu le problème que tu évoquais dans un fil précédent :

https://www.excel-downloads.com/threads/edition-pdf.112123/

J'ai récupéré et installé PDFCreator version 0.9.6 (Download | pdfforge.org) pour essayer de reproduire le bug que tu décris :

Une erreur lorsque l'on tente de créer des pdf via la classe PDFCreator.clsPDFCreator dans VBA, et que le processus PDFCreator.exe tourne déjà.

Remarques :

1) Normalement, avec VBA, si une classe COM est déjà instanciée (ici, Class:="PDFCreator.clsPDFCreator"), on peut y accéder via la commande GetObject(Class:="Nom de La Classe").
Mais dans notre cas, la commande ne marche pas (c'est un problème récurrent, si l'on en croit les posts à ce sujet sur la toile).
Cela veut dire qu'on ne peut pas se servir du processus PDFCreator.exe s'il tourne déjà et, donc, qu'on est obligé de le tuer, puisqu'il rentre en conflit avec notre utilisation de classe. Ca n'est pas très propre, mais je n'ai pas trouvé d'autres solutions ...

2) A ma connaissance, dans toutes les classes COM, il doit y avoir une méthode pour terminer l'instance de la classe.
Dans notre cas (version 0.9.6), il s'agit de la méthode cClose.
Mais là encore, il y a un petit problème, il faut bien respecter la séquence :

Code:
With pdfjob
    .cDefaultPrinter = DefaultPrinter
    .cClearCache
    Application.Wait (Now + TimeValue("0:00:3"))
    .cClose
End With

pour ne pas générer d'erreur ou "geler" Excel.

Si on respecte ce code, il ne devrait donc pas être nécessaire de tuer le processus PDFCreator.exe, puisqu'on le ferme proprement aprés chaque impression par le code VBA.

Néanmoins, par sécurité, j'ai rajouté la fonction KillTask(nomProcess) qui tue le process s'il existe.

Voir code ci dessous :

Code:
Sub PrintTest()
    Call PrintSheetInPDF(Worksheets("Sheet1"))
End Sub '~PrintTest

Sub PrintSheetInPDF(shSheet As Worksheet)
    Dim pdfjob      As Object
    Dim sPDFName    As String
    Dim sPDFPath    As String
    
    '/// Changer le nom du fichier de sortie sur la ligne ci dessous: ///
    sPDFName = ThisWorkbook.Name & "_" & shSheet.Name & ".pdf"
    sPDFPath = ThisWorkbook.Path
    'Check if worksheet is empty and exit if so
    
    shSheet.Select
    
    If IsEmpty(shSheet.UsedRange) Then Exit Sub
    
    ' ##############################
    ' Pas trés propre, mais je n'ai pas réussi à récupérer l'instance de la classe
    ' PDFCreator.clsPDFCreator avec la fonction GetObject
    ' Remarque : si la tache "PDFCreator.exe" n'existe pas, la fonction KillTask("PDFCreator.exe") ne fait rien
    Call KillTask("PDFCreator.exe")
    ' ##############################
 
    Set pdfjob = CreateObject("PDFCreator.clsPDFCreator")

    With pdfjob
        If .cStart("/NoProcessingAtStartup") = False Then
            MsgBox "Can't initialize PDFCreator.", vbCritical + vbOKOnly, "PrtPDFCreator"
            Exit Sub
        End If
        .cOption("UseAutosave") = 1
        .cOption("UseAutosaveDirectory") = 1
        .cOption("AutosaveDirectory") = sPDFPath
        .cOption("AutosaveFilename") = sPDFName
        .cOption("AutosaveFormat") = 0 ' 0 = PDF
        .cClearCache
    End With
    'Imprime le document en PDF
    ActiveSheet.PrintOut copies:=1, ActivePrinter:="PDFCreator"
    'Attend que le document soit entré dans la file d'impression
    Do Until pdfjob.cCountOfPrintjobs = 1
        DoEvents
    Loop
    pdfjob.cPrinterStop = False
    'Attend que l'impression du document soit terminée
    Do Until pdfjob.cCountOfPrintjobs = 0
        DoEvents
    Loop

    With pdfjob
        .cDefaultPrinter = DefaultPrinter
        .cClearCache
        Application.Wait (Now + TimeValue("0:00:3"))
        .cClose
    End With
    
    Set pdfjob = Nothing
End Sub '~PrintSheetInPDF


Sub KillTask(sAppName As String)
    Dim oProcList   As Object
    Dim oWMI        As Object
    Dim oProc       As Object
    
    'Create WMI object instance:
    Set oWMI = GetObject("winmgmts:")
    If IsNull(oWMI) = False Then
        'Create object collection of Win32 processes:
        Set oProcList = oWMI.InstancesOf("win32_process")
        'Iterate through the enumerated collection:
        For Each oProc In oProcList
            If UCase(oProc.Name) = UCase(sAppName) Then
                oProc.Terminate (0)
            End If
        Next oProc
    Else
        'Report Error
        MsgBox "Killing """ & sAppName & """ - Can't create WMI Object.", vbOKOnly + vbCritical, "CloseAPP_B"
    End If
    
    'Clear out the objects:
    Set oProcList = Nothing
    Set oWMI = Nothing
End Sub '~KillTask

@+
 
Dernière édition:

PERRINFAB

XLDnaute Nouveau
Re : Edition PDF

Bonjour,

C'est tout simplement génial!!!:D:D:D:D:D

J'ai cherché désespérément pdt un weekendet sans succès.

J'ai intégré ton code dans ma macro sans aucune adaptation particulière et ça fonctionne (le PC "rame" un peu mais bon)

Merci bcp de ton aide

A+

Fab
 

Discussions similaires

Statistiques des forums

Discussions
312 379
Messages
2 087 767
Membres
103 662
dernier inscrit
rterterert