Solution sans code : affichage des jours depuis la dernière modification d’un élément de liste

par Justin Joyce, LANtek

Remarque

Cet article fait partie d’une collection de billets publiés pendant quatre ans de blog Get the Point pour les utilisateurs finaux SharePoint.

Vue d’ensemble : rapports chronologiques personnalisés sans code

L’un des éléments fonctionnels souvent demandés d’un site SharePoint est un rapport chronologique pour les tâches ou les éléments de liste. En d’autres termes, combien de jours ou de mois se sont écoulés depuis la dernière modification de cet élément de liste ?

À première vue, cela semble être une demande très simple. Après tout, nous avons des dates pour les éléments en cours de création et de modification, nous avons la possibilité de stocker des dates personnalisées lorsque certaines modifications apportées aux éléments ont lieu par le biais de destinataires d’événements. Nous avons des colonnes calculées dans lesquelles nous pouvons inclure des formules de type Excel pour travailler avec nos informations. Cela semble être une proposition assez simple. Nous choisissons un champ de date, créons une colonne calculée, puis faisons une formule du type [DateField] – [Aujourd’hui]. Ah, pas si vite quand même ! Comme le savent tous ceux qui ont tenté cette tâche « simple », essayer d’utiliser quelque chose comme [Aujourd’hui] dans une colonne calculée pose des problèmes. Essayez d’insérer [Aujourd’hui] dans la zone de formule de votre colonne calculée et un message d’erreur semblable à celui-ci s’affiche :

Message d’erreur

Pourquoi ? Eh bien, cela a à voir avec la façon dont les colonnes calculées sont calculées.

Prenons une formule simple comme exemple :

= SI( [Colonne1]< =[Colonne2], « OK », « Pas OK »)

Tout ce que cela dit, c’est que si Column1 est inférieur ou égal à Column2, alors afficher OK, sinon afficher Not OK. Il s’agit d’une formule de base assez classique pour une colonne calculée qui fait une hypothèse de base concernant l’élément de liste qui contient ces colonnes : Les valeurs de Colonne1 et Colonne2 ne pourront jamais changer sans un événement de mise à jour sur l’élément de liste.

En effet, les colonnes calculées ne sont recalculées que lorsque la liste est mise à jour (ou créée), car elles supposent que les informations que vous calculez sont contenues dans l’élément lui-même. Cela crée un problème lorsque vous essayez d’utiliser un élément qui change indépendamment des champs de l’élément, comme la date du jour.

Maintenant, je n’étais pas à la réunion où ils ont décidé que c’est ainsi que les colonnes calculées fonctionneraient, cependant, si je devais faire une supposition éclairée, je supposerais qu’elles fonctionnent de cette façon pour la performance. Imaginez que vous disposiez d’une liste de plusieurs milliers d’éléments, chacun contenant une colonne calculée nécessitant une mise à jour « active ». Cela signifierait qu’un mécanisme, peut-être un travail de minuteur, devrait itérer sur chaque élément contenant cette colonne calculée de temps en temps et mettre à jour sa valeur. Cela peut être extrêmement éprouvant en termes de performances, car avec des déploiements plus importants, ce travail peut constamment s’exécuter et modifier des choses. Ce n’est que ma supposition, mais cela a beaucoup de sens si vous y réfléchissez.

Certaines suggestions de solutions similaires circulent et impliquent d’inciter SharePoint à accepter une valeur Aujourd’hui en créant une colonne nommée Aujourd’hui, puis en l’ajoutant à votre formule, puis en la supprimant. Tout cela est bien beau, mais rappelez-vous ce que j’ai dit à propos de la mise à jour des colonnes calculées. Cette valeur ne changera que lorsque l’élément sera mis à jour, ce qui signifie que vos valeurs seront rapidement incorrectes, en particulier dans le cas d’un calcul de jour.

J’en ai vu d’autres utiliser un JavaScript intelligent pour écrire les valeurs dans la page. Cela fonctionnerait aussi, mais je suis à peu près catégoriquement contre le script client quand cela peut être évité.

Mise en œuvre :

Alors que faire ? Les colonnes calculées sont hors de question pour les fonctions dites « volatiles » comme Aujourd’hui. Il est possible que nous développions un code personnalisé pour nous en occuper, comme une colonne calculée, une tâche de minuterie ou un processus programmé pour venir mettre à jour chaque élément qui nécessite ce calcul. Cela nous ramène au problème de performance que j’ai mentionné dans le dernier paragraphe, et en plus c’est une solution fragile qui serait très spécifique au site/liste/colonne en question. En plus de ces deux préoccupations, vous devriez également aller trouver un gars ringard, comme moi, qui sait coder et le persuader de développer cette solution pour vous. Mais il existe un moyen plus simple !

Si vous disposez des droits pour créer des champs et modifier des pages sur votre site, et que vous avez quelques connaissances sur XSLT et la création de vues, vous pouvez créer un modèle XSL qui peut être inclus dans une vue de liste et calculera fidèlement votre valeur chaque fois que la page est demandée. Ce scénario élimine notre préoccupation concernant les performances et ne nécessite pas de code personnalisé à développer et à déployer via une solution.

Parfait. Alors, comment faisons-nous ?

  1. Créez ou sélectionnez le champ qui servira de source. Il doit s’agir d’un type de date.
  2. Créez notre champ qui servira d’espace réservé pour la valeur en cours de calcul.
  3. Ajoutez ces deux champs à un type de contenu et ajoutez ce type de contenu à une liste.
  4. Créez un affichage de cette liste contenant les colonnes source et espace réservé.
  5. Chargez le modèle XSL dans la bibliothèque Styles.
  6. Définissez la propriété « Lien XSL » pour le composant WebPart Affichage de liste via l’interface utilisateur.
  7. Réussite !

Explorons un exemple de cas d’utilisation et parcourons l’implémentation. Notre client voulait une vue de sa liste principale qui lui indiquerait depuis combien de temps un élément de liste particulier était resté à son status. Cette liste contenait un type de contenu de site personnalisé dérivé du type d’élément et ajouté à la liste. Il y avait déjà un récepteur d’événements en place qui saisissait chaque fois que le champ de status de l’élément de liste était modifié et enregistrait cette date dans une colonne appelée « Date de modification de l’état ». Tout ce câblage n’est pas nécessaire et peut être fait avec N’IMPORTE QUEL champ de date (il se trouve que c’est notre implémentation, mais n’hésitez pas à expérimenter). Le strict minimum dont vous aurez besoin est votre champ de date source et votre champ d’espace réservé pour contenir votre calcul (plus à ce sujet dans le paragraphe suivant) ajoutés à votre liste, bien que je vous suggère d’utiliser les colonnes du site et les types de contenu du site au cas où vous souhaiteriez réutiliser cette solution à d’autres endroits de votre site.

Nous avons donc notre date source que nous pouvons utiliser dans notre calcul par rapport à la date du jour. Nous pouvons maintenant créer une colonne de site personnalisée à utiliser comme conteneur pour notre valeur calculée. Dans ce cas, j’ai choisi d’utiliser une colonne calculée car elle ne pourra pas être modifiée sur les nouveaux formulaires ou éditer les éléments, mais peut être sélectionnée pour être affichée dans les vues car nous ne voulons pas que les utilisateurs entrent des valeurs arbitraires dans cette colonne. Cela pourrait prêter à confusion quant à la raison pour laquelle il n’est pas affiché dans les vues, etc.

Maintenant que nous avons notre colonne de site, nous pouvons l’ajouter à nos types de contenu qui seront utilisés dans notre liste. Ensuite, nous devons créer notre affichage qui sera ensuite personnalisé avec notre XSLT. Veillez à créer un affichage standard contenant votre colonne de date source et votre nouvelle colonne calculée qui servira d’espace réservé pour la valeur calculée.

Nous avons maintenant tout ce dont nous aurons besoin pour prendre en charge notre rapport de vieillissement personnalisé. Il ne reste plus qu’à créer notre modèle XSL, à le télécharger dans la bibliothèque de styles du site et à le lier à notre vue de liste. Le modèle XSL que nous allons utiliser va contenir un balisage normal généré par SharePoint pour générer l’affichage, ainsi que notre propre balisage personnalisé utilisé pour remplacer certaines parties de celui-ci et calculer la valeur souhaitée pour nous.

Pour rendre à César ce qui lui est dû, les modèles XSL pour effectuer les calculs réels que j’utilise pour cette solution ont été gracieusement fournis par « swirch » sur les forums MSDN :
http://social.msdn.microsoft.com/Forums/en-US/sharepointcustomization/thread/aeda905b-9bc6-40c4-bd22-21306c5cb0d2/

Téléchargez la feuille de style XSL (aging.zip) que j’ai compilée ici :
https://OneDrive.live.com/?cid=c262e8e2d59a86d9&permissionsChanged=1&id=C262E8E2D59A86D9!104

En l’ouvrant dans votre éditeur de texte favori, vous verrez beaucoup de balisage SharePoint XSL normal pour le rendu des vues, si vous continuez à faire défiler jusqu’à la ligne 357, vous verrez le début des modèles personnalisés que j’ai ajoutés au balisage, le premier étant le modèle « DateDiff » suivi de « calculate-julian-day » et « FieldRef_printTableCell_EcbAllowed.Days_x0020_At_x0020_Status ». Voici nos trois modèles qui effectueront et afficheront nos calculs dans nos vues. Si vous comptez utiliser des noms de champ différents de ceux spécifiés plus haut dans cet article, vous devrez parcourir ces modèles et remplacer les références aux autres noms. N’oubliez pas que pour cela, vous devrez utiliser le nom INTERNE du champ, et non le nom complet.

Une fois que vous êtes satisfait que le modèle est prêt, accédez à votre bibliothèque de styles et téléchargez-la dans le dossier « Feuilles de style XSL », puis copiez le lien vers le fichier. Cela nous permettra d’y apporter facilement des modifications ultérieurement, ou de l’ajouter à différentes parties du site à notre guise.

Accédez ensuite à votre liste et sélectionnez l’affichage que vous avez créé plus tôt dans cet article. Dans le menu « Actions du site », cliquez sur « Modifier la page ».

Commande Modifier la page du menu Actions du site

Recherchez votre composant WebPart Affichage liste sur la page et ouvrez le menu du composant WebPart en cliquant sur la petite flèche orientée vers le bas dans le coin supérieur droit. Dans ce menu, sélectionnez « Modifier le composant WebPart ».

Commande Modifier le composant WebPart dans le menu WebPart

Le menu du composant WebPart s’ouvre sur le côté droit de la fenêtre de votre navigateur.

Menu Composant WebPart

Cliquez sur le + pour la section « Divers » et localisez la propriété « Lien XSL ».

Propriété Lien XSL du menu Composant WebPart

Collez le lien vers votre fichier XSL dans votre bibliothèque de styles que vous avez copié précédemment (il peut s’agir d’un lien relatif ou absolu).

Lien vers un fichier XLS collé

Cliquez sur « OK » pour enregistrer vos modifications, puis cliquez sur le bouton « Arrêter la modification » dans le ruban « Page » en haut de la page.

Bouton Arrêter la modification sous l’onglet Page

Si tout a été configuré correctement, vous devriez maintenant voir des chiffres dans votre colonne « Nombre de jours restants ».

Colonne Jours avec l’état affichant un nombre

Et enfin, voici à quoi cela ressemblerait avec des données de test de différentes dates :

Balance âgée affichant des données de test

Résumé

Le voilà : un moyen bien formaté, robuste et plus performant de créer un rapport de vieillissement dans SharePoint, avec une implémentation simple sans code. Cela a pas mal d’applications potentielles en dehors du cas d’utilisation que nous avons exploré ici. Un autre scénario courant pour ce type de rapport consiste à l’attacher à une liste de tâches afin de voir en un coup d’œil combien de temps s’est écoulé depuis la création d’une tâche.

Amusez-vous bien !

--Justin

Justin Joyce, LANtek

Commentaires

Étapes manquantes
08/10/2012 03:51
ok j’ai suivi les étapes, mais il doit manquer quelque chose - comment le XSL saura-t-il quelle date utiliser, ou dans quel champ ajouter les jours depuis ? Je déteste quand des étapes sont manquées.

No-Code, d’accord !
30/08/2012 12:12
Je suis d’accord - je ne pense pas que cela compte vraiment comme « pas de code ».
Il est intéressant de noter qu’à cause d’une erreur de SharePoint, j’ai une colonne calculée qui fonctionne en utilisant Aujourd’hui... Je ne sais pas comment ni pourquoi parce que je n’arrive pas à le refaire, mais celui est toujours là et fonctionne.

Formule pour la colonne calculée « Nombre de jours avant le statut » ?
02/05/2012 07:39
Justin – Quelle est la formule que vous avez utilisée pour votre colonne de site calculée « Days At Status » (colonne d’espace réservé) ? Était-ce « =aujourd’hui » ?

SharePoint 2007
2/12/2011 11:29
À l’heure actuelle, je n’ai pas essayé d’appliquer cette solution à SharePoint 2007, mais je suis en train de l’envisager. Malheureusement, aucune propriété XslLink n’est apparue sur le composant WebPart via l’interface utilisateur.

Excellent billet
30/11/2011 09:53
Bonjour,
Excellent article.
J’utilise SharePoint 2007.
Je n’ai pas de section Divers comme indiqué ci-dessus.
Avez-vous des étapes pour configurer SP2007 ?
Merci.

Objet : Solution sans code : affichage des jours depuis la dernière modification d’un élément de liste SharePoint
11/10/2011 08:24
Salut Chris.
Excellente trouvaille !
Je vais jeter un coup d’œil à ce que vous avez posté, espérons-le, plus tard dans la journée et voir si je peux rendre cette solution un peu plus robuste.
Je suis heureux que vous ayez aimé l’article, et je suis très heureux que vous ayez pu trouver une solution au format de date européen. :)
-Justin

Solution pour les formats de date européens
11/10/2011 06:45
Salut encore Justin,
Pour info, j’ai trouvé une solution au problème que j’ai mentionné précédemment sur cette page ;
https://sharepointbydummies.wordpress.com/2011/07/13/possible-work-around-to-date-format-issue-sharepoint-2010/

Formats de date européens
07/10/2011 03:59
Bonjour Justin,
C’est une très bonne solution merci, et c’est exactement le genre de chose que j’ai passé les deux derniers jours à chercher ! Cependant, j’ai un peu de mal avec ça et j’espérais que vous pourriez m’aider.
J’ai légèrement modifié votre code pour calculer le nombre de jours jusqu’à ce que quelque chose se produise, plutôt que depuis, en changeant les variables dans la dernière ligne de la fonction « DateDiff » ;

<xsl :value-of select="$JulianToday - $JulianStartDate"></xsl :value-of>

Cependant, je ne suis capable de calculer correctement la différence que la moitié du temps. Donc, par instance avec cette date (format jj/MM/aaaa) ;

30/12/2011

Il calcule correctement, mais avec cette date (même format)

12/10/2011

Il calcule comme si c’était le 10-déc-2011 plutôt que le 12-oct-2011.
J’ai essayé simplement de changer les positions des valeurs du jour et du mois dans la variable « JulianStartDate », comme ceci ;

<xsl :with-param name="Month » select="substring(ddwrt :FormatDateTime(string($StartDate), 1033, 'yyyyMMdd'),7,2)"/>
<xsl :with-param name="Day » select="substring(ddwrt :FormatDateTime(string($StartDate), 1033, 'yyyyMMdd'),5,2)"/>

Et cela a corrigé le problème avec le deuxième rendez-vous, mais c’était ensuite incorrect pour le premier rendez-vous !
J’ai également essayé de modifier les appels FormatDateTime pour utiliser des LCID européens et diverses modifications du dernier paramètre de FormatDateTime (par exemple ddMMyyyy, MMddyyyyy) avec les ajustements appropriés aux paramètres positionnels de la sous-chaîne sans succès.
J’apprécierais grandement tout conseil que vous pouvez offrir.
Merci,
Chris

No-Code
21/9/2011 04:27
Je ne pense pas que XSL soit considéré comme une solution « no-code », car la compréhension du langage XSL n’est pas pour tout le monde - mais cela n’implique pas de programmation. En plus de ça : Bonne solution, merci !