av Justin Joyce, LANtek
Obs
Den här artikeln är en del av en samling inlägg från fyra år med Get the Point-bloggen för SharePoint-slutanvändare.
Översikt: Anpassade åldringsrapporter utan kod
En av de funktioner som ofta efterfrågas på en SharePoint-webbplats är en åldersfördelningsrapport för antingen uppgifter eller listobjekt. Med andra ord, hur många dagar/månader har gått sedan det här listobjektet senast ändrades?
På ytan verkar detta vara en mycket enkel begäran. När allt kommer omkring har vi datum för objekt som skapas och ändras, vi har möjlighet att lagra anpassade datum när vissa ändringar av objekt sker via händelsemottagare. Vi har beräknade kolumner där vi kan ta med Excel-liknande formler för att arbeta med vår information. Detta verkar vara ett ganska enkelt förslag. Vi väljer ett datumfält, skapar en beräknad kolumn och gör sedan en formel i stil med [Datumfält] – [I dag]. Ah, inte så snabbt dock! Som alla som har försökt sig på den här "enkla" uppgiften vet orsakar det problem att försöka använda något som [Idag] i en beräknad kolumn. Om du försöker infoga [Idag] i formelrutan för den beräknade kolumnen får du ett felmeddelande som ser ut ungefär så här:
Varför det? Jo, det har att göra med sättet som beräknade kolumner beräknas på.
Låt oss ta en enkel formel som exempel:
= OM( [Kolumn1]<=[Kolumn2];"OK";"Inte OK")
Allt detta säger är att om Kolumn1 är mindre än eller lika med Kolumn2, visa OK, annars visas Inte OK. Det här är en ganska vanlig grundläggande formel för en beräknad kolumn och den gör ett grundläggande antagande om listobjektet som innehåller dessa kolumner: Värdena för Kolumn1 och Kolumn2 kan aldrig ändras utan en Update-händelse för listobjektet.
Det stämmer, beräknade kolumner beräknas bara om när listan uppdateras (eller skapas) eftersom de förutsätter att informationen du beräknar finns i själva objektet. Detta skapar problem när du försöker använda något som ändras oberoende av objektets fält, till exempel dagens datum.
Jag var inte med på mötet där de beslutade att de beräknade kolumnerna skulle fungera så här, men om jag var tvungen att göra en kvalificerad gissning skulle jag anta att de fungerar så här för prestanda. Tänk dig att du har en lista med flera tusen objekt, som vart och ett innehöll en beräknad kolumn som behövde en "live"-uppdatering. Det skulle innebära att någon mekanism, kanske ett tidsinställt jobb, skulle behöva iterera genom varje objekt som innehåller den beräknade kolumnen då och då och uppdatera dess värde. Detta kan vara extremt belastningsmässigt när det gäller prestanda eftersom jobbet kan vara igång och ändra saker i större distributioner. Det är bara min gissning, men det är ganska vettigt om du tänker på det.
Det finns några förslag på liknande lösningar som går ut på att lura SharePoint att acceptera värdet I dag genom att först skapa en kolumn med namnet I dag, sedan lägga till den i formeln och sedan ta bort den. Allt detta är bra, men kom ihåg vad jag sa om när beräknade kolumner uppdateras. Det här värdet ändras bara när objektet uppdateras, vilket innebär att värdena snart blir felaktiga, särskilt om det rör sig om en dagsberäkning.
Jag har sett andra använda smart JavaScript för att skriva värdena till sidan. Detta skulle också fungera, men jag är ganska kategoriskt emot klientskript när det kan undvikas.
Genomförande:
Så vad ska man göra? Beräknade kolumner är uteslutna för så kallade "beständiga" funktioner som Idag. Det är möjligt att vi kan utveckla någon anpassad kod för att ta hand om detta åt oss, till exempel en beräknad kolumn, ett tidsinställt jobb eller en schemalagd process som kommer och uppdaterar varje enskilt objekt som behöver göras den här beräkningen. Det för oss dock tillbaka till problemet med prestanda som jag nämnde i förra stycket, och dessutom är det en bräcklig lösning som skulle vara mycket specifik för webbplatsen/listan/kolumnen i fråga. Utöver dessa två problem måste du också hitta en nördig kille, som jag själv, som vet hur man kodar och övertalar honom att utveckla den här lösningen åt dig. Men det finns ett enklare sätt!
Om du har behörighet att skapa fält och redigera sidor på din webbplats, och har lite kunskap om XSLT och hur du skapar vyer, kan du sätta ihop en XSL-mall som kan inkluderas i en listvy och som troget beräknar ditt värde varje gång sidan begärs. Det här scenariot tar bort vår oro över prestanda och kräver inte att anpassad kod utvecklas och distribueras via en lösning.
Perfekt! Så hur gör vi det?
- Skapa eller välj det fält som ska fungera som vår källa. Det måste vara av datumtyp.
- Skapa fältet som ska fungera som platshållare för det värde som beräknas.
- Lägg till båda fälten i en innehållstyp och lägg till innehållstypen i en lista.
- Skapa en vy av listan som innehåller både käll- och platshållarkolumnerna.
- Ladda upp XSL-mallen till formatbiblioteket.
- Ange egenskapen "XSL-länk" för listvywebbdelen via användargränssnittet.
- Klart!
Nu ska vi utforska ett exempel på ett användningsfall och gå igenom implementeringen. Vår kund ville ha en vy över huvudlistan som kunde visa hur länge ett visst listobjekt hade legat på dess status. Den här listan innehöll en anpassad webbplatsinnehållstyp som härletts från objekttypen och lagts till i listan. Det fanns redan en händelsemottagare på plats som registrerar varje gång statusfältet i listobjektet ändras och sparar det datumet i en kolumn med namnet "Datumstatus ändrad". All denna kabeldragning är inte obligatorisk och kan göras med ALLA datumfält (det råkar vara så att detta är vår implementering men experimentera gärna). Det minsta du behöver är ditt källdatumfält och platshållarfält för att hålla din beräkning (mer om detta i nästa stycke) tillagd i din lista, även om jag föreslår att du använder webbplatskolumner och webbplatsinnehållstyper om du vill återanvända den här lösningen på andra platser på din webbplats.
Så vi har vårt källdatum som vi kan använda i beräkningen mot dagens datum. Nu kan vi skapa en anpassad webbplatskolumn och använda som behållare för vårt beräknade värde. I det här fallet valde jag att använda en beräknad kolumn eftersom den inte kommer att kunna ändras i formuläret för nya eller redigera objekt, men kan väljas för visning i vyerna eftersom vi inte vill att användare anger godtyckliga värden i den här kolumnen. Det kan vara förvirrande varför det inte visas i vyerna, etc.
Nu när vi har vår webbplatskolumn kan vi lägga till den i våra innehållstyper som kommer att användas i vår lista. Därefter måste vi skapa vår vy som senare kommer att anpassas med vår XSLT. Kontrollera att du skapar en standardvy som innehåller datumkällans kolumn och den nya beräknade kolumnen som ska fungera som platshållare för det beräknade värdet.
Vi har nu allt på plats som vi behöver för att stödja vår anpassade åldersfördelningsrapport. Allt som återstår är att skapa vår XSL-mall, ladda upp den till webbplatsens stilbibliotek och länka den till vår listvy. XSL-mallen som vi kommer att använda kommer att innehålla en del normal SharePoint-genererad markering för att generera vyn samt vår egen anpassade markering som används för att åsidosätta vissa delar av detta och beräkna vårt önskade värde åt oss.
XSL-mallarna för att göra de faktiska beräkningarna jag använder för den här lösningen tillhandahölls nådigt av "swirch" på MSDN-forumen:
http://social.msdn.microsoft.com/Forums/en-US/sharepointcustomization/thread/aeda905b-9bc6-40c4-bd22-21306c5cb0d2/
Ladda ner XSL-stilmallen (aging.zip) som jag har satt ihop här:
https://OneDrive.live.com/?cid=c262e8e2d59a86d9&permissionsChanged=1&id=C262E8E2D59A86D9!104
Om du öppnar detta i din favorittextredigerare kommer du att se massor av normal SharePoint XSL-markering för att återge vyerna, om du fortsätter att rulla ner till rad 357 kommer du att se början av de anpassade mallarna som jag lade till i markeringen, den första är mallen "DateDiff" följt av "calculate-julian-day" och "FieldRef_printTableCell_EcbAllowed.Days_x0020_At_x0020_Status". Det här är våra tre mallar som kommer att göra och visa våra beräkningar i våra vyer. Om du kommer att använda andra fältnamn än de som angavs tidigare i den här artikeln måste du gå igenom mallarna och ersätta alla referenser till de andra namnen. Kom ihåg att du bör använda det INTERNA namnet på fältet, inte visningsnamnet.
När du är nöjd med att mallen är redo att användas, navigera till ditt stilbibliotek och ladda upp den under mappen "XSL Style Sheets" och kopiera sedan ner länken till filen. Det gör att vi enkelt kan göra ändringar i den senare eller lägga till den på olika delar av webbplatsen som vi vill.
Gå sedan till listan och välj den vy som du skapade tidigare i den här artikeln. Från menyn "Webbplatsåtgärder" klickar du på "Redigera sida".
Leta reda på listvywebbdelen på sidan och öppna menyn Webbdel genom att klicka på den lilla nedåtriktade pilen i det övre högra hörnet. Välj "Redigera webbdel" på den här menyn.
Då öppnas webbdelens meny till höger i webbläsarfönstret.
Klicka på + för avsnittet "Diverse" och leta reda på egenskapen "XSL Link".
Klistra in länken till din XSL-fil i ditt formatbibliotek som du kopierade ner tidigare (detta kan vara en relativ eller absolut länk).
Klicka på "OK" för att spara dina ändringar och klicka sedan på knappen "Sluta redigera" i menyfliksområdet "Sida" högst upp på sidan.
Om allt har konfigurerats korrekt bör du nu se siffror i kolumnen "Dagar med status".
Och slutligen, så här skulle det se ut med några testdata av olika datum:
Sammanfattning:
Där är det: ett snyggt formaterat, robust och bättre sätt att skapa en åldrande rapport i SharePoint, komplett med en enkel implementering utan kod. Detta har en hel del potentiella tillämpningar förutom det enda användningsfallet vi utforskade här. Ett annat vanligt scenario för den här typen av rapport är att bifoga den till en uppgiftslista så att du snabbt kan se hur lång tid som har gått sedan en uppgift skapades.
Njut!
--Justin
Justin Joyce, LANtek
Kommentarer
Steg saknas
2012-10-08 03:51
ok jag följde stegen, men det måste vara något som saknas - hur kommer XSL att veta vilket datum som ska användas, eller vilket fält som ska läggas till dagarna sedan i? Ogillar när man missar steg.
No-Code, håller med!
2012-08-30 12:12
Jag håller med - jag tror inte att detta verkligen räknas som "ingen kod".
Intressant, genom någon screwup av SharePoint, har jag en fungerande beräknad kolumn med hjälp av Idag ... Jag är inte säker på hur eller varför eftersom jag inte kan få den att göra det igen, men den är fortfarande där och fungerar.
Formel för den beräknade kolumnen "Dagar med status"?
2012-05-02 07:39
Justin – Vilken är formeln du använde för den beräknade webbplatskolumnen "Dagar med status" (platshållarkolumnen)? Var det "=idag"?
SharePoint 2007
2011-12-02 11:29
För närvarande har jag inte försökt att tillämpa den här lösningen på SharePoint 2007, men jag tittar på det. Tyvärr finns det ingen XslLink-egenskap i webbdelen via användargränssnittet.
Bra inlägg
2011-11-30 09:53
Hej,
Bra inlägg.
Jag använder SharePoint 2007.
Jag har ingen Misc-sektion som nämnts ovan.
Har du anvisningar för en SP2007-konfiguration?
Tack.
Re: Lösning utan kod: Visa dagarna sedan ett SharePoint-listobjekt senast ändrades
2011-10-11 08:24
Hej Chris.
Bra hitta!
Jag ska ta en titt på vad du postat förhoppningsvis senare idag och se om jag kan göra den här lösningen lite mer robust.
Jag är glad att du gillade inlägget, och jag är väldigt glad att du kunde hitta en lösning på det europeiska datumformatet. :)
-Justin
Lösning för europeiska datumformat
2011-10-11 06:45
Hej igen Justin,
FYI, jag hittade en lösning på problemet jag nämnde tidigare på den här sidan;
https://sharepointbydummies.wordpress.com/2011/07/13/possible-work-around-to-date-format-issue-sharepoint-2010/
Europeiska datumformat
2011-10-07 03:59
Hej Justin!
Det här är en riktigt bra lösning tack, och precis en sådan sak jag har tillbringat de senaste två dagarna med att leta efter! Men jag har lite problem med det och jag hoppades att du kunde hjälpa mig.
Jag har ändrat din kod något för att beräkna antalet dagar tills något händer, snarare än sedan, genom att byta variablerna på den sista raden i funktionen "DateDiff";
<xsl:värde-av select="$JulianToday - $JulianStartDate"></xsl:värde-av>
Men jag kan bara få den att räkna ut skillnaden korrekt hälften av gångerna. Så till exempel med detta datum (format dd/MM/åååå);
30/12/2011
Det beräknas korrekt, men med detta datum (samma format)
12/10/2011
Det beräknas som om 10-Dec-2011 snarare än 12-Oct-2011.
Jag försökte helt enkelt byta positionerna för dag- och månadsvärdena i variabeln "JulianStartDate", så här;
<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)"/>
Och detta korrigerade problemet med det andra datumet, men det var då felaktigt för det första datumet!
Jag har också provat att ändra FormatDateTime-anropen för att använda europeiska LCID:er och olika ändringar av den sista parametern i FormatDateTime (t.ex. ddMMyyyy, MMddyyyy) med lämpliga justeringar av delsträngens positionsparametrar utan framgång.
Jag skulle uppskatta alla råd du kan erbjuda.
Tack!
Christer
No-Code
2011-09-21 04:27
Jag tror inte att XSL kvalificerar sig som en "no-code"-lösning, eftersom att förstå XSL-språket inte är för alla - men det involverar inte programmering. Förutom det: Trevlig lösning, tack!