door Justin Joyce, LANtek
Opmerking
Dit artikel maakt deel uit van een verzameling berichten van de vier jaar lopende blog Get the Point voor eindgebruikers van SharePoint.
Overzicht: Aangepaste, naar ouderdom gerangschikte rapporten zonder code
Een van de meest gevraagde functionele onderdelen van een SharePoint-site is een naar ouderdom gerangschikt rapport voor taken of lijstitems. Met andere woorden, hoeveel dagen of maanden is het geleden dat het lijstitem voor het laatst is gewijzigd?
Op het eerste gezicht lijkt dit een heel eenvoudig verzoek. We hebben tenslotte datums voor items die worden gemaakt en gewijzigd, we hebben de mogelijkheid om aangepaste datums op te slaan wanneer bepaalde wijzigingen aan items plaatsvinden via gebeurtenisontvangers. We hebben berekende kolommen waarin we Excel-achtige formules kunnen opnemen om met onze gegevens te werken. Dit lijkt een vrij eenvoudig voorstel. We kiezen een datumveld, maken een berekende kolom en maken vervolgens een formule in de trant van [DateField] – [Vandaag]. Ah, niet zo snel hoor! Zoals iedereen die deze 'eenvoudige' taak heeft geprobeerd, weet, veroorzaakt het gebruik van iets als [Vandaag] in een berekende kolom problemen. Als u [Vandaag] probeert in te voegen in het formulevak van de berekende kolom, krijgt u een foutbericht dat er ongeveer zo uitziet:
Waarom gebeurt dit? Dit heeft te maken met de manier waarop berekende kolommen worden berekend.
We nemen een eenvoudige formule als voorbeeld:
= ALS( [Kolom1]<=[Kolom2]; "OK"; "Niet OK")
Dit alles zegt dat als Kolom1 kleiner is dan of gelijk is aan Kolom2, er OK wordt weergegeven. Zo niet, dan wordt Niet OK weergegeven. Dit is een vrij normale basisformule voor een berekende kolom, gebaseerd op een aanname over het lijstitem dat deze kolommen bevat: De waarden voor Kolom1 en Kolom2 kunnen nooit wijzigen zonder een gebeurtenis Bijwerken op het lijstitem.
Inderdaad, berekende kolommen worden alleen opnieuw berekend wanneer de lijst wordt bijgewerkt (of gemaakt), omdat wordt aangenomen dat de informatie die u berekent, zich in het item zelf bevindt. Dit zorgt voor problemen als u probeert iets te gebruiken dat verandert en niet afhankelijk is van de velden van het item (bijvoorbeeld de actuele datum).
Ik was er niet bij toen werd besloten dat berekende kolommen op deze manier zouden werken, maar ik vermoed dat deze functie zo werkt omwille van de prestaties. Stel dat u een lijst hebt met duizenden items die allemaal een berekende kolom bevatten die 'live' moet worden bijgewerkt. Dit zou betekenen dat een bepaald mechanisme, zoals een timeropdracht, om de zoveel tijd alle items met die berekende kolom moet verwerken en bijwerken. Dit kan een enorme aanslag zijn op de prestaties, want in grotere implementaties kan dit ertoe leiden dat de opdracht doorlopend wordt uitgevoerd en er steeds dingen wijzigen. Dat is slechts een gok, maar het is best logisch als je erover nadenkt.
Er zijn vergelijkbare oplossingen voorgesteld, waarmee wordt geprobeerd SharePoint de waarde Vandaag wel te laten accepteren door middel een truc door eerst een kolom met de naam Vandaag, deze vervolgens toe te voegen aan de formule en daarna te verwijderen. Dat is allemaal leuk en aardig, maar denk aan wat ik zei over wanneer berekende kolommen worden bijgewerkt. Deze waarde verandert alleen wanneer het item wordt bijgewerkt, wat betekent dat uw waarden al snel onjuist zullen zijn, vooral in het geval van een dagberekening.
Er zijn mensen die een vernuftig stukje JavaScript gebruiken om de waarden naar de pagina te schrijven. Dat werkt, maar ik ben absoluut tegen het gebruik van clientscripts zolang dat niet nodig is.
Implementatie:
Dus wat te doen? Berekende kolommen zijn uitgesloten voor zogenaamde 'vluchtige' functies zoals Today. Het is mogelijk dat we aangepaste code kunnen ontwikkelen om dit voor ons te regelen, zoals een berekende kolom, timertaak of gepland proces om langs te komen en elk afzonderlijk item bij te werken dat deze berekening nodig heeft. Dat brengt ons echter terug bij het prestatieprobleem dat ik in de laatste alinea noemde, en bovendien is het een broze oplossing die zeer specifiek zou zijn voor de site/lijst/kolom in kwestie. Bovenop die twee zorgen, zou je ook een nerdy man moeten gaan zoeken, zoals ikzelf, die weet hoe hij moet coderen en hem moet overtuigen om deze oplossing voor je te ontwikkelen. Maar er is een eenvoudigere manier!
Als u de rechten hebt om velden te maken en pagina’s te bewerken op uw site en iets weet van XSLT en het maken van weergaven, kunt u zelf een XSL-sjabloon in elkaar zetten die kan worden opgenomen in een lijstweergave, en die uw waarde netjes berekent telkens wanneer de pagina wordt opgevraagd. In dit scenario hoeven we ons geen zorgen te maken over de prestaties en hoeft er geen aangepaste code te worden ontwikkeld en geïmplementeerd via een oplossing.
Perfect. Dus hoe doen we dat?
- Maak of selecteer het veld dat fungeert als de bron. Het moet een datumtype zijn.
- Maak een veld dat functioneert als tijdelijke aanduiding voor de waarde die wordt berekend.
- Voeg beide velden toe aan een inhoudstype en voeg het inhoudstype toe aan een lijst.
- Maak een weergave van de lijst die zowel de bronkolom en de tijdelijke kolom bevat.
- Upload de XSL-sjabloon naar de stijlbibliotheek.
- Stel de eigenschap 'XSL-koppeling' in voor het webonderdeel Lijstweergave via de gebruikersinterface.
- Gelukt!
Laten we eens kijken naar een voorbeeld van een use case en de implementatie doornemen. Onze klant wilde een weergave van de hoofdlijst waarin stond hoe lang een bepaald lijstitem zijn status had gehad. Deze lijst bevatte een aangepast site-inhoudstype dat was afgeleid van het type Item en dat was toegevoegd aan de lijst. Er was al een gebeurtenisontvanger aanwezig die elke keer vastlegt wanneer het statusveld op het lijstitem werd gewijzigd en die datum opslaat in een kolom met de naam "Datumstatus gewijzigd". Al deze bedrading is niet vereist en kan worden gedaan met ELK datumveld (toevallig is dit onze implementatie, maar voel je vrij om te experimenteren). Het absolute minimum dat u nodig heeft, is uw brondatumveld en tijdelijke aanduidingsveld om uw berekening (meer hierover in de volgende paragraaf) aan uw lijst toe te voegen, hoewel ik u aanraad sitekolommen en site-inhoudstypen te gebruiken voor het geval u deze oplossing op andere plaatsen op uw site wilt hergebruiken.
We beschikken dus over een brondatum die we kunnen gebruiken voor de berekening met de huidige datum. Nu kunnen we een aangepaste sitekolom maken als container voor de berekende waarde. In dit geval heb ik gekozen voor een berekende kolom, omdat deze niet kan worden gewijzigd in de formulieren voor nieuwe items en voor het bewerken van items, maar wel kan worden geselecteerd voor weergave in de weergaven, omdat we niet willen dat gebruikers willekeurige waarden in deze kolom kunnen invoeren. Het kan verwarrend zijn waarom het niet wordt weergegeven in de weergaven, enz.
Nu we een sitekolom hebben, kunnen we die toevoegen aan de inhoudstypen die we in onze lijst gebruiken. Vervolgens moeten we de weergave maken die we later aanpassen met de XSLT. Maak een standaardweergave met de brondatumkolom en de nieuwe berekende kolom, die functioneert als tijdelijke plaatsaanduiding voor de berekende waarde.
Alles staat nu klaar voor het maken van ons aangepaste, naar ouderdom gerangschikte rapport. We hoeven alleen nog de XSL-sjabloon te maken, te uploaden naar de stijlbibliotheek van de site en te koppelen aan de lijstweergave. De XSL-sjabloon die we gebruiken, bevat de gebruikelijke door SharePoint gegenereerde opmaak voor het genereren van de weergave, en wat van onze eigen opmaak voor het overschrijven van bepaalde delen daarvan en het berekenen van de gewenste waarde.
En ere wie ere toekomt: de XSL-sjablonen voor het uitvoeren van de daadwerkelijke berekeningen die ik gebruik voor deze oplossing zijn gemaakt door "swirch" op de MSDN-forums:
http://social.msdn.microsoft.com/Forums/en-US/sharepointcustomization/thread/aeda905b-9bc6-40c4-bd22-21306c5cb0d2/
Download hier de XSL stylesheet (aging.zip die ik heb samengesteld:
https://OneDrive.live.com/?cid=c262e8e2d59a86d9&permissionsChanged=1&id=C262E8E2D59A86D9!104
Als u dit opent in uw favoriete teksteditor ziet u veel normale SharePoint XSL-markeringen voor het weergeven van de weergaven, als u naar beneden blijft scrollen naar regel 357 ziet u het begin van de aangepaste sjablonen die ik aan de opmaak heb toegevoegd, de eerste is de sjabloon "DateDiff" gevolgd door "calculate-julian-day" en "FieldRef_printTableCell_EcbAllowed.Days_x0020_At_x0020_Status". Dit zijn de drie sjablonen die onze berekeningen maken en weergeven in onze weergaven. Als u andere veldnamen wilt gebruiken dan de namen die eerder in dit artikel zijn opgegeven, moet u eerst deze sjablonen doorlopen en alle verwijzingen naar de andere namen vervangen. Denk eraan dat u hiervoor de INTERNE naam van het veld moet gebruiken en niet de weergavenaam.
Wanneer u tevreden bent met uw sjabloon, uploadt u het naar de stijlbibliotheek in de map 'XSL-opmaakmodellen' en kopieert u de koppeling naar het bestand. Hierdoor kunnen we later eenvoudig wijzigingen aanbrengen of de sjabloon in andere delen van de site hergebruiken.
Ga nu naar uw lijst en selecteer de weergave die u eerder in dit artikel hebt gemaakt. Klik in het menu 'Siteacties' op 'Pagina bewerken'.
Zoek het webonderdeel Lijstweergave op de pagina en open het menu Webonderdeel door te klikken op de kleine pijl-omlaag rechtsboven. Selecteer 'Webonderdeel bewerken' in dit menu.
Hiermee opent u het menu van het webonderdeel aan de rechterkant van het browservenster.
Klik op de + voor de sectie 'Overige' en zoek de eigenschap 'XSL-koppeling'.
Plak de koppeling naar het XSL-bestand in uw stijlbibliotheek die u eerder hebt gekopieerd (dit kan een relatieve of absolute koppeling zijn).
Klik op 'OK' om uw wijzigingen op te slaan en klik vervolgens op de knop 'Stoppen met bewerken' op het lint 'Pagina' boven aan de pagina.
Als alles goed is geconfigureerd, ziet u nu getallen in de kolom 'Dagen op status'.
Uiteindelijk moet het er als volgt uitzien met wat testgegevens van verschillende datums:
Samenvatting:
Alstublieft, een mooi opgemaakte, krachtige en goed presterende manier om een naar ouderdom gerangschikt rapport te maken in SharePoint, compleet met een eenvoudige implementatie zonder code. Dit kan op vele manieren worden toegepast naast de beschreven use case. Zo zou u dit type rapport bijvoorbeeld aan een takenlijst kunnen toevoegen, zodat u in een oogopslag kunt zien hoe lang het geleden is dat een taak is gemaakt.
Veel plezier ermee!
--Justin
Justin Joyce, LANtek
Reacties
Ontbrekende stappen
8-10-2012 3:51 uur
ok, ik heb de stappen gevolgd, maar er ontbreekt vast iets: hoe weet de XSL welke datum moet worden gebruikt of aan welk veld de dagen sindsdien moeten worden toegevoegd? Ik haat het als stappen worden gemist.
No-Code, akkoord!
30-8-2012 12:12 uur
Ik ben het ermee eens - ik denk niet dat dit echt telt als "geen code".
Interessant is dat ik, door een of andere fout in SharePoint, een werkende berekende kolom heb met behulp van Today... ik weet niet zeker hoe of waarom, want ik kan het niet nog een keer laten doen, maar de ene is er nog steeds en werkt.
Formule voor de berekende kolom 'Dagen op status'?
2-5-2012 07:39
Justin: welke formule heb je gebruikt voor je berekende sitekolom 'Dagen op status' (de tijdelijke kolom)? Is dat '= vandaag'?
SharePoint 2007
2-12-2011 11:29
Ik heb nog niet geprobeerd deze oplossing toe te passen op SharePoint 2007, maar ik wil dat zeker doen. Helaas kan ik geen eigenschap XslLink vinden in het webonderdeel via de gebruikersinterface.
Geweldige post
30-11-2011 09:53
Hallo,
Geweldige post.
Ik gebruik SharePoint 2007.
Ik heb geen sectie Diversen zoals hierboven vermeld.
Hebt u stappen voor een SP2007-configuratie?
Dank u wel.
Re: Oplossing zonder code: Weergeven van de dagen sinds een SharePoint-lijstitem voor het laatst is gewijzigd
11-10-2011 08:24
Hoi Chris.
Geweldige vondst!
Ik ga kijken naar wat je hopelijk later vandaag hebt gepost en kijken of ik deze oplossing een beetje robuuster kan maken.
ik ben blij dat je de post leuk vond en ik ben erg blij dat je een oplossing hebt kunnen vinden voor de Europese datumnotatie. :)
-Justin
Oplossing voor Europese datumnotaties
11-10-2011 6:45
Hallo weer Justin,
Ter info, ik heb een oplossing gevonden voor het probleem dat ik eerder op deze pagina noemde;
https://sharepointbydummies.wordpress.com/2011/07/13/possible-work-around-to-date-format-issue-sharepoint-2010/
Europese datumnotaties
7-10-2011 03:59
Hoi Justin,
Dit is echt een goede oplossing, bedankt, en precies het soort dingen waar ik de afgelopen twee dagen naar heb gezocht! Ik heb er alleen wel een probleem mee, en ik hoop dat je me kunt helpen.
Ik heb je code enigszins aangepast om het aantal dagen te berekenen totdat er iets gebeurt, in plaats van sindsdien, door de variabelen in de laatste regel van de functie "DateDiff" om te draaien;
<xsl:value-of select="$JulianToday - $JulianStartDate"></xsl:value-of>
Ik kan het echter maar de helft van de tijd het verschil correct laten berekenen. Dus bijvoorbeeld met deze datum (formaat dd/MM/jjjj);
30/12/2011
Het berekent juist, maar met deze datum (dezelfde notatie)
12/10/2011
De berekening is 10-01-08-2011 in plaats van 12-okt-2011.
Ik heb geprobeerd de posities van de dag- en maandwaarden in de variabele "JulianStartDate" als volgt om te draaien;
<xsl:with-param name="Month" select="substring(ddwrt:FormatDateTime(string($StartDate), 1033, 'yyyyMMdd'),7,2)"/>
<xsl:with-param name="Dag" select="substring(ddwrt:FormatDateTime(string($StartDate), 1033, 'yyyyMMdd'),5,2)"/>
En dit corrigeerde het probleem met de tweede date, maar het was toen onjuist voor de eerste date!
Ik heb ook geprobeerd de FormatDateTime-aanroepen te wijzigen om Europese LCID's te gebruiken en verschillende wijzigingen aan te brengen in de laatste parameter van FormatDateTime (bijv. ddMMyyyy, MMddyyyy) met de juiste aanpassingen aan de positionele parameters van de substring, maar zonder succes.
Als je advies hebt, hoor ik het heel graag.
Bedankt,
Chris
No-Code
21-9-2011 4:27
Ik denk niet dat XSL kwalificeert als een "no-code" -oplossing, omdat het begrijpen van de XSL-taal niet voor iedereen is weggelegd, maar het hoeft niet te programmeren. Daarnaast: Leuke oplossing, bedankt!