Lösung ohne Code: Anzeigen der Tage seit der letzten Änderung eines Listenelements

von Jonas Joyce, LANtek

Hinweis

Dieser Artikel ist Teil einer Sammlung von Beiträgen aus vier Jahren des Blogs Get the Point für SharePoint-Endbenutzer.

Übersicht: Benutzerdefinierte codefreie Alterslisten

Eine der häufig angeforderten funktionalen Elemente einer SharePoint-Website ist eine Altersliste für Vorgänge oder Listenelemente. Mit anderen Worten, wie viele Tage/Monate ist es her, seit der dieses Listenelement zuletzt geändert wurde?

Auf den ersten Blick scheint dies eine sehr einfache Anforderung zu sein. Schließlich verfügen wir über Datumsangaben für Elemente, die erstellt und geändert werden, und wir haben die Möglichkeit, benutzerdefinierte Datumsangaben zu speichern, wenn bestimmte Änderungen an Elementen über Ereignisempfänger erfolgen. Wir haben berechnete Spalten, in denen wir Excel-ähnliche Formeln einschließen können, um mit unseren Informationen zu arbeiten. Dies scheint ein ziemlich unkompliziertes Angebot zu sein. Wir wählen ein Datumsfeld aus, erstellen eine berechnete Spalte und führen dann eine Formel nach den Zeilen [DateField] – [Heute] durch. Ah, aber nicht so schnell! Wie jeder, der diese "einfache" Aufgabe versucht hat, weiß, verursacht der Versuch, etwas wie [Heute] in einer berechneten Spalte zu verwenden, Probleme. Versuchen Sie, [Heute] in das Formelfeld Ihrer berechneten Spalte einzufügen, erhalten Sie eine Fehlermeldung wie die folgende:

Fehlermeldung

Was ist der Grund hierfür? Nun, es hat mit der Art und Weise zu tun, wie berechnete Spalten berechnet werden.

Nehmen wir eine einfache Formel als Beispiel:

= IF( [Column1]<=[Column2], "OK", "Not OK")

Dies bedeutet lediglich Folgendes: Wenn "Spalte1" kleiner oder gleich "Spalte2" ist, dann wird "OK" angezeigt, andernfalls wird "Nicht OK" angezeigt. Das ist eine ziemlich normale, einfache Formel für eine berechnete Spalte mit einer grundlegenden Annahme über das Listenelement, das diese Spalten enthält: Die Werte für "Spalte1" und "Spalte2" können sich nie ohne ein Aktualisierungsereignis für das Listenelement ändern.

Das ist richtig, berechnete Spalten werden nur neu berechnet, wenn die Liste aktualisiert (oder erstellt) wird, da sie davon ausgehen, dass die von Ihnen berechneten Informationen im Element selbst enthalten sind. Dies führt zu einem Problem, wenn Sie versuchen, etwas zu verwenden, das sich unabhängig von den Feldern des Elements ändert, z. B. das heutige Datum.

Jetzt war ich nicht in der Besprechung, in der sie entschieden haben, dass dies die Art und Weise ist, wie berechnete Spalten funktionieren würden, aber wenn ich eine fundierte Vermutung machen müsste, würde ich davon ausgehen, dass sie auf diese Weise für die Leistung funktionieren. Stellen Sie sich vor, Sie hätten eine Liste mit mehreren tausend Elementen, von denen jedes eine berechnete Spalte enthielt, für die ein "Liveupdate" erforderlich war. Das würde bedeuten, dass ein Mechanismus, z. B. ein Zeitgeberauftrag, jedes Element mit einer berechneten Spalte regelmäßig durchlaufen und den Wert aktualisieren müsste. Das könnte im Hinblick auf die Leistung kaum zu bewältigen sein, da dieser Auftrag bei größeren Bereitstellungen möglicherweise ununterbrochen ausgeführt werden und Elemente ändern würde. Das ist nur meine Vermutung, aber es ist ziemlich sinnvoll, wenn man darüber nachdenkt.

Es gibt einige Vorschläge für ähnliche Lösungen, die darin bestehen, SharePoint dazu zu verleiten, einen Heute-Wert zu akzeptieren, indem zuerst eine Spalte mit dem Namen Heute erstellt, dann zu Ihrer Formel hinzugefügt und dann gelöscht wird. Diese sind alle gut und gut, aber denken Sie daran, was ich darüber gesagt habe, wenn berechnete Spalten aktualisiert werden. Dieser Wert ändert sich nur, wenn das Element aktualisiert wird, was bedeutet, dass Ihre Werte bald falsch sind, insbesondere bei einer Tagesberechnung.

Ich habe gesehen, wie andere benutzer cleveres JavaScript verwenden, um die Werte auf die Seite zu schreiben. Dies würde auch funktionieren, aber ich bin prinzipiell gegen Clientskript, wenn es vermieden werden kann.

Implementierung:

Was ist also zu tun? Berechnete Spalten kommen bei so genannten "flüchtigen" Funktionen wie Heute nicht in Frage. Wir könnten benutzerdefinierten Code entwickeln, der diese Aufgabe für uns übernimmt, z. B. eine berechnete Spalte, einen Zeitgeberauftrag oder einen geplanten Prozess, der regelmäßig jedes einzelne Element aktualisiert, für das diese Berechnung vorgenommen werden muss. Damit kommen wir jedoch wieder zu dem im letzten Absatz erwähnten Leistungsproblem zurück, und darüber hinaus ist es eine unelegante Lösung, die hochgradig spezifisch für die jeweilige Website/Liste/Spalte wäre. Zusätzlich zu diesen beiden Bedenken müssten Sie auch noch einen Computerfreak wie mich finden, der sich mit derartigem Code auskennt, und ihn überreden, diese Lösung für Sie zu programmieren. Aber es gibt eine einfachere Möglichkeit!

Wenn Sie zum Erstellen von Feldern und zum Bearbeiten von Seiten auf Ihrer Website berechtigt sind und über grundlegende Kenntnisse von XSLT und vom Erstellen von Ansichten verfügen, können Sie eine XSL-Vorlage erstellen, die in eine Listenansicht eingefügt werden kann und zuverlässig jedes Mal, wenn die Seite angefordert wird, den erforderlichen Wert berechnet. Dieses Szenario beseitigt unsere Bedenken hinsichtlich der Leistung und erfordert keinen benutzerdefinierten Code, der über eine Lösung entwickelt und bereitgestellt wird.

Perfekt. Und wir funktioniert das nun?

  1. Zuerst müssen Sie das Feld erstellen oder auswählen, das als Quelle fungieren soll. Das Feld muss den Datentyp "Datum" aufweisen.
  2. Dann erstellen Sie das Feld, das als Platzhalter für den berechneten Wert fungieren soll.
  3. Fügen Sie beide Felder zu einem Inhaltstyp und den Inhaltstyp zu einer Liste hinzu.
  4. Erstellen Sie eine Ansicht der Liste, die die Quell- und Platzhalterspalten enthält.
  5. Laden Sie die XSL-Vorlage in die Formatbibliothek hoch.
  6. Legen Sie die Eigenschaft "XSL Link" für das Listenansicht-Webpart über die Benutzeroberfläche fest.
  7. Fertig!

Sehen wir uns einen Beispielanwendungsfall an und durchlaufen die Implementierung. Unser Kunde benötigt eine Ansicht seiner Hauptliste, die Informationen darüber liefert, wie lange ein bestimmtes Listenelement seinen aktuellen Status aufweist. Diese Liste enthält einen benutzerdefinierten Website-Inhaltstyp, der vom Elementtyp abgeleitet und der Liste hinzugefügt wird. Es war bereits ein Ereignisempfänger vorhanden, der jedes Mal erfasst, wenn status Feld im Listenelement geändert und in einer Spalte namens "Datumsstatus geändert" gespeichert wurde. Alle diese Verknüpfungen sind nicht erforderlich, unsere Lösung funktioniert mit JEDEM Datumsfeld (der vorliegende Fall ist lediglich ein Beispiel für eine Implementierung – Sie können beliebig experimentieren). Sie müssen als absolutes Minimum das Quelldatumsfeld und das Platzhalterfeld zum Speichern der Berechnung (weitere Informationen hierzu erhalten Sie im nächsten Absatz) zu Ihrer Liste hinzufügen, allerdings empfiehlt es sich, Websitespalten und Website-Inhaltstypen zu verwenden, falls Sie diese Lösung an anderer Stelle auf Ihrer Website wiederverwenden möchten.

Wir haben also unser Quelldatum, das wir in unserer Berechnung für das heutige Datum verwenden können. Jetzt können wir eine benutzerdefinierte Websitespalte erstellen, die als Container für unseren berechneten Wert verwendet werden soll. In diesem Fall habe ich mich für die Verwendung einer berechneten Spalte entschieden, da sie nicht in den neuen oder bearbeitungsbasierten Elementformularen geändert werden kann, sondern für die Anzeige in den Ansichten ausgewählt werden kann, da benutzer keine beliebigen Werte in diese Spalte eingeben möchten. Es könnte verwirrend sein, warum es nicht in den Ansichten angezeigt wird usw.

Nachdem wir nun die Websitespalte erstellt haben, können wir sie zu den Inhaltstypen hinzufügen, die in der Liste verwendet werden. Als Nächstes erstellen wir unsere Ansicht, die später mit XSLT angepasst wird. Stellen Sie sicher, dass Sie eine Standardansicht erstellen, die die Quelldatumsspalte und die neue berechnete Spalte enthält, die als Platzhalter für den berechneten Wert fungiert.

Wir haben nun alle Elemente vorbereitet, die wir zur Unterstützung unserer benutzerdefinierten Altersliste benötigen. Es bleibt nur noch, unsere XSL-Vorlage zu erstellen, sie in die Formatbibliothek der Website hochzuladen und sie mit unserer Listenansicht zu verknüpfen. Die XSL-Vorlage, die wir verwenden werden, soll einige normale, von SharePoint generierte Markups zum Generieren der Ansicht enthalten sowie unser eigenes benutzerdefiniertes Markup, das bestimmte Teile überschreibt und den gewünschten Wert berechnet.

Wenn Guthaben fällig ist, wurden die XSL-Vorlagen für die eigentlichen Berechnungen, die ich für diese Lösung verwende, gnädig von "swirch" in den MSDN-Foren bereitgestellt:
http://social.msdn.microsoft.com/Forums/en-US/sharepointcustomization/thread/aeda905b-9bc6-40c4-bd22-21306c5cb0d2/

Laden Sie das XSL-Stylesheet (aging.zip) herunter, das ich hier zusammengestellt habe:
https://OneDrive.live.com/?cid=c262e8e2d59a86d9&permissionsChanged=1&id=C262E8E2D59A86D9!104

Wenn Sie dies in Ihrem bevorzugten Text-Editor öffnen, sehen Sie viel normales SharePoint XSL-Markup zum Rendern der Ansichten. Wenn Sie weiter zur Zeile 357 scrollen, sehen Sie den Anfang der benutzerdefinierten Vorlagen, die ich dem Markup hinzugefügt habe, wobei die erste die Vorlage "DateDiff" gefolgt von "calculate-julian-day" und "FieldRef_printTableCell_EcbAllowed.Days_x0020_At_x0020_Status" ist. Dies sind unsere drei Vorlagen, die unsere Berechnungen in unseren Ansichten erstellen und anzeigen. Wenn Sie andere Feldnamen als weiter oben in diesem Artikel angegeben verwenden, müssen Sie diese Vorlagen durchgehen und alle Verweise auf die anderen Namen ersetzen. Denken Sie daran, dass Sie hierfür den INTERNEN Namen des Felds und nicht den Anzeigenamen verwenden möchten.

Sobald Sie zufrieden sind, dass die Vorlage einsatzbereit ist, navigieren Sie zu Ihrer Formatbibliothek, und laden Sie sie im Ordner "XSL Stylesheets" hoch, und kopieren Sie dann den Link zur Datei. Auf diese Weise können Sie zu einem späteren Zeitpunkt mühelos Änderungen vornehmen oder die Vorlage bei Bedarf zu anderen Teilen der Website hinzufügen.

Wechseln Sie als Nächstes zu Ihrer Liste, und wählen Sie die Ansicht aus, die Sie weiter oben in diesem Artikel erstellt haben. Klicken Sie im Menü "Websiteaktionen" auf "Seite bearbeiten".

Befehl 'Seite bearbeiten' im Menü 'Websiteaktionen'

Suchen Sie das Listenansicht-Webpart auf der Seite, und öffnen Sie das Menü "Webpart", indem Sie auf den kleinen nach unten gerichteten Pfeil in der oberen rechten Ecke klicken. Wählen Sie in diesem Menü "Webpart bearbeiten" aus.

Befehl 'Webpart bearbeiten' im Menü 'Webpart'

Dadurch wird das Menü des Webparts auf der rechten Seite ihres Browserfensters geöffnet.

Webpartmenü

Klicken Sie auf das + für den Abschnitt "Sonstiges", und suchen Sie die Eigenschaft "XSL-Link".

Eigenschaft 'XSL-Verknüpfung' im Menü 'Webpart'

Fügen Sie die weiter oben kopierte Verknüpfung zu Ihrer XSL-Datei in der Formatbibliothek ein (dies kann eine relative oder absolute Verknüpfung sein).

Eingefügte XSL-Dateiverknüpfung

Klicken Sie auf "OK", um Ihre Änderungen zu speichern, und klicken Sie dann oben auf der Seite im Menüband "Seite" auf die Schaltfläche "Bearbeitung beenden".

Schaltfläche 'Bearbeitung beenden' auf der Registerkarte 'Seite'

Wenn alles ordnungsgemäß konfiguriert wurde, sollten nun Zahlen in der Spalte "Days At Status" angezeigt werden.

Spalte 'Days At Status' mit angezeigter Zahl

Und so würde das ganze mit einigen Testdaten und verschiedenen Datumsangaben aussehen:

Ablaufbericht mit angezeigten Testdaten

Zusammenfassung:

Hier ist sie: eine ordentlich formatierte, robuste und leistungsstärkere Möglichkeit zum Erstellen einer Altersliste in SharePoint, eine vollständige und einfache codefreie Implementierung. Es gibt eine ganze Reihe von Anwendungsmöglichkeiten neben dem einen Anwendungsfall, den wir hier untersucht haben. Ein weiteres gängiges Szenario für diese Art von Bericht ist das Anfügen an eine Aufgabenliste, damit Sie auf einen Blick sehen können, wie lange es seit der Erstellung einer Aufgabe dauert.

Viel Spaß!

--Justin

Justin Joyce, LANtek

Kommentare

Fehlende Schritte
8.10.2012 03:51 Uhr
Ok Ich habe die Schritte ausgeführt, aber es muss etwas fehlen - wie wird die XSL wissen, welches Datum verwendet werden soll, oder in welchem Feld die Tage seitdem hinzugefügt werden sollen? Hassen Sie es, wenn Schritte verpasst werden.

No-Code, einverstanden!
30.08.2012 12:12 Uhr
Ich stimme zu - Ich glaube nicht, dass dies wirklich als "kein Code" zählt.
Interessanterweise habe ich durch irgendeinen Fehler von SharePoint eine funktionierende berechnete Spalte, die den Wert "Heute" verwendet... Ich bin nicht sicher, wie oder warum, denn es lässt sich in SharePoint nicht reproduzieren, aber die eine ist weiterhin vorhanden und funktioniert.

Formel für berechnete Spalte "Days At Status"?
02.05.2012 07:39 Uhr
Justin: Welche Formel haben Sie für die berechnete Websitespalte "Days At Status" (Platzhalterspalte) verwendet? Handelte es sich um "=Heute"?

SharePoint 2007
2.12.2011 11:29 Uhr
Derzeit habe ich nicht versucht, diese Lösung auf SharePoint 2007 anzuwenden, aber ich bin dabei. Leider gibt es in der Benutzeroberfläche keine XslLink-Eigenschaft im Webpart.

Großer Beitrag
30.11.2011 09:53 Uhr
Hallo,
Großer Beitrag.
Ich verwende SharePoint 2007.
Den oben erwähnten Abschnitt "Verschiedenes" gibt es bei mir nicht.
Haben Sie Schritte für eine SP2007-Konfiguration?
Vielen Dank.

Re: Lösung ohne Code: Anzeigen der Tage seit der letzten Änderung eines SharePoint-Listenelements
11.10.2011 08:24 Uhr
Hallo Chris.
tolle Suche!
Ich werde einen Blick auf das werfen, was Sie hoffentlich später am heutigen Tag gepostet haben und sehen, ob ich diese Lösung etwas robuster machen kann.
Ich freue mich, dass Ihnen der Beitrag gefallen hat und ich bin sehr froh, dass Sie eine Lösung für das europäische Datumsformat finden konnten. :)
-Justin

Lösung für europäische Datumsformate
11.10.2011 06:45 Uhr
Hallo Nochmals Justin,
FYI, ich habe eine Lösung für das Problem gefunden, das ich zuvor auf dieser Seite erwähnt habe;
https://sharepointbydummies.wordpress.com/2011/07/13/possible-work-around-to-date-format-issue-sharepoint-2010/

Europäische Datumsformate
7.10.2011 03.59 Uhr
Hallo Justin,
Dies ist eine wirklich gute Lösung, danke, und genau die Art von Dingen, die ich in den letzten zwei Tagen gesucht habe! Aber ich habe ein bisschen ein Problem damit und ich hoffte, dass Sie mir helfen können.
Ich habe Ihren Code leicht geändert, um die Anzahl der Tage zu berechnen, bis etwas passiert, anstatt seitdem, indem die Variablen in der letzten Zeile der "DateDiff"-Funktion gewechselt wurden;

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

Ich kann es jedoch nur zur Hälfte der Zeit dazu bringen, den Unterschied richtig einzugrenzen. Also für instance mit diesem Datum (Format tt/MM/jjjj);

30/12/2011

Es wird ordnungsgemäß berechnet, aber mit diesem Datum (gleiches Format)

12/10/2011

Es wird so berechnet, als ob 10-Dec-2011 und nicht 12-Oct-2011.
Ich habe versucht, einfach die Positionen der Tages- und Monatswerte in der Variablen "JulianStartDate" wie folgt zu wechseln.

<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)"/>

Und dies hat das Problem mit dem zweiten Datum behoben, aber es war dann falsch für das erste Datum!
Ich habe auch versucht, die FormatDateTime-Aufrufe so zu ändern, dass europäische LCIDs verwendet werden, und verschiedene Änderungen am letzten Parameter von FormatDateTime (z. B. ddMMyyyyy, MMddyyyyy) mit den entsprechenden Anpassungen an den Positionsparametern der Teilzeichenfolge ohne Erfolg.
Ich würde mich sehr über jeden Rat freuen, den Sie anbieten können.
Vielen Dank
Chris

No-Code
21.09.2011 04.27 Uhr
Ich glaube nicht, dass XSL als "No-Code"-Lösung qualifiziert ist, da das Verstehen der XSL-Sprache nicht jedermanns Sache ist - aber es beinhaltet nicht programmierung. Davon abgesehen: Gute Lösung, vielen Dank!