Partager via


Supprimer tous les commentaires d’un auteur de toutes les diapositives d’une présentation

Cette rubrique montre comment utiliser les classes du Kit de développement logiciel (SDK) Open XML pour Office afin de supprimer par programme tous les commentaires d’un auteur spécifique dans une présentation.

Remarque

Cet exemple concerne les commentaires modernes PowerPoint. Pour les commentaires classiques, consultez l’exemple archivé sur GitHub.

Obtention d’un objet PresentationDocument

Dans le Kit de développement logiciel (SDK) Open XML, la PresentationDocument classe représente un package de document de présentation. Pour utiliser un document de présentation, commencez par créer un instance de la PresentationDocument classe, puis utilisez cette instance. Pour créer la classe instance à partir du document, appelez la Open méthode qui utilise un chemin d’accès de fichier et une valeur booléenne comme deuxième paramètre pour spécifier si un document est modifiable. Pour ouvrir un document en lecture/écriture, spécifiez la valeur true de ce paramètre, comme indiqué dans l’instruction suivante using . Dans ce code, le paramètre fileName est une chaîne qui représente le chemin d’accès pour le fichier à partir duquel vous voulez ouvrir le document, et le paramètre author est le nom d’utilisateur affiché dans l’onglet Général des options PowerPoint.

using (PresentationDocument doc = PresentationDocument.Open(fileName, true))

Avec v3.0.0+ la Close() méthode a été supprimée au profit de l’instruction using. Cela garantit que la Dispose() méthode est appelée automatiquement lorsque l’accolade fermante est atteinte. Le bloc qui suit l’instruction using établit une étendue pour l’objet créé ou nommé dans l’instruction using , dans ce cas doc.

Structure de document de présentation de base

La structure de base d’un PresentationML document se compose d’un certain nombre de parties, parmi lesquelles la partie main qui contient la définition de présentation. Le texte suivant de la spécification ISO/IEC 29500 présente la forme globale d’un PresentationML package.

La partie main d’un PresentationML package commence par un élément racine de présentation. Cet élément contient une présentation qui, à son tour, fait référence à une liste de diapositives, à une liste de diapositives master, à une liste de notes master et à un document master liste. La liste des diapositives référence toutes les diapositives de la présentation ; la liste de masques de diapositive référence tous les masques de diapositive utilisés dans la présentation ; le masque de pages de note contient des informations sur la mise en forme des pages de notes et le masque de document décrit comment un document se présente.

Un document à distribuer est un ensemble imprimé de diapositives qui peut être distribué aux personnes de l’audience.

En plus de textes et de graphiques, chaque diapositive peut contenir des commentaires et des notes, peut avoir une disposition et peut faire partie d’une ou plusieurs présentations personnalisées. Un commentaire est une annotation destinée à la personne qui gère le jeu de diapositives de la présentation. Une note est un rappel ou un élément de texte destiné au présentateur ou à l’audience.

Les autres fonctionnalités qu’un PresentationML document peut inclure les suivantes : animation, audio, vidéo et transitions entre les diapositives.

Un PresentationML document n’est pas stocké sous la forme d’un corps volumineux dans une seule partie. Au lieu de cela, les éléments qui implémentent certains groupes de fonctionnalités sont stockés dans des composants distincts. Par exemple, tous les auteurs d’un document sont stockés dans une partie d’auteurs, tandis que chaque diapositive a sa propre partie.

ISO/IEC 29500 : 2016

L’exemple de code XML suivant représente une présentation qui contient deux diapositives ayant les numéros d’identification 267 et 256.

    <p:presentation xmlns:p="…" … > 
       <p:sldMasterIdLst>
          <p:sldMasterId
             xmlns:rel="https://…/relationships" rel:id="rId1"/>
       </p:sldMasterIdLst>
       <p:notesMasterIdLst>
          <p:notesMasterId
             xmlns:rel="https://…/relationships" rel:id="rId4"/>
       </p:notesMasterIdLst>
       <p:handoutMasterIdLst>
          <p:handoutMasterId
             xmlns:rel="https://…/relationships" rel:id="rId5"/>
       </p:handoutMasterIdLst>
       <p:sldIdLst>
          <p:sldId id="267"
             xmlns:rel="https://…/relationships" rel:id="rId2"/>
          <p:sldId id="256"
             xmlns:rel="https://…/relationships" rel:id="rId3"/>
       </p:sldIdLst>
           <p:sldSz cx="9144000" cy="6858000"/>
       <p:notesSz cx="6858000" cy="9144000"/>
    </p:presentation>

À l’aide du Kit de développement logiciel (SDK) Open XML, vous pouvez créer une structure de document et du contenu à l’aide de classes fortement typées qui correspondent aux éléments PresentationML. Vous trouverez ces classes dans l’espace de noms . Le tableau suivant répertorie les noms de classes des classes qui correspondent aux sldéléments , sldLayout, sldMasteret notesMaster .

Élément PresentationML Classe du Kit de développement logiciel (SDK) Open XML Description
<sld/> Slide Diapositive de présentation. Il s’agit de l’élément racine de SlidePart.
<sldLayout/> SlideLayout Mise en page des diapositives. Il s’agit de l’élément racine de SlideLayoutPart.
<sldMaster/> SlideMaster Masque des diapositives. Il s’agit de l’élément racine de SlideMasterPart.
<notesMaster/> NotesMaster Masque des pages de notes (ou handoutMaster). Il s’agit de l’élément racine de NotesMasterPart.

La structure de l’élément de commentaire

Le texte suivant de la spécification ISO/IEC 29500 présente des commentaires dans un package de présentation.

Un commentaire est une note textuelle rattachée à une diapositive, ayant comme objectif principal de permettre aux lecteurs d’une présentation de fournir des commentaires à l’auteur de la présentation. Chaque commentaire contient une chaîne de texte non mise en forme et des informations sur son auteur, et elle est rattachée à un emplacement particulier sur une diapositive. Les commentaires peuvent être visibles lors de la modification de la présentation, mais ils n’apparaissent pas lors de l’exécution d’un diaporama. L’application d’affichage décide du moment où afficher les commentaires et détermine leur apparence visuelle.

© ISO/IEC 29500 : 2016

Structure de l’élément Modern Comment

L’élément XML suivant spécifie un seul commentaire. Il contient le texte du commentaire (t) et les attributs faisant référence à son auteur (authorId), à la date et à l’heure de création (created) et à l’ID de commentaire (id).

<p188:cm id="{62A8A96D-E5A8-4BFC-B993-A6EAE3907CAD}" authorId="{CD37207E-7903-4ED4-8AE8-017538D2DF7E}" created="2024-12-30T20:26:06.503">
  <p188:txBody>
      <a:bodyPr/>
      <a:lstStyle/>
      <a:p>
      <a:r>
          <a:t>Needs more cowbell</a:t>
      </a:r>
      </a:p>
  </p188:txBody>
</p188:cm>

Les tableaux suivants répertorient les définitions des attributs et éléments enfants possibles de l’élément cm (comment). Pour obtenir la définition complète , consultez MS-PPTX 2.16.3.3 CT_Comment

Attribut Définition
id Spécifie l’ID d’un commentaire ou d’une réponse de commentaire.
authorId Spécifie l’ID d’auteur d’un commentaire ou d’une réponse de commentaire.
status Spécifie le status d’un commentaire ou d’une réponse de commentaire.
créé Spécifie la date et heure de création de la réponse au commentaire ou au commentaire.
startDate Spécifie la date de début du commentaire.
dueDate Spécifie la date d’échéance du commentaire.
assignedTo Spécifie la liste des auteurs auxquels le commentaire est attribué.
Intégration Spécifie le pourcentage d’achèvement du commentaire.
title Spécifie le titre d’un commentaire.
Élément enfant Définition
pc :sldMkLst Spécifie un moniker de contenu qui identifie la diapositive à laquelle le commentaire est ancré.
ac :deMkLst Spécifie un moniker de contenu qui identifie l’élément de dessin auquel le commentaire est ancré.
ac :txMkLst Spécifie un moniker de contenu qui identifie la plage de caractères de texte à laquelle le commentaire est ancré.
unknownAnchor Spécifie une ancre inconnue à laquelle le commentaire est ancré.
Pos Spécifie la position du commentaire par rapport au coin supérieur gauche du premier objet auquel le commentaire est ancré.
replyLst Spécifie la liste des réponses au commentaire.
txBody Spécifie le texte d’un commentaire ou d’une réponse de commentaire.
extLst Spécifie une liste d’extensions pour un commentaire ou une réponse de commentaire.

L’exemple de schéma XML suivant définit les membres de l’élément cm en plus des attributs obligatoires et facultatifs.

 <xsd:complexType name="CT_Comment">
   <xsd:sequence>
     <xsd:group ref="EG_CommentAnchor" minOccurs="1" maxOccurs="1"/>
     <xsd:element name="pos" type="a:CT_Point2D" minOccurs="0" maxOccurs="1"/>
     <xsd:element name="replyLst" type="CT_CommentReplyList" minOccurs="0" maxOccurs="1"/>
     <xsd:group ref="EG_CommentProperties" minOccurs="1" maxOccurs="1"/>
   </xsd:sequence>
   <xsd:attributeGroup ref="AG_CommentProperties"/>
   <xsd:attribute name="startDate" type="xsd:dateTime" use="optional"/>
   <xsd:attribute name="dueDate" type="xsd:dateTime" use="optional"/>
   <xsd:attribute name="assignedTo" type="ST_AuthorIdList" use="optional" default=""/>
   <xsd:attribute name="complete" type="s:ST_PositiveFixedPercentage" default="0%" use="optional"/>
   <xsd:attribute name="title" type="xsd:string" use="optional" default=""/>
 </xsd:complexType>

Fonctionnement de l’exemple de code

Après avoir ouvert le document de présentation pour l’accès en lecture/écriture et instancié la PresentationDocument classe, le code obtient l’auteur de commentaire spécifié à partir de la liste des auteurs de commentaires.

// Get the modern comments.
IEnumerable<Author>? commentAuthors = doc.PresentationPart?.authorsPart?.AuthorList.Elements<Author>()
    .Where(x => x.Name is not null && x.Name.HasValue && x.Name.Value!.Equals(author));

En itérant parmi les auteurs correspondants et les diapositives de la présentation, le code obtient tous les composants diapositive, ainsi que le composant commentaires de chacun. Il obtient ensuite la liste des commentaires de l’auteur spécifié et supprime chacun d’eux. Il vérifie si le composant commentaires ne contient aucun commentaire existant, auquel cas il le supprime. Il supprime également l’auteur des commentaires du composant auteurs de commentaires.

// Iterate through all the matching authors.
foreach (Author commentAuthor in commentAuthors)
{
    string? authorId = commentAuthor.Id;
    IEnumerable<SlidePart>? slideParts = doc.PresentationPart?.SlideParts;

    // If there's no author ID or slide parts or slide parts, return.
    if (authorId is null || slideParts is null)
    {
        return;
    }

    // Iterate through all the slides and get the slide parts.
    foreach (SlidePart slide in slideParts)
    {
        IEnumerable<PowerPointCommentPart>? slideCommentsParts = slide.commentParts;

        // Get the list of comments.
        if (slideCommentsParts is not null)
        {
            IEnumerable<Tuple<PowerPointCommentPart, Comment>> commentsTup = slideCommentsParts
                .SelectMany(scp => scp.CommentList.Elements<Comment>()
                .Where(comment => comment.AuthorId is not null && comment.AuthorId == authorId)
                .Select(c => new Tuple<PowerPointCommentPart, Comment>(scp, c)));

            foreach (Tuple<PowerPointCommentPart, Comment> comment in commentsTup)
            {
                // Delete all the comments by the specified author.
                comment.Item1.CommentList.RemoveChild(comment.Item2);

                // If the commentPart has no existing comment.
                if (comment.Item1.CommentList.ChildElements.Count == 0)
                {
                    // Delete this part.
                    slide.DeletePart(comment.Item1);
                }
            }

        }
    }

    // Delete the comment author from the authors part.
    doc.PresentationPart?.authorsPart?.AuthorList.RemoveChild(commentAuthor);
}

Exemple de code

La méthode suivante prend comme paramètres le nom et le chemin d’accès au fichier de présentation source et le nom de l’auteur dont les commentaires doivent être supprimés. Elle recherche tous les commentaires de l’auteur spécifié dans la présentation et les supprime. Elle supprime ensuite cet auteur de la liste des auteurs de commentaires.

Remarque

Pour obtenir le nom exact de l’auteur, ouvrez le fichier de présentation, cliquez sur l’élément de menu Fichier , puis cliquez sur Options. La fenêtre Options PowerPoint s’ouvre et le contenu de l’onglet Général s’affiche. Le nom de l’auteur doit correspondre au nom d’utilisateur de cet onglet.

Voici un exemple de code complet en C# et Visual Basic.

// Remove all the comments in the slides by a certain x.
static void DeleteCommentsByAuthorInPresentation(string fileName, string author)
{
    using (PresentationDocument doc = PresentationDocument.Open(fileName, true))
    {
        // Get the modern comments.
        IEnumerable<Author>? commentAuthors = doc.PresentationPart?.authorsPart?.AuthorList.Elements<Author>()
            .Where(x => x.Name is not null && x.Name.HasValue && x.Name.Value!.Equals(author));

        if (commentAuthors is null)
        {
            return;
        }

        // Iterate through all the matching authors.
        foreach (Author commentAuthor in commentAuthors)
        {
            string? authorId = commentAuthor.Id;
            IEnumerable<SlidePart>? slideParts = doc.PresentationPart?.SlideParts;

            // If there's no author ID or slide parts or slide parts, return.
            if (authorId is null || slideParts is null)
            {
                return;
            }

            // Iterate through all the slides and get the slide parts.
            foreach (SlidePart slide in slideParts)
            {
                IEnumerable<PowerPointCommentPart>? slideCommentsParts = slide.commentParts;

                // Get the list of comments.
                if (slideCommentsParts is not null)
                {
                    IEnumerable<Tuple<PowerPointCommentPart, Comment>> commentsTup = slideCommentsParts
                        .SelectMany(scp => scp.CommentList.Elements<Comment>()
                        .Where(comment => comment.AuthorId is not null && comment.AuthorId == authorId)
                        .Select(c => new Tuple<PowerPointCommentPart, Comment>(scp, c)));

                    foreach (Tuple<PowerPointCommentPart, Comment> comment in commentsTup)
                    {
                        // Delete all the comments by the specified author.
                        comment.Item1.CommentList.RemoveChild(comment.Item2);

                        // If the commentPart has no existing comment.
                        if (comment.Item1.CommentList.ChildElements.Count == 0)
                        {
                            // Delete this part.
                            slide.DeletePart(comment.Item1);
                        }
                    }

                }
            }

            // Delete the comment author from the authors part.
            doc.PresentationPart?.authorsPart?.AuthorList.RemoveChild(commentAuthor);
        }
    }
}

Voir aussi