IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VBA Word Discussion :

VBA - Word 2010 - Copier un tableau d'un document Word dans l'en-tête d'un autre document Word


Sujet :

VBA Word

  1. #1
    Nouveau membre du Club
    Femme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Février 2016
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Février 2016
    Messages : 66
    Points : 31
    Points
    31
    Par défaut VBA - Word 2010 - Copier un tableau d'un document Word dans l'en-tête d'un autre document Word
    Bonjour,

    Je dois transformer le format d'un très grand nombre de documents Word (2010).
    Parmi les actions, il me faut modifier leur en-tête (et renseigner ensuite le contenu à partir d'un fichier Excel: se sera le challenge suivant !)

    L'en-tête du modèle vierge se trouve dans un fichier source enregistré dans le même répertoire que le fichier destinataire.
    Il s'agit d'un tableau.

    J'ai réussi à automatiser la suppression de l'en-tête d'origine du document destinataire dans une première macro.
    Je n'arrive pas à trouver le code pour importer le tableau du fichier source, malgré quelques lectures sur des sujets similaires que j'avoue avoir du mal à décrypter (débutante que je suis).

    Voici mon code
    Je n'ai pas pu le tester réellement, il s'arrête à l'étape 2 :
    - surligné : ".Tables" de la ligne "Set TableEnTete = Source.Tables(1)"
    - message : Membre de méthodes ou de données introuvables"

    Pouvez-vous m'aider ?
    Remerciements
    Marie-Noëlle

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
     
    Sub CopyEnTete()
    '
    ' Etape 1 : Déclarer les chemins
      Dim Chemin As String, FichierDestinataire As String
     
      Chemin = ActiveDocument.Path & "\"
      FichierSource = "Archive Modeles de Blocs"
      FichierDestinataire = ThisDocument.Name
     
      ' Etape 2 : Déclarer les feuilles de travail et l'objet Table à copier
      Dim Source As Documents, Destinataire As Documents
      Dim TableEnTete As Table
     
      Set Destinataire = ThisDocument
      Set Source = Documents("Archive Modeles de Blocs")
      Set TableEnTete = Source.Tables(1)
     
     'Etape 3 Copier Coller la table
      TableEnTete.Select
      Selection.Copy
            With Destinataire
                ActiveWindow.ActivePane.View.SeekView = wdSeekCurrentPageHeader
                Documents.Add
                Selection.Paste
            End With
     
    End Sub

  2. #2
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Marino69 Voir le message
    Bonjour,

    Ne pas confondre Document et Documents dans la déclaration des variables. Ton code ne peut pas fonctionner car Source et Destinataire correspondent à l'ensemble des documents ouverts.
    Je n'ai pas compris pourquoi tu créais un nouveau document à la fin de ton code. Si ton nouveau document est vraiment celui où il faut coller l'entête, alors il faudra modifier le code ci-dessous.

    • Le code ci-dessous copie l'entête du fichier présent dans un document source et le colle dans le document actif DocDestinataire.
    • Le document source doit être ouvert. Modifier l'extension si elle n'est pas .docm.
    • La procédure RemiseEnFormeDocument est là simplement pour remettre les documents dans leur présentation d'origine. Le code peut sans doute être simplifié.



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
     
     Sub CopyEnTete()
     
      Dim DocSource As Document, DocDestinataire As Document
      Dim Continuer As Boolean
     
          On Error GoTo Fin
     
          Continuer = False
     
          Set DocDestinataire = ThisDocument
     
          For Each DocEnCours In Documents
              If DocEnCours.Name = "Archive Modeles de Blocs.docm" Then Continuer = True
          Next DocEnCours
     
          If Continuer = True Then
             Set DocSource = Documents("Archive Modeles de Blocs.docm")
          Else
             GoTo Fin
          End If
     
          If DocSource.Sections(1).Headers.Count > 0 Then
     
             DocSource.Sections(1).Headers(1).Range.Tables(1).Select
             Selection.Copy
             DocDestinataire.Sections(1).Headers(1).Range.Select
             Selection.Paste
     
             RemiseEnFormeDocument DocDestinataire
             RemiseEnFormeDocument DocSource
     
          End If
     
          GoTo Fin
     
    Fin:
     
         Set DocDestinataire = Nothing
         Set DocSource = Nothing
     
    End Sub
     
     
    Sub RemiseEnFormeDocument(ByVal DocEnCours As Document)
     
        With DocEnCours.ActiveWindow
                If .View.SplitSpecial <> wdPaneNone Then .Panes(2).Close
                If .ActivePane.View.Type = wdNormalView Or .ActivePane.View.Type = wdOutlineView Then .ActivePane.View.Type = wdPrintView
     
                .ActivePane.View.SeekView = wdSeekCurrentPageHeader
                If .View.SplitSpecial = wdPaneNone Then
                   .ActivePane.View.Type = wdPrintView
                Else
                   .View.Type = wdPrintView
                End If
     
                .ActivePane.View.SeekView = wdSeekMainDocument
                If .View.SplitSpecial = wdPaneNone Then
                    .ActivePane.View.Type = wdPrintView
                Else
                    .View.Type = wdPrintView
                End If
        End With
     
    End Sub

  3. #3
    Nouveau membre du Club
    Femme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Février 2016
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Février 2016
    Messages : 66
    Points : 31
    Points
    31
    Par défaut
    Bonjour Eric,

    Un grand merci pour encore voler à mon secours.

    C'est bien le document destinataire actif dans lequel j'ai besoin d'importer l'en-tête du document source (et non un nouveau document : mon "'Documents.Adds" de la fin du code n'est qu'un "copier" malheureux d'une de mes recherches.
    Je tâtonne, découvre et ... "comprends" par déduction dans le meilleur des cas. Je te suis donc infiniment reconnaissante de ton aide.

    Lorsque je lance le code proposé depuis le fichier destinataire (le fichier source étant ouvert), la macro s'arrête sur le fichier source en mode "brouillon" avec une fenêtre "en-tête" ouverte sous la fenêtre du fichier et un onglet vert "Outil en-tête et pieds de page" apparu dans le bandeau.
    Lorsque que je tente de saisir du texte dans la fenêtre "en-tête", ou si je clique sur l'onglet "outil en-tête et pieds de page" , je "sors de Word" et j'ai un message "? Des modifications ont été automatiquement enregistrées dans le modèle Normal.dot. Voulez-vous charger la version modifiée ?".

    Si je rétabli l'affichage en page, le fichier source n'est pas modifié (l'en-tête s'est peut copiée sur elle-même ?)
    Quant au fichier destinataire : lui non plus n'est pas modifié.


    J'ai l'impression que , ThisDocument devient le document source au moment de la sélection de son en-tête au lieu de rester le document destinataire comme écrit en début de code (DocDestinataire = ThisDocument).
    Qu'en penses-tu , je cale ...

    Marie-Noëlle

  4. #4
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Marino69 Voir le message
    J'ai l'impression que tu as créé un module et placé tes macros dans ton Normal.dot. Il faut le créer dans ton document destinataire.

    Un exemple dans ce zip, attention le nom du fichier source est le même que le tien.

  5. #5
    Nouveau membre du Club
    Femme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Février 2016
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Février 2016
    Messages : 66
    Points : 31
    Points
    31
    Par défaut
    Bonsoir,

    En effet, j'ai vu à l'aide du Menu déroulant de la fenêtre Macro, que toutes les macros se sont enregistrées dans "Normal.dot (modèle global)". C'est sans doute parce que je commence leur création avec l'enregistreur de macros qui d'après mes lectures enregistre sa production par défaut dans ce fichier.
    J'ai donc déniché "Normal.dotm" dans "C:\Users\monLogin\AppData\Roaming\Microsoft" et supprimé le code de CopyEnTete.
    En revanche je n'ai pas trouver comment copier le code dans le fichier lui-même (si je le colle à la suite des autres macros, il réapparait dans le "Normal.dotm")

    Pourrais-tu m'indiquer comment faire ?

    J'ai aussi lu qu'enregistrer les macros dans "Normal.dot " est une méthode pour rendre accessibles les macros depuis tous les fichiers, ce qui est bien pratique car j'aurai 600 fichiers à traiter.
    Concernant CopyEnTete qu'il faudrait retirer de "Normal.dot", je réalise qu'il vaudrait mieux pouvoir la lancer depuis le fichier source (exporter l'en-tête vers le fichier destinataire) plutôt que l'inverse.
    Demain j'essais d'adapter le code sur la base des fichiers que tu as joints qui fonctionnent très bien.

    Cordialement,
    Marie-Noëlle

  6. #6
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Marino69 Voir le message
    Pour coller les macros dans ton fichier Word, tu ouvres l'éditeur VBA (Alt-F11):

    Pièce jointe 388854


    Sur le fichier .docm, clic droit, développer Insertion et insérer un module :
    Pièce jointe 388855

    Puis coller les macros dans le module.

    Sinon sur le même principe, tu pouvais supprimer le module dans Normal.dot (il devait s'appeler sans doute New modul) depuis l'éditeur comme tu peux le voir.

    En ce qui concerne le stockage de tes macros dans Normal.dot, ce n'est pas forcément une bonne idée. Il te faut placer dans celui-ci que celles qui te servent régulièrement et les sauvegarder car il arrive parfois d'avoir à supprimer le Normal.dot. Nb : En cas de suppression, il se regénère à l'ouverture de Word.

    Pour tout ce qui relève de ton traitement actuel, tu as intérêt à créer un fichier de traitement indépendant des fichiers source et destinataires. Un bouton ActiveX comme dans mon fichier te permettra de lancer la procédure. Il ne te restera plus qu'à développer un Userform pour pointer les fichiers que tu veux mettre à jour.

  7. #7
    Inactif  

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2012
    Messages
    4 904
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2012
    Messages : 4 904
    Points : 10 168
    Points
    10 168
    Billets dans le blog
    36
    Par défaut
    Bonjour,

    Citation Envoyé par Eric KERGRESSE Voir le message
    Pour coller les macros dans ton fichier Word, tu ouvres l'éditeur VBA (Alt-F11):


    En ce qui concerne le stockage de tes macros dans Normal.dot, ce n'est pas forcément une bonne idée.
    Je suis plutôt d'accord. Personnellement, je préfère quelques modèles dédiés avec les macros qui conviennent.


    car il arrive parfois d'avoir à supprimer le Normal.dot. Nb : En cas de suppression, il se regénère à l'ouverture de Word.
    Il n'est pas nécessaire de l'effacer. Le seul fait de le renommer en, par exemple, anormal.dot, va provoquer la génération d'un nouveau Normal.dot.

    Et Word, a une fonctionnalité intégrée, pour copier ou déplacer des macros et des styles entre des modèles et des documents

    Nom : CroquisWord1.png
Affichages : 1520
Taille : 141,2 Ko

    Nom : CroquisWord2.png
Affichages : 811
Taille : 34,9 Ko
    À ma connaissance, le seul personnage qui a été diagnostiqué comme étant allergique au mot effort. c'est Gaston Lagaffe.

    Ô Saint Excel, Grand Dieu de l'Inutile.

    Excel n'a jamais été, n'est pas et ne sera jamais un SGBD, c'est pour cela que Excel s'appelle Excel et ne s'appelle pas Access junior.

  8. #8
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par clementmarcotte Voir le message
    Salut Clément,

    Bien vu.

  9. #9
    Nouveau membre du Club
    Femme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Février 2016
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Février 2016
    Messages : 66
    Points : 31
    Points
    31
    Par défaut
    Bonjour,

    Merci Clément pour ta contribution à la discussion.

    Eric, sur tes conseilles :
    - Normal.dotm est maintenant vide
    - J'ai tout importé dans un nouveau fichier dédié aux macros et modifié le code pour que la macro utilise "Fichier a traiter" au lieu de "ThisDocument" (je renommerai à la main les fichiers à transformer au fur et à mesure avec "fichier à traiter")
    - Sur la lancée j'ai complété le code pour ajouter le "copier/coller" du bas de page du document Source vers le document Destinataire.
    Tout fonctionne bien : ça fait plaisir !

    - Merci pour la suggestion d'un formulaire que j'essaierai plus tard, en fonction du temps qui me prendra la suite de l'automatisation des transformations.

    Pour terminer cet étape, j'ai encore besoin de ton aide pour reproduire ton bouton macro :
    J'ai créé un Bouton Active X sur la page Word (à côté du tiens) , j'ai copié/collé le code du bouton de ton fichier en remplaçant seulement le nom de la macro.
    - je n'ai pas trouvé comment renommer le bouton
    - Mais surtout :
    Curieusement : cette modification, faite dans mon bouton, se produit aussi dans le tiens et la 2eme private sub s'ajoute toute seule aux 2 boutons.
    mais bien que les 2 boutons aient du coup le même code, le tiens fonctionne et le miens non.

    Je dois encore organiser les macros importées "au km" dans un module du fichier.
    Pourrais-tu m'indiquer un lien pour comprendre la logique de l'architecture des macros ? (quand mets on les macros dans un même module ou des modules séparé ?)


    Cordialement,
    Marie-Noëlle

    Code pour le bouton
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    Option Explicit
     
    Private Sub BoutonLancer_Click()
            Application.ScreenUpdating = False
            CopyEnTetePiedPage
            Application.ScreenUpdating = True
    End Sub
     
    Private Sub CommandButton1_Click()
     
    End Sub

    Code de la Macro qui copie/colle le tableau d'en-tête et de pied de page d'un document Word à un autre.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
     
    Option Explicit
     
     
    Sub CopyEnTetePiedPage()
     
      Dim DocSource As Document, DocDestinataire As Document, DocEnCours As Document
      Dim Continuer As Boolean
     
          On Error GoTo Fin
     
          Continuer = False
     
     
          For Each DocEnCours In Documents
              If DocEnCours.Name = "Archive Modeles de Blocs FH.docm" Then Continuer = True
          Next DocEnCours
     
          For Each DocEnCours In Documents
              If DocEnCours.Name = "Fichier a traiter.docm" Then Continuer = True
          Next DocEnCours
     
          If Continuer = True Then
             Set DocSource = Documents("Archive Modeles de Blocs FH.docm")
             Set DocDestinataire = Documents("Fichier a traiter.docm")
          Else
             GoTo Fin
          End If
     
          If DocSource.Sections(1).Headers.Count > 0 Then
     
             DocSource.Sections(1).Headers(1).Range.Tables(1).Select
             Selection.Copy
             DocDestinataire.Sections(1).Headers(1).Range.Select
             Selection.Paste
     
             RemiseEnFormeDocument DocDestinataire
             RemiseEnFormeDocument DocSource
     
          End If
     
     
          If DocSource.Sections(1).Footers.Count > 0 Then
     
             DocSource.Sections(1).Footers(1).Range.Tables(1).Select
             Selection.Copy
             DocDestinataire.Sections(1).Footers(1).Range.Select
             Selection.Paste
     
             RemiseEnFormeDocument DocDestinataire
             RemiseEnFormeDocument DocSource
     
          End If
          GoTo Fin
     
    Fin:
     
         Set DocDestinataire = Nothing
         Set DocSource = Nothing
     
    End Sub
     
     
    Sub RemiseEnFormeDocument(ByVal DocEnCours As Document)
     
        With DocEnCours.ActiveWindow
                If .View.SplitSpecial <> wdPaneNone Then .Panes(2).Close
                If .ActivePane.View.Type = wdNormalView Or .ActivePane.View.Type = wdOutlineView Then .ActivePane.View.Type = wdPrintView
     
                .ActivePane.View.SeekView = wdSeekCurrentPageHeader
                If .View.SplitSpecial = wdPaneNone Then
                   .ActivePane.View.Type = wdPrintView
                Else
                   .View.Type = wdPrintView
                End If
     
                '.ActivePane.View.SeekView = wdSeekMainDocument
                'If .View.SplitSpecial = wdPaneNone Then
                '    .ActivePane.View.Type = wdPrintView
                'Else
                '    .View.Type = wdPrintView
                'End If
     
                .ActivePane.View.SeekView = wdSeekCurrentPageFooter
                If .View.SplitSpecial = wdPaneNone Then
                   .ActivePane.View.Type = wdPrintView
                Else
                   .View.Type = wdPrintView
                End If
        End With
     
     
    End Sub

  10. #10
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Marino69 Voir le message
    Pour modifier ton contrôle ActiveX

    Pièce jointe 389000

    Pour l'étape 3 : Cette étape peut consister préalablement à dupliquer le bouton.
    Pour l'étape 4 : Jamais de lettre accentuée dans le nom.

    Astuce : Si tu essaies de créer ton contrôle ActiveX, tu te seras sans doute aperçue que tu ne pouvais pas le positionner là où tu voulais. Si tu regardes ce que j'ai fait, j'ai placé mon contrôle dans un Shape au fond transparent et sans bordure. Cela permet de placer ton contrôle n'importe où sur le document.



    Je dois encore organiser les macros importées "au km" dans un module du fichier.
    Pourrais-tu m'indiquer un lien pour comprendre la logique de l'architecture des macros ? (quand mets on les macros dans un même module ou des modules séparé ?)
    Je ne comprends pas ce que tu veux faire. La macro que tu as créée dans ton fichier support va s'appliquer à tous les fichiers à traiter. Il te faut maintenant créer un code pour appeler automatiquement tes fichiers à traiter.

    Où se situent-ils ? Dans un même répertoire ? Une sélection par le nom est-elle possible ?

  11. #11
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Marino69 Voir le message
    Dans la continuité de mon mail précédent, regarde ce billet de mon blog : word-vba-concatener-fichiers-dat-sauvegarde-rtf-partir-document-word-docm.

    Le fichier .zip contient un Userform avec un "Liste à Liste" que tu peux utiliser pour récupérer les fichiers à modifier moyennant quelques modifications.

  12. #12
    Nouveau membre du Club
    Femme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Février 2016
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Février 2016
    Messages : 66
    Points : 31
    Points
    31
    Par défaut
    Bonsoir Eric,

    - Le bouton de lancement de la macro fonctionne maintenant.
    Merci pour tes explications très claires et pédagogiques !

    - J'ai tenté de faire l'automatisation pour appeler les fichiers à traiter en m'inspirant du tutoriel vers lequel tu m'a orientée (Débutez en VBA Word) et d'un autre du même titre : utilisation de "FileDialog" de 2 manières, suivie de "Debug.Print" sur la base d'un des deux sites (cf. code 1 et code 2)
    Les deux codes font bien apparaitre une fenêtre permettant la sélection d'un fichier à traiter.
    En revanche je n'ai pas réussi à mettre en œuvre "Open" pour faire ouvrir le fichier sélectionné.
    Je crains d'avoir encore besoin d'un coup de main!

    - Concernant ma question sur l'architecture des macros, voici quelques précisions de contexte :
    Je dispose maintenant de différentes macros pour transformer les documents : remise en page correcte des tableaux, fractionnement d'une colonne d'un des tableau en 3 (avec ton aide), ajout de texte en en-tête de certaines colonnes le remplacement de l'en-tête et du pied de page et je dois en faire d'autres pour importer du texte du fichier source à la fin du fichier destinataire et importer des valeurs de cellules Excel dans certains champs du fichier destinataire.
    Je voudrais connaitre les bonnes pratiques d'organisation de ces macros (une macro par module, toutes les macros dans un seul module ?)
    Est-ce que cette architecture a une importance pour le fonctionnement ?
    Pour l'instant j'ai tout copier dans un seul module du fichier de lancement des macros (pour vider le Normal.dotm)


    Encore un grand merci pour ton support
    Cordialement
    Marie-Noëlle


    Code 1
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    Option Explicit
     
    Sub Choisir_Fichier_a_Traiter()
     
    Dim dlg As FileDialog
    Dim strFileName As String
    Dim strInitialFolder As String
     
    Set dlg = Application.FileDialog(msoFileDialogFilePicker)
    With dlg
        .InitialFileName = strInitialFolder
        .AllowMultiSelect = False
        .Title = "Choisir_le_Fichier"
        .Show
    End With
     
    strFileName = dlg.SelectedItem(1)
     
    Set dlg = Nothing
    End Sub
    Sub Ouvrir_Fichier_a_Traiter()
     
    Debug.Print strFileName("C:\Users\MonLogin\OneDrive - MonEntreprise\MACRO VBA Word\", "Choisir_le_Fichier")
     
    End Sub


    Code 2
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    Function strFileName(strInitialFolder As String, strTitre As String) As String
    Dim dlg As FileDialog
     
    Set dlg = Application.FileDialog(msoFileDialogFilePicker)
     
        With dlg
            .InitialFileName = strInitialFolder
            .Title = strTitre
            .Show
        End With
     
    strFileName = dlg.SelectedItems(1)
     
    Set dlg = Nothing
    End Function
     
    Sub Ouvrir_Fichier_a_Modifier()
     
    Debug.Print strFileName("C:\Users\MonLogin\OneDrive - MonEntreprise\MACRO VBA Word\", "Choisir_le_Fichier_à_traiter")
     
    End Sub

  13. #13
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Marino69 Voir le message
    - Concernant ma question sur l'architecture des macros, voici quelques précisions de contexte :
    Je dispose maintenant de différentes macros pour transformer les documents : remise en page correcte des tableaux, fractionnement d'une colonne d'un des tableau en 3 (avec ton aide), ajout de texte en en-tête de certaines colonnes le remplacement de l'en-tête et du pied de page et je dois en faire d'autres pour importer du texte du fichier source à la fin du fichier destinataire et importer des valeurs de cellules Excel dans certains champs du fichier destinataire.
    Je voudrais connaitre les bonnes pratiques d'organisation de ces macros (une macro par module, toutes les macros dans un seul module ?)
    Est-ce que cette architecture a une importance pour le fonctionnement ?
    Pour l'instant j'ai tout copier dans un seul module du fichier de lancement des macros (pour vider le Normal.dotm)
    Imagine un instant que c'est toi qui aura à assurer la maintenance de ton outil (disons pendant les 30 prochaines années ). Si tu as déjà fait l'expérience de revenir sur un de tes outils ne serait-ce que 3 mois après l'avoir livré à ton client, tu seras très étonnée de ton jugement :
    • Souvent ce sera : "Mais qui c'est le c.. qui m'a programmé çà ?". Et tu vas vite galérer, perdre beaucoup de temps et t'énerver si ton code n'est pas bien structuré.
    • Parfois tu ne te rappelleras même plus l'utilité de certaines parties de ton outil ().


    Pour ma part (cela n'engage que moi), je déclare :

    - Mes variables publiques dans un seul module, souvent le premier (Ex : Module1_DeclarationsVariables). Les variables ont un nom très explicite. Si le nom est un assemblage de mots, la première lettre de chaque mot est une majuscule pour bénéficier de l'intellisense (en tapant une variable en minuscule, tu vois tout de suite si l'orthographe est bonne si tu vois les minuscules se transformer en majuscules). Les déclarations sont ordonnées et regroupées par types de variables (string, long, etc) pour ne pas avoir à chercher longtemps.
    - Les fonctions dans un module spécifique (Ex : Module2_Fonctions).
    - Les procédures communes à plusieurs processus dans un troisième module.
    - Chaque processus dans un module spécifique : Module10_TraitementX, Module20_TraitementY . Si le module ne suffit pas, je crée des sous modules Module11_TraitementX1, ex... L'idée est d'avoir un seul module pour toute une chaîne de traitements (comme ici dans ton cas), de façon à limiter ton intervention sur cet unique module le cas échéant. Cela vaut le coup lorsque tu as plusieurs dizaines de modules. Des fois, des procédures réalisant le même traitement sont répétées dans plusieurs modules pour éviter d'aller à droite à gauche. L'avantage également est de pouvoir faire un copier coller du module dans de nouveaux outils.

    Pour chaque module, la procédure principale est toujours en tête. Les noms des procédures sont toujours explicites (et donc souvent à rallonge) et ne contiennent aucun caractère accentué pour garantir la portabilité. Je fais appel à des sous routines dans le code principal pour alléger et clarifier le code en mettant des commentaires pour expliquer ce que fait la procédure, si le nom de la procédure appelée ne se suffit pas à lui-même pour être compréhensible. Pour cela, les procédures sont paramétriques : tu passes les valeurs de tes variables (même publiques) dans des variables de même type dans ta nouvelle procédure.

    Important : Pour la déclaration des objets : Un Set XXXX = dans une procédure doit s'accompagner d'un Set XXXX = Nothing dans la même procédure. Si la variable est utilisée dans d'autres procédures, elle est passée en paramètre. Avec cette méthode tu éviteras la saturation de la mémoire et tu vas vraiment gagner du temps et de la fiabilité....

    Lorsque les variables sont des objets (documents, tables, Range, etc... sur Word, Worksheet, Range, etc... sur Excel), j'instancie les variables avec Set XXXX dès le début de la procédure principale. Cela te permet de bénéficier de l'intellisense. C'est à dire qu'en tapant un . derrière ta variable, tu auras accès à toutes les propriétés et méthodes possibles sur cet objet. C'est un gain de temps énorme, même si tu finis par bien les connaître.

    Voilà en gros comment je procède, mais comme indiqué plus haut cela n'engage que moi.

  14. #14
    Nouveau membre du Club
    Femme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Février 2016
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Février 2016
    Messages : 66
    Points : 31
    Points
    31
    Par défaut
    Bonsoir Eric,

    Merci pour ces recommandations d'architecture du projet. Je vais les suivre à la lettre !

    J'ai 3 questions à te soumettre :

    Concernant la procédure qui permet le choix du document à traiter, j'ai renoncé à Debug.print car je n'ai toujours pas réussi à utiliser le résultat.
    Néanmoins je me suis débrouillée autrement :
    Ouvrir_Fichier_à_Traiter : Le fichier choisi (via FileDialogFilePicker) s'ouvre , il est renommé "Fichier à Traiter" et il s'enregistre dans un répertoire "Fichier Terminé". Il reste ouvert pour les traitements suivants.

    - 1ère question :
    La procédure CopyEntêtePiedPage ne fonctionne pas sur ce "Fichier à Traiter" car il n'a pas l'extension.docm (J'ai vérifié qu'elle fonctionne si j'ajoute cette extension à la main, ou si je sélectionne un fichier .docm)
    Dans la procédure, si j'ajoute .docm à la fin du chemin d'accès de destination j'obtiens une erreur d'execution 6294 : "Type et extension du fichier incompatibles"
    --> Pourrais-tu m'indiquer comment faire pour que la macro enregistre en docm, des fichiers qui sont en Word97 2003 au départ ?

    - 2ème question :
    Si je sors de "FileDialogFilePicker" sans sélectionner de fichier, cela provoque une erreur.
    La condition "If Fdialog.Show = -1 Then" corrige cette erreur, mais elle ajoute une deuxième ouverture de fenêtre pour la copie du document (sans cette condition, il n'y a qu'une seule ouverture de fenêtre pour la sélection du fichier)
    --> Pourrais-tu m'indiquer comment libeller correctement la condition pour éviter le bug en cas de sortie sans sélection de fichier?

    - 3ème question (indépendante) :
    Quand tous les fichiers de cette procédure sont fermés...il y a une activité rémanente ! Tout nouveau fichier Word présente dorénavant l'en-tête et le pied de page prédéfinis dans le fichier source!
    --> Aurais-tu une idée pour supprimer cette rémanence ?

    Je pense que ce sont là mes derniers points de blocage, pour cette partie de la macro en tout cas.

    D'avance merci pour ta patience !

    Cordialement,
    Marie-Noëlle


    Module 1 - Déclaration des variables
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    Option Explicit
     
    'Une variable de niveau module, déclarée à l'aide de l'instruction Public, est visible et utilisable_
    'dans le projet tout entier
     
     
    Public DocSource As Document
    Public DocDestinataire As Document
    Public DocEnCours As Document
     
     
    'le Type de données Boolean stock un simple état VRAI ou FAUX
    Public Continuer As Boolean

    Module 3 - Procédure Commune - Ouvrir_Fichier_à_Traiter ()
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    Option Explicit
     
    Sub Ouvrir_Fichier_à_Traiter()
    'Cette procedure propose la selection d'un fichier, ouvre le fichier selectionné,
    'l'enregistre dans le répertoire Fichiés Terminés.
    'Le fichier reste ouvert pour être traité par une autre procédure
     
    Dim Fdialog As FileDialog, Result As Integer
    Dim FichierFileName As String
    Dim FichierInitialFolder As String
     
    'Selectionner le fichier à traiter
    Set Fdialog = Application.FileDialog(msoFileDialogFilePicker)
     
    With Fdialog
        .InitialFileName = FichierInitialFolder
        .AllowMultiSelect = False
        .Title = "Choisir_le_Fichier"
        .Show
    End With
     
    'Ouvrir le fichier à traiter
    'If Fdialog.Show = -1 Then
        FichierFileName = Fdialog.SelectedItems(1)
        Documents.Open FichierFileName
        ActiveDocument.SaveAs "C:\Users\MonLogin\OneDrive - MonEntreprise\Fichiers Terminés\Fichier à traiter"
    'End If
     
    Set Fdialog = Nothing
    End Sub
    Module 41 - Procédure CopyEnTetePiedPage()
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
     
    Sub CopyEnTetePiedPage()
     
     
          On Error GoTo Fin
          Continuer = False
     
     
          For Each DocEnCours In Documents
              If DocEnCours.Name = "Archive Modeles de Blocs FH.docm" Then Continuer = True
          Next DocEnCours
     
          For Each DocEnCours In Documents
              If DocEnCours.Name = "Fichier à Traiter.docm" Then Continuer = True
          Next DocEnCours
     
          If Continuer = True Then
             Set DocSource = Documents("Archive Modeles de Blocs FH.docm")
             Set DocDestinataire = Documents("Fichier à traiter.docm")
          Else
             GoTo Fin
          End If
     
          If DocSource.Sections(1).Headers.Count > 0 Then
     
             DocSource.Sections(1).Headers(1).Range.Tables(1).Select
             Selection.Copy
             DocDestinataire.Sections(1).Headers(1).Range.Select
             Selection.Paste
     
             RemiseEnFormeDocument DocDestinataire
             RemiseEnFormeDocument DocSource
     
          End If
     
     
          If DocSource.Sections(1).Footers.Count > 0 Then
     
             DocSource.Sections(1).Footers(1).Range.Tables(1).Select
             Selection.Copy
             DocDestinataire.Sections(1).Footers(1).Range.Select
             Selection.Paste
     
             RemiseEnFormeDocument DocDestinataire
             RemiseEnFormeDocument DocSource
     
          End If
          GoTo Fin
     
    Fin:
     
         Set DocDestinataire = Nothing
         Set DocSource = Nothing
     
    End Sub
     
     
    Sub RemiseEnFormeDocument(ByVal DocEnCours As Document)
     
        With DocEnCours.ActiveWindow
                If .View.SplitSpecial <> wdPaneNone Then .Panes(2).Close
                If .ActivePane.View.Type = wdNormalView Or .ActivePane.View.Type = wdOutlineView Then .ActivePane.View.Type = wdPrintView
     
                .ActivePane.View.SeekView = wdSeekCurrentPageHeader
                If .View.SplitSpecial = wdPaneNone Then
                   .ActivePane.View.Type = wdPrintView
                Else
                   .View.Type = wdPrintView
                End If
     
     
                .ActivePane.View.SeekView = wdSeekCurrentPageFooter
                If .View.SplitSpecial = wdPaneNone Then
                   .ActivePane.View.Type = wdPrintView
                Else
                   .View.Type = wdPrintView
                End If
     
        End With
     
     
    End Sub

  15. #15
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Marino69 Voir le message
    Un exemple dans le fichier joint. Je te laisse le soin d'ajouter les parties manquantes (pied de page).

  16. #16
    Nouveau membre du Club
    Femme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Février 2016
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Février 2016
    Messages : 66
    Points : 31
    Points
    31
    Par défaut
    Bonsoir Eric,

    J'ai testé le formulaire et c'est génial (magique)!
    J'ai compris le principe et où insérer mes procédures c'est le principale pour l'instant.
    Son contenu néanmoins est bien au delà de mes compétences (j'ai en tout et pour tout 2 ou 3 macros Excel à mon actif et c'est la 1ere en Word !).

    Un grand merci pour cet outil qui va m'être très utile.

    une dernière question : les fichiers du répertoire à traiter se positionnent par défaut dans la fenêtre "à traiter", et il faut déplacer ceux que l'on ne veut pas traiter (par ex. si je les traite 10 par 10, il faudra que j'en déplacent 590)
    Est-ce possible d'inverser : sélectionner les fichiers à traiter ?

    Encore tous mes remerciements,
    Marie-Noëlle

  17. #17
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Marino69 Voir le message
    Bonjour,

    Oui, il faut inverser les Listbox lors du chargement de la boîte de dialogue : prendre ListBoxNonRetenus au lieu de ListBoxRetenus dans la procédure ChargerLesFichiersDansLaBoiteDeDialogue.

  18. #18
    Nouveau membre du Club
    Femme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Février 2016
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Février 2016
    Messages : 66
    Points : 31
    Points
    31
    Par défaut
    Bonsoir,

    L'inversement des Listbox fonctionne bien, et j'ai ajouté une autre procédure qui fonctionne - C'est top !

    Ce faisant j'ai remarqué que tu donnes des nouveaux noms pour les DocSource et DocEnCours d'une procédure à la suivante (DocSource2 et DocEnCours2; DocSource3 et DocEnCours3;...).
    Pour autant, pour appeler les procédures, il faut renseigner DocSource et DocEnCours.

    Si ce n'est pas trop long, pourrais-tu m'expliquer pourquoi il faut donner ces nouveaux noms?
    et comment ces nouveaux noms sont ils reconnus ?

    Cordialement,
    Marie-Noëlle

  19. #19
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Marino69 Voir le message
    Ce faisant j'ai remarqué que tu donnes des nouveaux noms pour les DocSource et DocEnCours d'une procédure à la suivante (DocSource2 et DocEnCours2; DocSource3 et DocEnCours3;...).
    Pour autant, pour appeler les procédures, il faut renseigner DocSource et DocEnCours.
    Si ce n'est pas trop long, pourrais-tu m'expliquer pourquoi il faut donner ces nouveaux noms?
    et comment ces nouveaux noms sont ils reconnus ?
    Bonjour,

    Les variables DocSource et DocEncours sont déclarées publiques et sont de type Document. J'aurais pu travailler directement avec ces variables dans toutes les autres procédures et dans tous les modules. Il m'arrive de le faire, mais c'est un risque. Si ton code contient de nombreuses lignes, je te défie de contrôler le contenu de tes variables. Pour la clarté du code, il vaut mieux passer les valeurs de tes variables en paramètres. Il est aussi plus compréhensible d'indiquer que DocSource2 représente DocSource dans la procédure principale, j'aurais pu également l'appeler DocXXXXX.

  20. #20
    Nouveau membre du Club
    Femme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Février 2016
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Février 2016
    Messages : 66
    Points : 31
    Points
    31
    Par défaut
    Bonsoir Eric,

    Merci pour toutes tes explications et le code.
    Je vais clore cette discussion avec encore tous mes remerciements.

    A bientôt certainement, ... (je m'attaque aux autres procédures).

    Bravo pour ce site aussi.

    Cordialement,
    Marie-Noëlle

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 11/06/2018, 20h02
  2. Copier-Coller tableau word vers ppt via VBA
    Par bpt26 dans le forum Général VBA
    Réponses: 2
    Dernier message: 10/07/2017, 11h34
  3. [WD-2010] probleme concernant copier et coller dans un tableau word 2010
    Par atlaslion dans le forum Word
    Réponses: 10
    Dernier message: 28/08/2015, 13h43
  4. VBA Access 2010 - Copier du texte enrichi vers Word
    Par bapt_91 dans le forum VBA Access
    Réponses: 2
    Dernier message: 15/07/2015, 10h51
  5. Réponses: 1
    Dernier message: 19/12/2006, 16h12

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo