XL 2010 Macro enregistrement PDF + choix des feuilles

safranien

XLDnaute Occasionnel
Bonjour à tous

je vous sollicite car je ne suis pas très aguerri sur la manip VBA. Ci-joint un fichier exemple. Dans Feuil1 il y a un bouton qui me permet d'enregistrer en PDF les feuilles 1,4,5,6,8,9 et 10. Ces feuilles constituent un rapport de base. J'aimerais offrir la possibilité d'ajouter des feuilles et que lorsque je clique sur le bouton "Impression PDF"; il y ait une check box qui me permette de choisir les feuilles à ajouter. Par défaut, seraient cochées les cases correspondant aux feuilles de base citées précédemment. Voir l'onglet "Donnees" dans lequel j'ai imagé cela.

Deux autres questions :

j'ai essayé de manier le code présent dans mon fichier récupéré sur un forum mais il ne comportait pas ce qu'il fallait faire pour dissocier les feuilles et revenir sur une feuille précise la feuille 1). Ce que j'ai écrit est certainement très moche et doit pouvoir être optimisé

With Sheets("Feuil12")
.Activate
End With
With Sheets("Feuil1")
.Select
End With

Pour finir, j'exécute cette macro actuellement sur un fichier qui est assez lourd et chargé de données et de graphiques. Dans mon fichier, j'ai un menu déroulant qui me permet de passer d'une installation à une autre avec des mises à jour de données et de calculs. Je lance l'impression PDF, je passe au site suivant etc. Pour les premieres impressions, tout se passe bien, j'ai, par exemple, 14 pages qui sortent dans mon PDF. Au bout du 4e ou 5e changement de site, quand je lance l'impression PDF, je n'ai plus que 10 pages qui sortent dans le PDF (je devrais toujours avoir 14 pages). Je suis obligé de fermer excel, de relancer le fichier, l'impression et là j'ai bien mes 14 pages. Je me dis qu'en fermant tout l'excel je dois vider une sorte de mémoire cache. Si c'est cela selon vous, est ce qu'il est possible d'insérer dans le code une fonction permettant de vider la mémoire à chaque lancement d'impression?

J'espère que vous pourrez m'aider.

Bonne soirée
 

Pièces jointes

  • Safranien - Impression PDF macro.xlsm
    47.8 KB · Affichages: 9
Solution
Re

Pour le changer le CodeName :

1593602863180.png


Fenêtre "Propriété" => F4 pour l'afficher...


Et pour ta dernière demande essaies comme ceci :

VB:
For Each WS In ThisWorkbook.Worksheets
  Select Case WS.CodeName
    Case "Feuil1", "Feuil2", "Feuil4", "Feuil6", "Feuil7", "X_Feuil3"
       Me.ListBox1.AddItem WS.Name
        If WS.CodeName = "Feuil4" Or WS.CodeName = "Feuil7" Or WS.CodeName = "X_Feuil3" Then
           Me.ListBox1.Selected(x) = True
        End If
         x = x + 1
  End Select
Next WS

Mais c'est lourd si tu dois changer souvent les feuilles ou si tu en supprimes ... Une méthode "générique" évitait ceci...

Bien à toi, à vous,
@+Thierry

EDIT Re...

_Thierry

XLDnaute Barbatruc
Tu n'as pas quelque chose de plus générique ?

Style
If InStr(WS.Name, "Print") <> 0 Then
(Si l'onglet contient "Print" dans son nom

Ou :
If Left(WS.Name, 1) = "P" Then
Si le nom d'onglet commence par "P"....

Enfin tu vois ...

@+Thierry
 

safranien

XLDnaute Occasionnel
arf non je n'ai rien qui colle à ça. En PJ, la liste de tous les onglets de mon fichier (il y en a aussi qui sont masqués mais qui du coup apparaissent également dans la liste de choix). Dans l'encadré rouge, tous ceux que j'aimerais voir apparaître dans la liste d'impression, et ceux avec la croix étant ceux qui doivent être cochés par défaut. Ca va être compliqué si je comprends bien...?
Onglets PDF.jpg
 

_Thierry

XLDnaute Barbatruc
Re

Ce n'est pas compliqué, mais dans un loop on ne peut faire qu'un seul Select Case.
Soit on abandonne le loop sur toutes les feuilles du classeur, au bénéfice d'un loop sur une Array des Feuilles, mais je n'aime pas trop car tu ne verras jamais les nouvelles feuilles...

Soit on fait un if infernal avec 12 onglets ...

Même pas l'emplacement dans le classeur peut-être maitrisé ? (les onglets ont un numéro d'index à partir du premier à gauche... ?

@+Thierry
 

safranien

XLDnaute Occasionnel
On pourrait se dire que les onglets devant apparaître sont les 12 en partant de la droite? Sinon je mets une x devant le nom de chaque onglets que je ne veux pas voir apparaître et on part sur le code de type
If Left(WS.Name, 1) = "P" Then (mais faut que tu me dises où l'insérer et la suite ... Oui je n'y pige rien e VBA malheureusement :()

Mais je me dis que puisqu'on peut définir une liste d'onglets qui doivent être cochés par défut, on doit pouvoir définir au préalable une liste d'onglets devant apparaître dans la liste ?
Il n'est pas prévu que j'ajoute des onglets devant être convertis en PDF mais si ça venait à être le cas, il me suffirait d'ajouter le nom de cet onglet dans le code pour le voir apparaître dans la liste.
Qu'en penses-tu?
 
Dernière édition:

fanch55

XLDnaute Accro
Bonjour à tous,
Sinon il existe cette macro pour imprimer les onglets que l'on désire dans un fichier quelconque:
VB:
Option Explicit
Private Sub CommandButton2_Click()
Dim PrintDlg        As DialogSheet
Dim CurrentSheet    As Worksheet
Dim Sh              As Worksheet
Dim Cb              As CheckBox
Dim Sel_Sheets      As String
Dim FileName        As Variant
Dim TopPos          As Integer

Application.ScreenUpdating = False

    ' Check for protected workbook
    If ActiveWorkbook.ProtectStructure Then
        MsgBox "Le classeur est protégé.", vbCritical
        Exit Sub
    End If

    ' Add a temporary dialog sheet
    Set CurrentSheet = ActiveSheet
    Set PrintDlg = ActiveWorkbook.DialogSheets.Add

    ' Add the checkboxes
    TopPos = PrintDlg.Buttons(1).Top
    For Each Sh In ActiveWorkbook.Worksheets
        ' Skip hidden sheets
        If Sh.Visible Then
           PrintDlg.CheckBoxes.Add(78, TopPos, 100, 16.5).Text = Sh.Name
           TopPos = TopPos + 13
        End If
    Next
    
    ' Move the OK and Cancel buttons
    PrintDlg.Buttons.Left = PrintDlg.CheckBoxes(1).Left + PrintDlg.CheckBoxes(1).Width
    
    ' Set dialog height, width, and caption
    With PrintDlg.DialogFrame
        .Height = Application.Max(68, PrintDlg.DialogFrame.Top + TopPos - 34)
        .Width = PrintDlg.Buttons(1).Left ' <-- bizarre mais fonctionne
        .Caption = "Cochez les feuilles à publier"
    End With
    
    ' Set focus on Cancel
    PrintDlg.Buttons(1).BringToFront
    
    ' Display the dialog box
    CurrentSheet.Activate
    Application.ScreenUpdating = True
        If PrintDlg.Show Then
            For Each Cb In PrintDlg.CheckBoxes
                If Cb.Value = xlOn Then Sel_Sheets = Trim(Sel_Sheets & " " & Cb.Caption)
            Next Cb
            If Sel_Sheets <> vbNullString Then
               ' Display the dialog box to obtain filename
                FileName = Application.GetSaveAsFilename( _
                    FileFilter:="Publication (*.pdf),*.pdf", _
                    InitialFileName:=ThisWorkbook.Path)
                If Not FileName = False Then
                    ' Select sheets to export
                    Sheets(Split(Sel_Sheets)).Select
                    ' Publication
                    ActiveSheet.ExportAsFixedFormat _
                        Type:=xlTypePDF, OpenAfterPublish:=True, _
                        FileName:=FileName
                End If
            End If
        End If

    ' Delete temporary dialog sheet (without a warning)
    Application.DisplayAlerts = False
    PrintDlg.Delete

' Reactivate original sheet
CurrentSheet.Activate
Set CurrentSheet = Nothing
Set PrintDlg = Nothing

End Sub
 

_Thierry

XLDnaute Barbatruc
Re Bonjour @safranien , @fanch55 , le Forum

On pourrait se dire que les onglets devant apparaître sont les 12 en partant de la droite?
OK UserForm1 dans la v02 (sur les 5 derniers onglets de droite, tu verras, facile à adapter dans le code

Sinon je mets une x devant le nom de chaque onglets que je ne veux pas voir apparaître
OK UserForm2 dans la v02, Feuilles exclues commençant avec "X" majuscule

Dans les deux cas, il est clair que cette condition primaire prévaut sur la selection d'onglet plus bas avec le Select Case... (on ne peut pas sélectionner un item non présent dans la list !)


Bonne découverte

@+Thierry
 

Pièces jointes

  • XLD_Safranien-ImpressionPDF_USF_MultiSheets_v02.xlsm
    64.5 KB · Affichages: 6

safranien

XLDnaute Occasionnel
Super !!!! Ca fonctionne merci beaucoup beaucoup.

Du coup, si j'utilise ce code pour un autre de mes fichiers ayant une architecture différente, et pour lequel ce ne serait pas forcément les X derniers onglets qu'il faudrait prendre en compte dans la liste mais des onglets éparpillés, est ce qu'on ne peut pas écrire le nom des onglets devant être repris dans la liste au même titre que l'on écrit la liste des onglets que l'on veut voir cochés par défaut?

Et quand on regarde l'écran Visual Bsic, je constate que, quelque soit le nom que l'on donne à un onglet, il est toujorus associé au même nom de FeuilX. Dans le code, si je remplace les noms des onglets par les noms des Feuilles correspondantes, est ce que ça fonctionne? Ce qui permettrait finalement de changer les noms des onglets sans avoir à revenir changer les noms de ces derniers dans les codes.

Normalement, je n'ai plus de questions après celles-ci ...
 

patricktoulon

XLDnaute Barbatruc
bonjour a tous
encore une fois,un userform en mode responsif façon patricktoulon est tout indiqué

kado

CLICK sur mon bouton en feuille 1
dans la liste les "par defaut" sont sélectionnés automatiquement
il te reste a en cocher d'autres ou a décocher comme tu veux
j'ai bloqué le saveAs pour l'instant
supprimer l'encadré comme précisé dans le code de ma sub dans le module pour rendre le save As effectif
pour l'instant elle te renvoie le message avec les noms des feuilles selectionnées
et la sélection est effective
;)
 

Pièces jointes

  • Safranien - Impression PDF V patricktoulon .xlsm
    61.6 KB · Affichages: 8

_Thierry

XLDnaute Barbatruc
Re @safranien ,

Pas de souci, j'ai un peu de temps, c'est un cours sur les manips de Worksheets ce Fil !

Ce que tu mentionnes :

1593601270260.png


C'est le CodeName des Worksheets... Et Oui tu peux "jouer" avec ça aussi !

VB:
For Each WS In ThisWorkbook.Worksheets

If Left(WS.CodeName, 1) = "X" Then
Me.ListBox1.AddItem WS.Name
Select Case WS.Name
Case "Feuil1", "Feuil3", "Feuil4", "Feuil6", "Feuil7"
Me.ListBox1.Selected(x) = True

Case Else
'Do Nothing
End Select
x = x + 1
End If
Next


Bonne continuation
@+Thierry

EDIT Salut Patrick !
 
Dernière édition:

_Thierry

XLDnaute Barbatruc
Héhéhé sacré Patrick !

Oui très bien l'utilisation d'un userform en mode responsif !!!
J'ai peur par contre que Safranien décroche sur ce coup là, même moi j'ai du mal à suivre ! ;)

Et puis donc les demandes ont aussi évoluée depuis le premier post, on en est à un pré-filtrage de ce qu'on met dans la ListBox avant d'y faire ensuite des pré-sélection de feuilles...

Toujours superbe démo !
@+Thierry
 

safranien

XLDnaute Occasionnel
Re @safranien ,

Pas de souci, j'ai un peu de temps, c'est un cours sur les manips de Worksheets ce Fil !

Ce que tu mentionnes :

Regarde la pièce jointe 1071864

C'est le CodeName des Worksheets... Et Oui tu peux "jouer" avec ça aussi !

VB:
For Each WS In ThisWorkbook.Worksheets

If Left(WS.CodeName, 1) = "X" Then
Me.ListBox1.AddItem WS.Name
Select Case WS.Name
Case "Feuil1", "Feuil3", "Feuil4", "Feuil6", "Feuil7"
Me.ListBox1.Selected(x) = True

Case Else
'Do Nothing
End Select
x = x + 1
End If
Next


Bonne continuation
@+Thierry

EDIT Salut Patrick !

je suis un boulet, je ne sais même comment mettre un X dans le codeName des Worksheets :(
Désolé pour ma nullitude.

Du coup, est ce qu'à la place de
For Each WS In ThisWorkbook.Worksheets
If WS.Index >= ThisWorkbook.Worksheets.Count - 11 Then
Me.ListBox1.AddItem WS.Name

on pourrait pas tourner l'écriture pour dire
Onglets à faire apparaître dans la liste = "Feuil1", "Feuil2" etc

Ca m'irait très bien et si au final je devais modifier un nom d'onglet je viendrais modifier le nom dans le code.
 

patricktoulon

XLDnaute Barbatruc
re
on pourrait pas tourner l'écriture pour dire
Onglets à faire apparaître dans la liste = "Feuil1", "Feuil2" etc
peut etre le demandeur va se decider a regarder mon fichier
;)

les codes names ne s'utilisent pas en string

avec les codename l'array serait
exemple
a=array(feuil1.name,feuil4.name,feuil8.name)

mais se serait une ENORME BETISE !!!!d'utiliser cette méthode


pourquoi?
et bien parce que demain tu supprime une feuille ou plusieurs
et après demain tu en rajoute x autres
les codename absent par la suppression de l'avant veille vont être remplacé par les nouveaux ajoutés

conclusion
il te faudra quand même modifier dans le code pour
excepter ou confirmer ces codename dans l'array par d"faut alors qu'utiliser les nom de sheets étant uniques et étant impossible de donner le même nom à deux feuilles tu n'aura jamais de problème
A bon entendeur ;)

a
 

safranien

XLDnaute Occasionnel
Bonjour Patrick

merci beaucoup pour ton aide, effectivement je n'avais pas encore regardé ta propo. Tu as du voir que je n'y connaissais pas grand chose au VBA et à son langage et je commence à peine à comprendre les lignes de code proposées par Thierry et je ne voulais pas m'embrouiller avec d'autres lectures que je vais mettre des heures à comprendre (ou pas du tout d'ailleurs). Array, string etc c'est confus pour moi mais j'essaie de comprendre. Du coup, je voulais essayer d'aller au bout avec Thierry avant de tester d'autres solutions.
J'ai regardé ton fichier et je n'arrive pas à comprendre comment tu choisis les onglets à faire apparaître dans la liste ni comment tu détermines ceux qui doivent être cochés par défaut. Tu vois un peu mon niveau... Et quand je clique sur la coche verte, je ne vois pas de PDF qui se génère.

Quand Thierry m'aura aidé sur cette dernière écriture, je me pencherai sur ta solution.

Merci encore.
 

safranien

XLDnaute Occasionnel
Bonjour à tous,
Sinon il existe cette macro pour imprimer les onglets que l'on désire dans un fichier quelconque:
VB:
Option Explicit
Private Sub CommandButton2_Click()
Dim PrintDlg        As DialogSheet
Dim CurrentSheet    As Worksheet
Dim Sh              As Worksheet
Dim Cb              As CheckBox
Dim Sel_Sheets      As String
Dim FileName        As Variant
Dim TopPos          As Integer

Application.ScreenUpdating = False

    ' Check for protected workbook
    If ActiveWorkbook.ProtectStructure Then
        MsgBox "Le classeur est protégé.", vbCritical
        Exit Sub
    End If

    ' Add a temporary dialog sheet
    Set CurrentSheet = ActiveSheet
    Set PrintDlg = ActiveWorkbook.DialogSheets.Add

    ' Add the checkboxes
    TopPos = PrintDlg.Buttons(1).Top
    For Each Sh In ActiveWorkbook.Worksheets
        ' Skip hidden sheets
        If Sh.Visible Then
           PrintDlg.CheckBoxes.Add(78, TopPos, 100, 16.5).Text = Sh.Name
           TopPos = TopPos + 13
        End If
    Next
   
    ' Move the OK and Cancel buttons
    PrintDlg.Buttons.Left = PrintDlg.CheckBoxes(1).Left + PrintDlg.CheckBoxes(1).Width
   
    ' Set dialog height, width, and caption
    With PrintDlg.DialogFrame
        .Height = Application.Max(68, PrintDlg.DialogFrame.Top + TopPos - 34)
        .Width = PrintDlg.Buttons(1).Left ' <-- bizarre mais fonctionne
        .Caption = "Cochez les feuilles à publier"
    End With
   
    ' Set focus on Cancel
    PrintDlg.Buttons(1).BringToFront
   
    ' Display the dialog box
    CurrentSheet.Activate
    Application.ScreenUpdating = True
        If PrintDlg.Show Then
            For Each Cb In PrintDlg.CheckBoxes
                If Cb.Value = xlOn Then Sel_Sheets = Trim(Sel_Sheets & " " & Cb.Caption)
            Next Cb
            If Sel_Sheets <> vbNullString Then
               ' Display the dialog box to obtain filename
                FileName = Application.GetSaveAsFilename( _
                    FileFilter:="Publication (*.pdf),*.pdf", _
                    InitialFileName:=ThisWorkbook.Path)
                If Not FileName = False Then
                    ' Select sheets to export
                    Sheets(Split(Sel_Sheets)).Select
                    ' Publication
                    ActiveSheet.ExportAsFixedFormat _
                        Type:=xlTypePDF, OpenAfterPublish:=True, _
                        FileName:=FileName
                End If
            End If
        End If

    ' Delete temporary dialog sheet (without a warning)
    Application.DisplayAlerts = False
    PrintDlg.Delete

' Reactivate original sheet
CurrentSheet.Activate
Set CurrentSheet = Nothing
Set PrintDlg = Nothing

End Sub

Bonjour fanch55

merci pour ta proposition. Je regarde ça quand j'ai fini avec Thierry et reviens vers toi si besoin.
 

Discussions similaires

Statistiques des forums

Discussions
285 052
Messages
1 865 437
Membres
156 262
dernier inscrit
rachid2021
Haut Bas