101 votes

Comment mettre à jour tous les champs dans un document Word ?

Je veux une façon de mettre à jour tous les champs dans un document Word 2013. (Si cela fonctionne dans d'autres versions, tant mieux; j'ai eu ce problème à l'origine avec Word 2007, et rien ne semble avoir changé depuis lors.) Cela inclut les renvois, les numéros de page, les tables des matières, les index, les en-têtes, etc. Si cela peut être mis à jour en appuyant sur F9, je veux le mettre à jour.

(En théorie, la mise à jour des champs peut nécessiter la mise à jour d'autres champs, par exemple, un tableau des matières plus long modifie certains numéros de page dans le texte principal. S'occuper des cas courants me suffit. En fait, cela ne me dérange pas de devoir exécuter le macro deux ou trois fois avant qu'il ne se stabilise. Je veux juste avoir un seul macro qui trouve tout.)

Jusqu'à présent, ma tentative ne met pas à jour les champs dans les zones de texte à l'intérieur des figures. Comment les mettre à jour et qu'est-ce que j'ai oublié d'autre?


MODIFICATION : En combinant la réponse donnée avec ce que j'avais déjà, on obtient un macro qui semble tout mettre à jour (avec un défaut connu).

'' Mettre à jour tous les champs, index, etc. dans le document spécifié.
Sub UpdateAllFieldsIn(doc As Document)
    '' Mettre à jour les tables. Nous faisons cela en premier pour qu'elles contiennent toutes les entrées nécessaires
    '' et s'étendent au nombre final de pages.
    Dim toc As TableOfContents
    For Each toc In doc.TablesOfContents
        toc.Update
    Next toc
    Dim tof As TableOfFigures
    For Each tof In doc.TablesOfFigures
        tof.Update
    Next tof
    '' Mettre à jour les champs partout. Cela inclut les mises à jour des numéros de page dans
    '' les tables (mais n'ajouterait ni ne supprimerait d'entrées). Cela prend également en charge
    '' toutes les mises à jour d'index.
    Dim sr As range
    For Each sr In doc.StoryRanges
        sr.Fields.Update
        While Not (sr.NextStoryRange Is Nothing)
            Set sr = sr.NextStoryRange
            '' FIXME: pour les notes de bas de page, les notes de fin et les commentaires, je reçois un pop-up
            '' "Word ne peut pas annuler cette action. Voulez-vous continuer?"
            sr.Fields.Update
        Wend
    Next sr
End Sub
'' Mettre à jour tous les champs, index, etc. dans le document actif.
'' Il s'agit d'une sous-routine sans paramètres afin qu'elle puisse être utilisée de manière interactive.
Sub UpdateAllFields()
    UpdateAllFieldsIn ActiveDocument
End Sub

1 votes

Pour plus de complétude, vous voudrez peut-être ajouter le tableau des autorités : Dim toa As Word.TableOfAuthorities / For Each toa In ActiveDocument.TablesOfAuthorities / toa.Update / Suivant

0 votes

Juste un avertissement que j'ai essayé ceci dans Word 2013, et confirmant que cela fonctionne toujours. Merci beaucoup @Gilles d'avoir fourni le code!

0 votes

Que diriez-vous d'une macro qui va en aperçu avant impression et revient au document?

2voto

Sherd Points 121

Pour C# :

using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.Office.Interop.Word;

class Program
{
    static void Main(string[] args)
    {
        List path = new List(args);

        string filePathstr = string.Join(" ", path.ToArray());
        //System.Windows.Forms.MessageBox.Show("filepathstr: " + filePathstr);

        string folderPathstr = Path.GetDirectoryName(filePathstr);
        //System.Windows.Forms.MessageBox.Show("folderPathstr: " + folderPathstr);

        try
        {
            Application ap = new Application();
            Document document = ap.Documents.Open(filePathstr);
            document.Fields.Update();

            foreach (Section section in document.Sections)
            {
                document.Fields.Update();  // mettre à jour chaque section

                HeadersFooters headers = section.Headers;  //Obtenir tous les en-têtes
                foreach (HeaderFooter header in headers)
                {
                    Fields fields = header.Range.Fields;
                    foreach (Field field in fields)
                    {
                        field.Update();  // mettre à jour tous les champs dans les en-têtes
                    }
                }

                HeadersFooters footers = section.Footers;  //Obtenir tous les pieds de page
                foreach (HeaderFooter footer in footers)
                {
                    Fields fields = footer.Range.Fields;
                    foreach (Field field in fields)
                    {
                        field.Update();  // mettre à jour tous les champs dans les pieds de page
                    }
                }
            }    

            document.Save();
            document.Close();

        }
        catch (NullReferenceException)
        {
            System.Windows.Forms.MessageBox.Show("Un fichier valide n'a pas été sélectionné.");
        }
    }
}

1voto

Charles Kenyon Points 2826

Les deux méthodes suivantes ont fonctionné pour moi :

Sub FieldsUpdateAlStoryMayor()
' Graham Mayor
' http://www.gmayor.com/installing_macro.htm
' mettre à jour les champs dans un document
    Dim oStory As range
    For Each oStory In ActiveDocument.StoryRanges
        oStory.Fields.Update
        If oStory.StoryType <> wdMainTextStory Then
            While Not (oStory.NextStoryRange Is Nothing)
                Set oStory = oStory.NextStoryRange
                oStory.Fields.Update
            Wend
        End If
    Next oStory
    Set oStory = Nothing
End Sub

Sub FieldsUpdateAllStoryMaxey()    ' Greg Maxey
' https://gregmaxey.com/word_tip_pages/word_fields.html
    Dim rngstory As Word.range
    Dim lngValidate As Long    ' ne connais pas la raison de ceci - CK
    Dim oShp As Shape
    Dim oTOC As TableOfContents, oToa As TableOfAuthorities, oTof As TableOfFigures
    lngValidate = ActiveDocument.Sections(1).Headers(1).range.StoryType    ' ne connais pas la raison de ceci
    For Each rngstory In ActiveDocument.StoryRanges
        ' itérer à travers toutes les histoires liées
        Do
            On Error Resume Next
            rngstory.Fields.Update
            Select Case rngstory.StoryType
                Case 6, 7, 8, 9, 10, 11
                    If rngstory.ShapeRange.Count > 0 Then
                        For Each oShp In rngstory.ShapeRange
                            If oShp.TextFrame.HasText Then
                                oShp.TextFrame.TextRange.Fields.Update
                            End If
                        Next
                    End If
                Case Else
                    ' Ne rien faire
            End Select
            On Error GoTo -1
            ' Obtenir l'histoire liée suivante (si elle existe)
            Set rngstory = rngstory.NextStoryRange
        Loop Until rngstory Is Nothing
        ' Cas spéciaux
        For Each oTOC In ActiveDocument.TablesOfContents
            oTOC.Update
        Next oTOC
        For Each oToa In ActiveDocument.TablesOfAuthorities
            oToa.Update
        Next
        For Each oTof In ActiveDocument.TablesOfFigures
            oTof.Update
        Next
    Next
End Sub

Les deux traitent, de différentes manières, du fait que les champs peuvent être présents dans des "histoires" autres que l'histoire principale du document. Vous pouvez consulter leurs sites web pour voir la théorie/idées derrière le code.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X