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?
Oberflächlich betrachtet scheint dies eine sehr einfache Anfrage zu sein. Schließlich haben wir Datumsangaben für erstellte und geänderte Elemente, und wir haben die Möglichkeit, benutzerdefinierte Datumsangaben zu speichern, wenn bestimmte Änderungen an Elementen über Ereignisempfänger erfolgen. Wir haben berechnete Spalten, in die wir Excel-ähnliche Formeln einbinden können, um mit unseren Informationen zu arbeiten. Das scheint ein ziemlich einfacher Vorschlag zu sein. Wir wählen ein Datumsfeld aus, erstellen eine berechnete Spalte und erstellen dann eine Formel in etwa nach dem Motto [DateField] – [Heute]. Ah, aber nicht so schnell! Wie jeder, der diese "einfache" Aufgabe versucht hat, weiß, verursacht der Versuch, so etwas wie [Heute] in einer berechneten Spalte zu verwenden, Probleme. Wenn Sie versuchen, [Heute] in das Formelfeld Ihrer berechneten Spalte einzufügen, erhalten Sie eine Fehlermeldung wie diese:
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( [Spalte1]<=[Spalte2]; "OK"; "Nicht 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.
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.
Ich war nicht in der Besprechung, in der entschieden wurde, dass berechnete Spalten auf diese Weise funktionieren würden, aber wenn ich eine fundierte Vermutung anstellen müsste, würde ich davon ausgehen, dass sie für die Leistung auf diese Weise funktionieren. Stellen Sie sich vor, Sie hätten eine Liste von mehreren tausend Elementen, von denen jedes eine berechnete Spalte enthält, die eine "Live"-Aktualisierung erfordert. 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 macht ziemlich viel Sinn, wenn man darüber nachdenkt.
Es gibt einige Vorschläge für ähnliche Lösungen, bei denen SharePoint dazu verleitet wird, einen Wert für "Heute" zu akzeptieren, indem zuerst eine Spalte mit dem Namen "Heute" erstellt, dann Ihrer Formel hinzugefügt und dann gelöscht wird. Diese sind alles schön und gut, aber denken Sie daran, was ich gesagt habe, wenn berechnete Spalten aktualisiert werden. Dieser Wert ändert sich nur, wenn das Element aktualisiert wird. Dies bedeutet, dass Ihre Werte bald falsch sein werden, insbesondere im Fall einer Tagesberechnung.
Ich habe andere gesehen, die 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 für sogenannte "volatile" Funktionen wie Today 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 nicht, dass benutzerdefinierter Code entwickelt und über eine Lösung bereitgestellt wird.
Perfekt. Und wir funktioniert das nun?
- Zuerst müssen Sie das Feld erstellen oder auswählen, das als Quelle fungieren soll. Das Feld muss den Datentyp "Datum" aufweisen.
- Dann erstellen Sie das Feld, das als Platzhalter für den berechneten Wert fungieren soll.
- Fügen Sie beide Felder zu einem Inhaltstyp und den Inhaltstyp zu einer Liste hinzu.
- Erstellen Sie eine Ansicht der Liste, die die Quell- und Platzhalterspalten enthält.
- Laden Sie die XSL-Vorlage in die Formatbibliothek hoch.
- Legen Sie die Eigenschaft "XSL-Link" für das Listenansicht-Webpart über die Benutzeroberfläche fest.
- Fertig!
Sehen wir uns einen Beispielanwendungsfall an und gehen die Implementierung durch. 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 jede Änderung dieses Status auf dem Listenelement erfasst und dieses Datum in einer Spalte namens "Datum Statusänderung" speichert. 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 gegen 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 eine berechnete Spalte entschieden, da sie in den neuen oder bearbeiteten Elementformularen nicht geändert werden kann, aber für die Anzeige in den Ansichten ausgewählt werden kann, da wir nicht möchten, dass Benutzer beliebige Werte in diese Spalte eingeben. Es könnte verwirrend sein, warum es nicht in den Ansichten usw. angezeigt wird.
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. Alles, was noch übrig bleibt, ist, unsere XSL-Vorlage zu erstellen, sie in die Stilbibliothek der Website hochzuladen und 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.
Die XSL-Vorlagen für die eigentlichen Berechnungen, die ich für diese Lösung verwende, wurden freundlicherweise von "swirch" in den MSDN-Foren zur Verfügung gestellt:
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 Texteditor öffnen, sehen Sie viel normales SharePoint XSL-Markup zum Rendern der Ansichten, wenn Sie weiter nach unten bis Zeile 357 scrollen, sehen Sie den Anfang der benutzerdefinierten Vorlagen, die ich dem Markup hinzugefügt habe, die erste ist die "DateDiff" -Vorlage, gefolgt von "calculate-julian-day" und "FieldRef_printTableCell_EcbAllowed.Days_x0020_At_x0020_Status". Dies sind unsere drei Vorlagen, die unsere Berechnungen in unseren Ansichten durchführen und anzeigen. Wenn Sie andere Feldnamen als die zuvor in diesem Artikel angegebenen 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 sollten.
Wenn Sie zufrieden sind, dass die Vorlage einsatzbereit ist, navigieren Sie zu Ihrer Stilbibliothek und laden Sie sie in den 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ü "Site-Aktionen" auf "Seite bearbeiten".
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.
Dadurch wird das Menü des Webparts auf der rechten Seite Ihres Browserfensters geöffnet.
Klicken Sie auf das + für den Abschnitt "Verschiedenes" und suchen Sie die Eigenschaft "XSL-Link".
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).
Klicken Sie auf "OK", um Ihre Änderungen zu speichern, und klicken Sie dann auf die Schaltfläche "Bearbeitung beenden" im Menüband "Seite" oben auf der Seite.
Wenn alles korrekt konfiguriert wurde, sollten nun Zahlen in der Spalte "Status der Tage bei" angezeigt werden.
Und so würde das ganze mit einigen Testdaten und verschiedenen Datumsangaben aussehen:
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 häufiges Szenario für diese Art von Bericht ist das Anhängen an eine Aufgabenliste, damit Sie auf einen Blick sehen können, wann seit der Erstellung einer Aufgabe alles her ist.
Viel Spaß!
--Justin
Justin Joyce, LANtek
Kommentare
Fehlende Schritte
08.10.2012 03:51
ok, ich habe die Schritte befolgt, aber es muss etwas fehlen - woher weiß die XSL, welches Datum verwendet werden soll oder in welches Feld die Tage seitdem eingefügt werden sollen? Ich hasse es, wenn Schritte verpasst werden.
Kein Code, einverstanden!
30.08.2012 12:12
Ich stimme zu - ich glaube nicht, dass dies wirklich als "kein Code" gilt.
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 die berechnete Spalte "Tage im Status"?
02.05.2012 07:39
Justin: Was ist die Formel, die Sie für die berechnete Websitespalte "Status der Tage am Status" (Platzhalterspalte) verwendet haben? Handelte es sich um "=Heute"?
SharePoint 2007
12/2/2011 11:29 AM
Derzeit habe ich nicht versucht, diese Lösung auf SharePoint 2007 anzuwenden, aber ich schaue sie mir an. Leider gibt es in der Benutzeroberfläche keine XslLink-Eigenschaft im Webpart.
Toller Beitrag
30.11.2011 9:53 Uhr
Hallo,
Toller Beitrag.
Ich verwende SharePoint 2007.
Den oben erwähnten Abschnitt "Verschiedenes" gibt es bei mir nicht.
Gibt es Schritte für eine SP2007-Konfiguration?
Vielen Dank.
Betreff: Codefreie Lösung: Anzeigen, vor wie vielen Tagen ein SharePoint-Listenelement zuletzt geändert wurde
11.10.2011 08:24
Hallo Chris.
Toller Fund!
Ich werde mir hoffentlich später ansehen, was Sie 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
Hallo nochmal, Justin,
Zu Ihrer Information, 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
07.10.2011 03:59
Hi Justin,
Das ist eine wirklich gute Lösung, danke, und genau die Art von Dingen, nach denen ich die letzten zwei Tage gesucht habe! Allerdings habe ich ein kleines Problem damit und ich hatte gehofft, dass Sie mir helfen können.
Ich habe Ihren Code leicht geändert, um die Anzahl der Tage zu berechnen, bis etwas passiert, und nicht seitdem, indem ich die Variablen in der letzten Zeile der Funktion "DateDiff" vertausche;
<xsl:value-of select="$JulianToday - $JulianStartDate"></xsl:value-of>
Allerdings bin ich nur in der Lage, die Differenz in der Hälfte der Zeit richtig zu berechnen. Also zum Instance mit diesem Datum (Format TT/MM/JJJJ);
30/12/2011
Es wird richtig berechnet, aber mit diesem Datum (gleiches Format)
12/10/2011
Die Berechnung erfolgt so, als ob der 10. Dezember 2011 und nicht der 12. Oktober 2011 wäre.
Ich habe versucht, einfach die Positionen der Tages- und Monatswerte in der Variablen "JulianStartDate" wie folgt zu vertauschen.
<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 damit war das Problem mit dem zweiten Date behoben, allerdings war es dann beim ersten Date falsch!
Ich habe auch versucht, die FormatDateTime-Aufrufe zu ändern, um europäische LCIDs zu verwenden, und verschiedene Änderungen am letzten Parameter von FormatDateTime (z. B. TTMMjjjj, MMddyjjj) mit den entsprechenden Anpassungen an den Positionsparametern der Teilzeichenfolge ohne Erfolg.
Ich würde mich sehr über jeden Rat freuen, den Sie geben können.
Vielen Dank
Chris
No-Code
21.09.2011 04:27
Ich glaube nicht, dass XSL als "No-Code"-Lösung gilt, da das Verständnis der XSL-Sprache nicht jedermanns Sache ist - aber es beinhaltet keine Programmierung. Davon abgesehen: Gute Lösung, vielen Dank!