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 :

Trouver le premier tableau à partir d'un endroit d'un fichier [WD-2003]


Sujet :

VBA Word

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    97
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 97
    Points : 121
    Points
    121
    Par défaut Trouver le premier tableau à partir d'un endroit d'un fichier
    Bonjour,

    Après une recherche infructueuse sur le forum, je vous soulève mon
    problème. Le fichier Word que j'utilise contient de nombreux paragraphes et
    de nombreux tableaux. Mon but est de connaître l'indice du 1er tableau d'un
    chapitre dont le nom est une chaîne de caractères particulière.

    Dans cette optique je recherche d'abord la chaîne de caractère, supposons
    qu'elle corresponde à la constante cChaineATrouver. Cela correspond au 1er
    traitement de ma routine. A noter que je vérifie la longueur de la chaîne
    pour éviter de récupérer la chaîne qui se trouve dans le sommaire (car
    cette chaîne est censée être un titre).

    Une fois ce prétraitement effectué, si la chaîne est présente dans le
    document, mon idée est alors de comparer chaque paragraphe à la première
    cellule de chaque tableau du document. S'il y a concordance, j'ai trouvé le
    tableau recherché.

    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
    Public Sub MaFonction(ByRef oDoc as Word.Document)
    Dim Para as Word.Paragraph
    Dim ParaTrouve as Boolean
    Dim i, j, k as Long
     
    ' Récupération du bon chapitre
    ParaTrouve = False
    For Each Para In oDoc Then
        If InStr(Para.Range.Text, cChaineATrouver) Then
            ParaTrouve = True
            Exit For
        End If
    Next
     
    ' Récupération du tableau
    If ParaTrouve = True Then
        For j = i + 1 to oDoc.Paragraphs.Count - i
            For k = 1 to oDoc.Tables.Count
                If oDoc.Paragraphs(j).Range.Text = oDoc.Tables(k).Cell(1,1).Range.Text Then
                    ' J'ai trouvé mon tableau, il a pour indice "k"
                    j = oDoc.Paragraphs.Count - i
                    Exit For
                End If
            Next k
        Next i
    End If
    Cependant, cette méthode possède quelques inconvénients :
    - Je ne teste que la 1ère cellule du tableau. Si elle est vide, je risque
    de la confondre avec un paragraphe vide et je récupère alors un mauvais
    tableau
    - Le temps d'exécution lorsque le fichier possède plus de 10000 paragraphes
    est beaucoup trop long
    - La méthode semble quand même bien lourde...

    Comment faire pour améliorer ma fonction ? Me suis-je dès le départ mal
    orienté ?

    En passant, j'ai aussi eu un autre problème en utilisant la propriété Find.
    Si j'écris

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Dim a as Boolean
     
    oDoc.Content.Select
    With Selection.Find
        .ClearFormatting
        .MatchWholeWord = False
        .MatchCase = False
        .Text = cChaineATrouver
        a = .Execute
    End With
    Le document reste entièrement sélectionné et a = False

    Alors que si j'écris

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Dim a as Boolean
     
    With oDoc.Content.Find
        .ClearFormatting
        .MatchWholeWord = False
        .MatchCase = False
        .Text = cChaineATrouver
        a = .Execute
    End With
    a = True mais aucun texte n'est sélectionné. N'est-ce pas pourtant le but
    de la manoeuvre ?

    Je m'excuse de la longueur de mon message, j'espère avoir été assez clair
    et que vous trouverez une solution à mon problème. Merci d'avance.

  2. #2
    Rédacteur/Modérateur

    Avatar de Heureux-oli
    Homme Profil pro
    Contrôleur d'industrie
    Inscrit en
    Février 2006
    Messages
    21 086
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : Belgique

    Informations professionnelles :
    Activité : Contrôleur d'industrie
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 21 086
    Points : 42 925
    Points
    42 925
    Par défaut
    Salut,

    Pour que le texte soit sélectionné, il faut passer par une sélection.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    With Selection.find
        .forward = true
        .text = "MonTexte"
        a = .Execute
    End With
    Mais il faut être certain que la chaîne à trouver se trouve après la sélection en cours.
    Donc, il faut aller au début du document.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Selection.HomeKey Unit:=wdStory
    On peut éliminer la chaîne qui se trouve dans la table des matières en vérifiant son style, les entrées de la table des matières est en Style commençant par TOC (Table Of Content).

    Pour connaître l'index d'un tableau situé dans un document, il suffit de le sélectionner et d'étendre la sélection jusqu'au début du document.
    Ensuite, il ne reste qu'à compter le nombre de tables que contient la sélection et ce nombre est l'index de la table.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Selection.HomeKey unit:=wdStory, Extend:=wdExtend
    monIndex = Selection.tables.count
    Pour savoir si tu te trouves dans un tableau, il existe une fonction.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Selection.Information(wdWithInTable)

    En passant, toutes les variables doivent être typées individuellement en VBA.
    Dans ton code :
    seul K est un long, les autres sont des variants.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Dim i as long, j as long, k as long
    Pour des raisons de rapidité d'exécution, je te conseille de passer par la fonction de recherche qui est plus performante que par une boucle sur tous les paragraphes.

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    97
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 97
    Points : 121
    Points
    121
    Par défaut
    Pour la recherche, je ne savais pas que le texte ne devait pas être sélectionné. J'ai donc testé ta méthode mais sans succès.

    Voici mon code écrit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    oDoc.Content.Select
    Selection.HomeKey Unit:=wdStory
    With Selection.find
        .forward = true
        .text = "MonTexte"
        a = .Execute
    End With
    L'exécution entraîne de nouveau la sélection de l'intégralité du document et au DEBUG, j'obtiens

    Le problème ne peut-il pas venir du fait que je ne travaille pas dans le document courant mais dans une autre instance de word (oDoc) ?

    Merci pour les autres réponses, je ne les ai pas encore testées, mais cela me paraît une bonne solution.

  4. #4
    Expert éminent
    Avatar de Sepia
    Homme Profil pro
    Administrateur du cursus IDE@L - Chef de Projet NCU (digital learning) - Université de Rennes
    Inscrit en
    Octobre 2007
    Messages
    3 117
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Administrateur du cursus IDE@L - Chef de Projet NCU (digital learning) - Université de Rennes
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Octobre 2007
    Messages : 3 117
    Points : 6 856
    Points
    6 856
    Par défaut
    Salut Yoyo57,


    Citation Envoyé par Yoyo57 Voir le message
    Pour la recherche, je ne savais pas que le texte ne devait pas être sélectionné
    Non, ce n'est pas nécessaire mais Heureux-Oli t'a donné la méthode la plus simple pour des raisons didactiques. Voici un tuto sur la fonction rechercher/remplacer de Word

    @+

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    97
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 97
    Points : 121
    Points
    121
    Par défaut
    Ton tutoriel est très intéressant Sepia, je l'ai lu mais il se focalise sur la fonction recherche de word, et non sur son utilisation depuis VBA.

    Ma recherche est assez simple, je sais que le mot recherché figure dans mon document, mais VBA ne le trouve pas et ne le sélectionne pas.

  6. #6
    Rédacteur/Modérateur

    Avatar de Heureux-oli
    Homme Profil pro
    Contrôleur d'industrie
    Inscrit en
    Février 2006
    Messages
    21 086
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : Belgique

    Informations professionnelles :
    Activité : Contrôleur d'industrie
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 21 086
    Points : 42 925
    Points
    42 925
    Par défaut
    Salut,

    Il ne faut pas sélectionner un texte en tout ou en partie.

    C'est la sélection qui va aller au texte cherché.

    Juste

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Selection.HomeKey unit:=wdstory
    With Selection.Find
       .Text = "mmmm"
    .....
    La première ligne est le déplacement du curseur au début du document.
    Les suivantes sont pour l'utilisation de la méthode Find.

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    97
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 97
    Points : 121
    Points
    121
    Par défaut
    Rebonjour,

    J'ai bien compris qu'il fallait se placer au début du document mais mon idée de sélectionner l'intégralité du document permettait de placer le curseur dans ce document (où se trouve le texte recherché) et non dans le document actif depuis lequel est lancée la macro.

    J'ai testé telle quelle ta solution, malheureusement toujours sans succès.

    Mon document commence par un tableau. J'ai donc pensé que la recherche ne s'effectuait que dans la 1ère case du tableau. J'ai alors cherché le premier mot du tableau. Nouvel échec....

    Merci encore pour le temps passé sur mon problème.

  8. #8
    Rédacteur/Modérateur

    Avatar de Heureux-oli
    Homme Profil pro
    Contrôleur d'industrie
    Inscrit en
    Février 2006
    Messages
    21 086
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : Belgique

    Informations professionnelles :
    Activité : Contrôleur d'industrie
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 21 086
    Points : 42 925
    Points
    42 925
    Par défaut
    Salut,

    La sélection est obligatoirement dans le document ouvert et donc actif.

    Soit j'ai pas tout compris soit il te manque quelque chose.

    Pour tester ce code, j'insère du cade avec =rand(10,10)
    je place un tableau contenant dans une des cellules Olivier et lance la recherche.

    J'ai bien un True sir .Execute et le mot est souligné dans le tableau.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    Sub rechercheMot()
    Selection.HomeKey unit:=wdStory
    With Selection.Find
        .Text = "Olivier"
        .Forward = True
        Debug.Print .Execute
    End With
    Debug.Print Selection.Range.Text
    End Sub
    Et le dernier debut.print renvoie bien le mot trouvé.

    Pour le premier mot du tableau, c'est assez simple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Sub testsurtableau()
    Dim otbl As Table
     
    For Each otbl In ActiveDocument.Tables
        otbl.Cell(1, 1).Select
     
        Debug.Print Selection.Words(1)
    Next otbl
     
    End Sub
    Si tu ne souhaites pas passer par un objet sélection

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Sub testsurtableau()
    Dim otbl As Table
     
    For Each otbl In ActiveDocument.Tables
     
        Debug.Print otbl.Range.Words(1)
     
    Next otbl
     
    End Sub

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    97
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 97
    Points : 121
    Points
    121
    Par défaut
    Salut,

    Pour fixer les idées, le document dans lequel je veux faire la recherche commence par un tableau, puis s'enchaînent du texte et des tableaux. Le mot recherché n'est cependant pas dans un tableau.

    La sélection est obligatoirement dans le document ouvert et donc actif.
    Ce que tu dis est intéressant, je pense que mon problème vient de là. En effet, si j'écris le code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    oDoc.Activate 'oDoc est le document fils où je compte effectuer la recherche
    If oDoc.Name <> ActiveDocument.Name Then Call MsgBox("Erreur")
    j'obtiens à l'exécution une boîte de dialogue me disant qu'il y a une erreur. Cela veut dire que mon document n'a pas été activé, et cela doit être la cause du plantage de la recherche. Pourtant, le document en question (oDoc) est ouvert.

    Au DEBUG, je vois que le nom du document actif est le document source qui lance la recherche.

    Il faut savoir que ma recherche est lancée à l'aide d'un UserForm. Je me dis donc que le UserForm empêche l'activation d'un autre document (dans mon cas oDoc). Je tente de contourner le problème en ouvrant mon UserForm de manière non modale (avec le TAG vbModeless). Toujours sans succès, je n'arrive pas à activer oDoc.

    Je pense donc que le problème ne vient pas de l'utilisation de la propriété Find mais de la mauvaise initialisation de l'endroit dans lequel la recherche doit s'effectuer. Qu'en penses-tu ? As-tu une solution pour régler ce problème ?

  10. #10
    Rédacteur/Modérateur

    Avatar de Heureux-oli
    Homme Profil pro
    Contrôleur d'industrie
    Inscrit en
    Février 2006
    Messages
    21 086
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : Belgique

    Informations professionnelles :
    Activité : Contrôleur d'industrie
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 21 086
    Points : 42 925
    Points
    42 925
    Par défaut
    Salut,

    Je viens de faire un test et si on sélectionne le range du document, on peut faire la recherche.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    Sub recherchemotdocument2()
    Dim oDoc As Document
     
    Set oDoc = Application.Documents.Open("c:\temp\a.doc")
    oDoc.Range.Select
    With Selection.Find
        .Text = "Olivier"
        .Forward = True
        Debug.Print .Execute
    End With
     
     
    End Sub
    Ce code ne se trouve pas dans le document où j'effectue la recherche.
    J'ouvre le document, sélectionne le range et fais une recherche sur ce range.

    La fonction trouve bien le mot situé dans une table.

  11. #11
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    97
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 97
    Points : 121
    Points
    121
    Par défaut
    Salut,

    Je viens de comprendre l'origine de mon problème. En fait je passais par la fonction suivante pour ouvrir le fichier Word

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Public Function OuvertureFichier(ByRef oWord as Object, ByVal NomFichier as String)
        Set oWord = CreateObject("Word.Application")
        oWord.Documents.Open NomFichier, False, False
        oWord.Visible = True
    End Function
    Cette fonction était utilisée de la manière suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Call OuvertureFichier(oWord, NomFichier)
    Set oDoc = oWord.Documents(1)
    Or cela crée une nouvelle instance de word, ce qui m'empêche de faire la recherche dans le fichier.

    J'ai adopté ta solution :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Set oDoc = Application.Documents.Open(NomFichier, False, False)
    Mais cette méthode a deux inconvénients majeur : je ne vois plus la macro qui lance l'ouverture du fichier mais les différentes sélections qui se font dans mon document ouvert.

    J'ai corrigé ces inconvénients par la ligne Application.ScreenUpdating = False, et en rendant mon UserForm non modal

    Merci infiniment pour toute l'aide apportée, je considère le problème résolu. Et merci aussi pour la foule de petits conseils donnés au cours de cette discussion.

  12. #12
    Rédacteur/Modérateur

    Avatar de Heureux-oli
    Homme Profil pro
    Contrôleur d'industrie
    Inscrit en
    Février 2006
    Messages
    21 086
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : Belgique

    Informations professionnelles :
    Activité : Contrôleur d'industrie
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 21 086
    Points : 42 925
    Points
    42 925
    Par défaut
    Salut,

    En marge de la discussion, j'ai repéré un petit souci dans ton code.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Public Function OuvertureFichier(ByRef oWord as Object, ByVal NomFichier as String)
        Set oWord = CreateObject("Word.Application")
    Dans les arguments passés à la fonction, tu as un objet oWord.
    Normalement, cet objet devrait déjà être défini puisqu'il n'est pas optionnel.
    Or dans la ligne suivante, tu lui attribues une valeur ?

    Autre chose, tu aurais plus de facilité à utiliser le EarlyBinding au lieu de LateBinding.

  13. #13
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    97
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 97
    Points : 121
    Points
    121
    Par défaut
    Salut,

    Citation Envoyé par Heureux-oli Voir le message
    Dans les arguments passés à la fonction, tu as un objet oWord.
    Normalement, cest objet devrait déjà être défini puisqu'il n'est pas optionnel.
    Or dans la ligne suivante, tu lui attribue une valeur ?
    En fait, l'objet n'est pas défini, il est juste déclaré.
    Comme je passe par une référence, je me permets d'initialiser mon objet à l'intérieur de la fonction appelée.

    Citation Envoyé par Heureux-oli Voir le message
    Autre chose, tu aurais plus de facilité à utiliser le EarlyBinding au lieu de LateBinding.
    C'est en effet ce que j'ai fait pour résoudre mon problème, je remplace l'intégralité du code d'appel de la fonction par :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Set oDoc = Application.Documents.Open(NomFichier, False, False)
    Cela permet d'ouvrir le document dans la même instance de Word, et donc de pouvoir activer oDoc (ce qui était impossible avec mon code initial), comme je l'explique précédemment :

    Citation Envoyé par Yoyo57 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    oDoc.Activate 'oDoc est le document fils où je compte effectuer la recherche
    If oDoc.Name <> ActiveDocument.Name Then Call MsgBox("Erreur")
    j'obtiens à l'exécution une boîte de dialogue me disant qu'il y a une erreur. Cela veut dire que mon document n'a pas été activé, et cela doit être la cause du plantage de la recherche. Pourtant, le document en question (oDoc) est ouvert.
    Au final ta fonction recherchemotdocument2() me convient parfaitement pour ma recherche. Merci encore !

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

Discussions similaires

  1. Réponses: 8
    Dernier message: 31/05/2020, 19h18
  2. Réponses: 2
    Dernier message: 18/11/2012, 11h25
  3. Trouver le premier element d'un tableau dans un template
    Par Zucher dans le forum Contribuez
    Réponses: 2
    Dernier message: 27/01/2008, 18h48
  4. Réponses: 2
    Dernier message: 13/09/2007, 12h55
  5. Réponses: 2
    Dernier message: 03/01/2005, 16h02

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