Exercice : utiliser des feuilles de calcul et des commandes de complément

Effectué

Dans cet exercice, vous apprendrez à figer la ligne d’en-tête du tableau que vous avez créé précédemment, pour qu’elle reste visible lorsque l’utilisateur fait défiler la feuille de calcul vers le bas. Vous allez également découvrir comment activer ou désactiver la protection des feuilles de calcul.

Figer un en-tête de tableau

Lorsqu’un tableau est tellement long que l’utilisateur doit le faire défiler pour afficher les lignes suivantes, la ligne d’en-tête peut être masquée. Dans cette section, vous allez figer la ligne d’en-tête du tableau que vous avez créé précédemment, pour qu’elle reste visible lorsque l’utilisateur fait défiler la feuille de calcul vers le bas.

Figer la ligne d’en-tête du tableau

  1. Ouvrez le fichier ./src/taskpane/taskpane.html.

  2. Recherchez l’élément <button> du bouton create-chart, puis ajoutez la balise suivante après cette ligne :

    <button class="ms-Button" id="freeze-header">Freeze Header</button><br/><br/>
    
  3. Ouvrez le fichier ./src/taskpane/taskpane.js.

  4. Dans l’appel de la méthode Office.onReady(), recherchez la ligne suivante :

    document.getElementById("create-chart").onclick = createChart;
    

    Ajoutez le code suivant juste après :

    document.getElementById("freeze-header").onclick = freezeHeader;
    
  5. Ajoutez la fonction suivante à la fin du fichier :

    async function freezeHeader() {
      await Excel.run(async (context) => {
    
        // TODO1: Queue commands to keep the header visible when the user scrolls.
    
        await context.sync();
      })
      .catch(function (error) {
        console.log("Error: " + error);
        if (error instanceof OfficeExtension.Error) {
          console.log("Debug info: " + JSON.stringify(error.debugInfo));
        }
      });
    }
    
  6. À l’intérieur de la fonction freezeHeader(), remplacez TODO1 par le code suivant:

    const currentWorksheet = context.workbook.worksheets.getActiveWorksheet();
    currentWorksheet.freezePanes.freezeRows(1);
    

    Remarque

    • La collection Worksheet.freezePanes est un ensemble de volets de la feuille de calcul qui sont épinglés, c’est-à-dire figés, lorsque vous faites défiler la feuille de calcul.
    • La méthode freezeRows() prend comme paramètre le nombre de lignes, à partir du haut, qui doivent être figées. Nous transmettons la valeur 1 pour épingler la première ligne.
  7. Vérifiez que vos modifications sont enregistrées dans le projet.

Test du complément

  1. Si le serveur web local est déjà en cours d’exécution et que votre complément est déjà chargé dans Excel, passez à l’étape 2. Sinon, démarrez le serveur web local et chargez la version test de votre complément :

    • Pour tester votre complément dans Excel, exécutez la commande suivante dans le répertoire racine de votre projet. Cela a pour effet de démarrer le serveur web local (s’il n’est pas déjà en cours d’exécution) et d’ouvrir Excel avec votre complément chargé.

      npm start
      
    • Pour tester votre complément dans Excel sur le web, exécutez la commande suivante dans le répertoire racine de votre projet. Lorsque vous exécutez cette commande, le serveur web local démarre (s’il n’est pas déjà en cours d’exécution).

      npm run start:web
      

      Pour utiliser votre complément, ouvrez un nouveau document dans Excel sur le web, puis chargez la version test de votre complément en suivant les instructions de l’article relatif au chargement de version test des compléments Office dans Office sur le web.

  2. Si le volet Office du complément n’est pas déjà ouvert, sous l’onglet Accueil, sélectionnez Afficher le volet Office.

  3. Si le tableau que vous avez ajouté précédemment dans ce didacticiel est présent dans la feuille de calcul, supprimez-le.

  4. Dans le volet Office, sélectionnez Créer un tableau.

  5. Dans le volet Tâches, sélectionnez Figer l’en-tête.

  6. Faites suffisamment défiler la feuille de calcul vers le bas pour voir que l’en-tête du tableau est toujours visible dans la partie supérieure même lorsque les lignes du haut sont masquées.

Capture d’écran de Figer l’en-tête défini par le didacticiel dans Excel.

Protéger une feuille de calcul

Dans cette section, vous allez rajouter un bouton au ruban. Lorsque l’utilisateur clique sur ce dernier, il exécute une fonction que vous allez définir et qui active/désactive la protection de la feuille de calcul.

Configuration du manifeste pour ajouter un deuxième bouton de ruban

  1. Ouvrez le fichier manifeste ./manifest.xml.

  2. Recherchez l’élément <Control>. Cet élément définit le bouton Afficher le volet des pages sur le ruban Accueil que vous utilisez pour lancer le complément. Nous allons ajouter un deuxième bouton au même groupe sur le ruban Accueil.

    Entre la balise Control de fin (</Control>) et la balise Group de fin (</Group>), ajoutez le balisage suivant.

    <Control xsi:type="Button" id="<!--TODO1: Unique (in manifest) name for button -->">
        <Label resid="<!--TODO2: Button label -->" />
        <Supertip>
          <Title resid="<!-- TODO3: Button tool tip title -->" />
          <Description resid="<!-- TODO4: Button tool tip description -->" />
        </Supertip>
        <Icon>
          <bt:Image size="16" resid="Icon.16x16"/>
          <bt:Image size="32" resid="Icon.32x32"/>
          <bt:Image size="80" resid="Icon.80x80"/>
        </Icon>
        <Action xsi:type="<!-- TODO5: Specify the type of action-->">
          <!-- TODO6: Identify the function.-->
        </Action>
    </Control>
    
  3. Dans le code XML que vous venez d’ajouter au fichier manifeste, remplacez TODO1 par une chaîne qui attribue un ID unique au bouton au sein de ce fichier manifeste. Étant donné que notre bouton va activer ou désactiver la protection de la feuille de calcul, utilisez ToggleProtection. Lorsque vous avez terminé, la balise d’ouverture de l’élément Control doit ressembler à ceci :

    <Control xsi:type="Button" id="ToggleProtection">
    
  4. Les trois TODOs suivants définissent les éléments resid, c’est-à-dire les ID de ressource. Une ressource est une chaîne. Vous allez créer ces trois chaînes lors d’une étape ultérieure. Pour l’instant, vous devez attribuer des ID aux ressources. Le bouton label doit indiquer Toggle Protection, mais l’ID de cette chaîne doit être ProtectionButtonLabel. L’élément Label doit donc ressembler à ceci :

    <Label resid="ProtectionButtonLabel" />
    
  5. L’élément SuperTip définit l’info-bulle du bouton. Le titre de l’info-bulle doit être identique à l’étiquette du bouton, nous utilisons donc le même identifiant de ressource : ProtectionButtonLabel. La description de l’info-bulle est Click to turn protection of the worksheet on and off. Cependant, l’ID doit être ProtectionButtonToolTip. Lorsque vous avez terminé, l’élément SuperTip doit ressembler à ceci :

    <Supertip>
      <Title resid="ProtectionButtonLabel" />
      <Description resid="ProtectionButtonToolTip" />
    </Supertip>
    

    Remarque

    Dans un complément de production, vous n’utiliseriez pas la même icône pour deux boutons différents, mais pour simplifier ce didacticiel, nous allons le faire. Par conséquent, le balisage Icon de notre nouvel élément Control est simplement une copie de l’élément Icon provenant de l’élément Control existant.

  6. Le type de l’élément Action se trouvant à l’intérieur de l’élément Control d’origine qui était déjà présent dans le fichier manifeste est défini sur ShowTaskpane, mais notre nouveau bouton ne va pas ouvrir un volet Office, il va exécuter une fonction personnalisée que vous allez créer à une étape ultérieure. Remplacez donc TODO5 par ExecuteFunction, qui correspond au type d’action des boutons qui déclenchent des fonctions personnalisées. Létiquette d’ouverture de l’élément Action doit ressembler à ceci :

    <Action xsi:type="ExecuteFunction">
    
  7. L’élément Action d’origine possède des éléments enfants qui spécifient un ID de volet Office ainsi qu’une URL de la page qui doit être ouverte dans le volet Office. Toutefois, un élément Action de type ExecuteFunction comporte un élément enfant unique qui nomme la fonction que le contrôle exécute. Vous créerez cette fonction à une étape ultérieure, et la nommerez toggleProtection. Par conséquent, remplacez TODO6 par le balisage suivant :

    <FunctionName>toggleProtection</FunctionName>
    

    Le balisage Control complet doit à présent ressembler à ce qui suit :

    <Control xsi:type="Button" id="ToggleProtection">
        <Label resid="ProtectionButtonLabel" />
        <Supertip>
          <Title resid="ProtectionButtonLabel" />
          <Description resid="ProtectionButtonToolTip" />
        </Supertip>
        <Icon>
          <bt:Image size="16" resid="Icon.16x16"/>
          <bt:Image size="32" resid="Icon.32x32"/>
          <bt:Image size="80" resid="Icon.80x80"/>
        </Icon>
        <Action xsi:type="ExecuteFunction">
          <FunctionName>toggleProtection</FunctionName>
        </Action>
    </Control>
    
  8. Faites défiler vers le bas jusqu’à la section Resources du manifeste.

  9. Ajoutez le balisage suivant en tant qu’enfant de l’élément bt:ShortStrings.

    <bt:String id="ProtectionButtonLabel" DefaultValue="Toggle Worksheet Protection" />
    
  10. Ajoutez le balisage suivant en tant qu’enfant de l’élément bt:LongStrings.

    <bt:String id="ProtectionButtonToolTip" DefaultValue="Click to protect or unprotect the current worksheet." />
    
  11. Enregistrez le fichier.

Création de la fonction qui protège la feuille

  1. Ouvrez le fichier .\commands\commands.js.

  2. Ajoutez la fonction suivante immédiatement après la fonction action(). Nous spécifions un paramètre args pour la fonction et la toute dernière ligne de la fonction appelle args.completed. Il s’agit d’une condition requise pour toutes les commandes de type ExecuteFunction. Elle signale à l’application hôte Office que la fonction est terminée et que l’interface utilisateur est à nouveau réactive.

    async function toggleProtection(args) {
      await Excel.run(async (context) => {
    
        // TODO1: Queue commands to reverse the protection status of the current worksheet.
    
        await context.sync();
      })
      .catch(function (error) {
        console.log("Error: " + error);
        if (error instanceof OfficeExtension.Error) {
          console.log("Debug info: " + JSON.stringify(error.debugInfo));
        }
      });
      args.completed();
    }
    
  3. Ajoutez la ligne suivante à la fin du fichier :

    Office.actions.associate("toggleProtection", toggleProtection);
    
  4. À l’intérieur de la fonction toggleProtection(), remplacez TODO1 par le code suivant. Ce code utilise la propriété de protection de l’objet de feuille de calcul dans un modèle de bouton bascule standard. L’élément TODO2 sera expliqué dans la section suivante.

    const sheet = context.workbook.worksheets.getActiveWorksheet();
    
    // TODO2: Queue command to load the sheet's "protection.protected" property from
    //        the document and re-synchronize the document and task pane.
    
    if (sheet.protection.protected) {
      sheet.protection.unprotect();
    } else {
      sheet.protection.protect();
    }
    

Ajoutez du code pour récupérer des propriétés de document dans les objets de script du volet Office

Dans chaque fonction que vous avez créée dans cette unité jusqu’à présent, vous avez mis en file d’attente les commandes pour écrire dans le document Office. Chaque fonction se terminait par un appel de la méthode context.sync(), qui envoie les commandes en file d’attente au document pour qu’elles soient exécutées. Cependant, le code que vous avez ajouté dans la dernière étape appelle la propriété sheet.protection.protected et c’est une différence significative par rapport aux fonctions antérieures que vous avez écrites, car l’objet sheet est uniquement un objet de proxy qui existe dans le script de votre volet Office. Il ne connaît pas l’état de protection réel du document, donc sa propriété protection.protected ne peut pas contenir une valeur réelle. Tout d’abord, il est nécessaire de récupérer l’état de protection dans le document et l’utiliser pour définir la valeur de sheet.protection.protected. Seulement ensuite, la propriété sheet.protection.protected peut être appelée sans générer d’exception. Ce processus de récupération comporte trois étapes :

  1. Mettez en file d’attente une commande de chargement (c’est-à-dire, fetch) des propriétés que votre code doit lire.
  2. Appelez la méthode sync() de l’objet de contexte pour envoyer la commande mise en file d’attente vers le document pour exécution, et renvoyez les informations demandées.
  3. Étant donné que la méthode sync() est asynchrone, assurez-vous qu’elle est terminée avant que votre code appelle les propriétés qui ont été récupérées.

Ces étapes doivent être effectuées à chaque fois que votre code doit lire (read) des informations provenant du document Office.

  1. À l’intérieur de la fonction toggleProtection(), remplacez TODO2 par le code suivant :

    sheet.load('protection/protected');
    await context.sync();
    

    Remarque

    • Chaque objet Excel possède une méthode load(). Vous spécifiez les propriétés de l’objet que vous voulez lire dans le paramètre en tant que chaîne de noms séparés par des virgules. Dans ce cas, la propriété que vous devez lire est une sous-propriété de la propriété protection. Pour référence la sous-propriété, procédez presque exactement de la même façon que vous le feriez à n’importe quel autre emplacement de votre code, sauf que vous devez utiliser une barre oblique (« / ») au lieu d’un point « . ».
    • Pour vous assurer que la logique bascule, qui indique sheet.protection.protected, ne s’exécute pas tant que le sync n’est pas terminé et que le sheet.protection.protected a reçu la valeur correcte extraite du document, elle doit venir après l’opérateur await .

    Lorsque vous avez terminé, la fonction entière doit ressembler à ce qui suit :

    async function toggleProtection(args) {
        await Excel.run(async (context) => {
          const sheet = context.workbook.worksheets.getActiveWorksheet();
          sheet.load('protection/protected');
    
          await context.sync();
    
          if (sheet.protection.protected) {
              sheet.protection.unprotect();
          } else {
              sheet.protection.protect();
          }
    
          await context.sync();
        })
        .catch(function (error) {
          console.log("Error: " + error);
          if (error instanceof OfficeExtension.Error) {
            console.log("Debug info: " + JSON.stringify(error.debugInfo));
          }
        });
        args.completed();
    }
    
  2. Vérifiez que vous avez enregistré toutes les modifications que vous avez apportées au projet.

Test du complément

  1. Fermez toutes les applications Office, y compris Excel.

  2. Supprimez le cache Office en supprimant le contenu du dossier de cache. Cette opération est nécessaire pour effacer complètement de l’hôte l’ancienne version du complément.

    • Pour Windows : %LOCALAPPDATA%\Microsoft\Office\16.0\Wef\.

    • Pour macOS : ~/Library/Containers/com.Microsoft.OsfWebHost/Data/.

      Remarque

      Si ce dossier n’existe pas, recherchez les dossiers suivants et, le cas échéant, supprimez le contenu du dossier :

      • ~/Library/Containers/com.microsoft.{host}/Data/Library/Caches/Où se trouve {host} Office (par exemple, Excel)
      • ~/Library/Containers/com.microsoft.{host}/Data/Library/Application Support/Microsoft/Office/16.0/Wef/Où se trouve l’{host} Office (par exemple, Excel)
      • com.microsoft.Office365ServiceV2/Data/Caches/com.microsoft.Office365ServiceV2/
  3. Si le serveur web local est déjà en cours d’exécution, arrêtez-le en entrant la commande suivante dans l’invite de commandes.

    npm stop
    
  4. Étant donné que votre fichier manifeste a été mis à jour, vous devez à nouveau charger une version test du complément à l’aide du fichier manifeste mis à jour. Démarrez le serveur web local et chargez indépendamment votre complément :

    • Pour tester votre complément dans Excel, exécutez la commande suivante dans le répertoire racine de votre projet. Cela a pour effet de démarrer le serveur web local (s’il n’est pas déjà en cours d’exécution) et d’ouvrir Excel avec votre complément chargé.

      npm start
      
    • Pour tester votre complément dans Excel sur le web, exécutez la commande suivante dans le répertoire racine de votre projet. Lorsque vous exécutez cette commande, le serveur web local démarre (s’il n’est pas déjà en cours d’exécution).

      npm run start:web
      

      Pour utiliser votre complément, ouvrez un nouveau document dans Excel sur le web, puis chargez la version test de votre complément en suivant les instructions de l’article relatif au chargement de version test des compléments Office dans Office sur le web.

  5. Sous l’onglet Accueil d’Excel, sélectionnez le bouton Activer/désactiver la protection de la feuille de calcul. La plupart des contrôles figurant sur le ruban sont désactivés (et visuellement grisés) comme on peut le voir dans la capture d’écran suivante.

    Capture d’écran du ruban dans Excel avec la protection de feuille de calcul activée.

  6. Sélectionnez une cellule comme vous le feriez si vous vouliez modifier son contenu. Excel affiche un message d’erreur indiquant que la feuille de calcul est protégée.

  7. Sélectionnez le bouton Activer/désactiver la protection de la feuille de calcul à nouveau pour réactiver les contrôles. Vous pouvez alors modifier une nouvelle fois les valeurs de cellule.

Résumé

Dans cet exercice, vous avez appris à figer la ligne d’en-tête du tableau que vous avez créé précédemment. Elle reste ainsi visible lorsque l’utilisateur fait défiler la feuille de calcul vers le bas. Vous avez également découvert comment activer ou désactiver la protection des feuilles de calcul.

Testez vos connaissances

1.

Laquelle de ces options permet d’afficher la feuille de calcul suivante d’un classeur ?

2.

Pour appeler une fonction JavaScript à partir d’un bouton du ruban de l’application Office défini dans le manifeste du complément, vous devez effectuer laquelle des opérations suivantes ?