av Justin Joyce, LANtek
Obs!
Denne artikkelen er en del av en samling innlegg fra fire år med Get the point-bloggen for SharePoint-sluttbrukere.
Oversikt: Egendefinerte aldersfordelte rapporter uten kode
En av de ofte forespurte funksjonelle delene på et SharePoint-område, er en aldersfordelt rapport for oppgaver eller listeelementer. Med andre ord, hvor mange dager/måneder er det siden dette listeelementet sist ble endret?
På overflaten ser dette ut til å være en veldig enkel forespørsel. Vi har tross alt datoer for elementer som opprettes og endres, vi har muligheten til å lagre egendefinerte datoer når visse endringer i elementer skjer gjennom hendelsesmottakere. Vi har beregnede kolonner der vi kan inkludere Excel-lignende formler for å jobbe med informasjonen vår. Dette virker som et ganske enkelt forslag. Vi velger et datofelt, oppretter en beregnet kolonne, og deretter lager vi en formel i retning av [DateField] – [Today]. Ah, ikke så fort skjønt! Som alle som har prøvd denne "enkle" oppgaven vet, forårsaker det problemer å prøve å bruke noe som for eksempel [Today] i en beregnet kolonne. Hvis du prøver å sette inn [Today] i formelboksen til den beregnede kolonnen, får du en feilmelding omtrent som dette:
Hvorfor skjer dette? Det har noe å gjøre med måten beregnede kolonner beregnes på.
La oss ta en enkel formel som et eksempel:
= HVIS( [Column1]<=[Column2], "OK", "Not OK")
Alt dette sier er at hvis Kolonne1 er mindre enn eller lik Kolonne2, da vises OK, ellers viser du Ikke OK. Dette er en ganske vanlig grunnleggende formel for en beregnet kolonne, og den gjør en grunnleggende antagelse om listeelementet som inneholder disse kolonnene: Verdiene for Kolonne1 og Kolonne2 vil aldri kunne endres uten en oppdateringshendelse på listeelementet.
Det stemmer, beregnede kolonner beregnes bare på nytt når listen oppdateres (eller opprettes), fordi de antar at informasjonen du beregner finnes i selve elementet. Dette skaper et problem når du prøver å bruke noe som endres uavhengig av elementets felt, for eksempel dagens dato.
Nå var jeg ikke i møtet der de bestemte at dette er måten beregnede kolonner ville fungere på, men hvis jeg måtte gjøre en kvalifisert gjetning, ville jeg anta at de fungerer på denne måten for ytelse. Tenk deg at du hadde en liste med flere tusen elementer, som hver inneholdt en beregnet kolonne som trenger en «live» oppdatering. Det ville bety at en mekanisme, kanskje en tidtakerjobb, måtte gjentas gjennom hvert element som inneholdt den beregnede kolonnen med jevne mellomrom, og oppdatere verdien. Dette kan være svært krevende med tanke på ytelsen, for med større distribusjoner kan denne jobben hele tiden kjøre og endre ting. Det er bare min gjetning, men det gir ganske mye mening hvis du tenker på det.
Det finnes noen forslag til lignende løsninger som flyter rundt der ute, som involverer å lure SharePoint til å godta en I dag-verdi ved først å opprette en kolonne kalt I dag, deretter legge den til i formelen og deretter slette den. Alt dette er vel og bra, men husk hva jeg sa om når beregnede kolonner blir oppdatert. Denne verdien endres bare når elementet oppdateres, noe som betyr at verdiene snart vil være feil, spesielt når det gjelder en dagsberegning.
Jeg har sett andre bruke smart JavaScript til å skrive verdiene til siden. Dette ville også fungere, men jeg er ganske kategorisk imot klientskript når det kan unngås.
Gjennomføring:
Så hva skal jeg gjøre? Beregnede kolonner er uaktuelt for såkalte «flyktige» funksjoner som I dag. Det er mulig at vi kan utvikle en tilpasset kode for å ta seg av dette for oss, for eksempel en beregnet kolonne, tidtakerjobb eller en planlagt prosess for å komme og oppdatere hvert enkelt element som trenger denne beregningen gjort. Det bringer oss tilbake til problemet med ytelse jeg nevnte i forrige avsnitt, og i tillegg er det en sprø løsning som vil være svært spesifikk for nettstedet/listen/kolonnen det gjelder. På toppen av disse to bekymringene, må du også finne en nerdete fyr, som meg selv, som vet hvordan han skal kode og overtale ham til å utvikle denne løsningen for deg. Men det finnes en enklere måte!
Hvis du har rettigheter til å opprette felt og redigere sider på nettstedet, og har litt kunnskap om XSLT og hvordan du oppretter visninger, kan du sette sammen en XSL-mal som kan inkluderes i en listevisning, og som nøyaktig beregner verdien hver gang siden forespørres. Dette scenariet fjerner bekymringen vi bryr oss om ytelse, og krever ikke at egendefinert kode utvikles og distribueres via en løsning.
Perfekt. Så hvordan gjør vi det?
- Opprett eller velg feltet som skal fungere som vår kilde. Det må være en datotype.
- Opprett feltet vårt som skal fungere som en plassholder for verdien som beregnes.
- Legg til begge disse feltene i en innholdstype, og legg til denne innholdstypen i en liste.
- Opprett en visning av listen som inneholder både kilde- og plassholderkolonnene.
- Last opp XSL-malen til stilbiblioteket.
- Angi egenskapen XSL-kobling for nettdelen for listevisning via brukergrensesnittet.
- Vellykket!
La oss utforske et eksempel på et brukstilfelle og gå gjennom implementeringen. Kunden vår ønsket en visning av hovedlisten som kunne fortelle dem hvor lenge et bestemt listeelement hadde ligget med status. Denne listen inneholdt en egendefinert nettstedsinnholdstype som var avledet fra elementtypen og lagt til i listen. Det fantes allerede en hendelsesmottaker som registrerer hver gang statusfeltet på listeelementet ble endret, og lagret denne datoen i en kolonne kalt «Dato status endret». All denne kablingen er ikke nødvendig, og kan gjøres med ALLE datofelt (det har seg slik at dette er vår implementering, men eksperimenter gjerne). Det minste du trenger er kildedatofeltet og plassholderfeltet for å holde beregningen (mer om dette i neste avsnitt) lagt til i listen, selv om jeg foreslår at du bruker nettstedskolonner og innholdstyper for nettsted i tilfelle du ønsker å bruke denne løsningen andre steder på nettstedet.
Så vi har kildedatoen som vi kan bruke i beregningen mot dagens dato. Nå kan vi opprette en egendefinert nettstedskolonne som skal brukes som en beholder for den beregnede verdien. I dette tilfellet valgte jeg å bruke en beregnet kolonne siden den ikke vil kunne endres i skjemaet for nytt eller redigert element, men kan velges for visning i visningene siden vi ikke vil at brukere skal skrive inn vilkårlige verdier i denne kolonnen. Det kan være forvirrende hvorfor det ikke vises i visningene osv.
Nå som vi har nettstedskolonnen vår, kan vi legge den til i innholdstypene våre som skal brukes i listen vår. Deretter må vi lage vår visning som senere vil bli tilpasset med vår XSLT. Pass på at du oppretter en standardvisning som inneholder kolonnen for kildedato og den nye beregnede kolonnen som skal fungere som plassholder for den beregnede verdien.
Vi har nå alt vi trenger for å støtte vår tilpassede aldringsrapport. Alt som gjenstår er å opprette XSL-malen, laste den opp til nettstedets stilbibliotek og koble den til listevisningen. XSL-malen vi skal bruke, kommer til å inneholde noen vanlige SharePoint-genererte markeringer for å generere visningen, samt vår egen egendefinerte markering som brukes til å overstyre bestemte deler av dette og beregne ønsket verdi for oss.
XSL-malene for å gjøre de faktiske beregningene jeg bruker for denne løsningen er kreditert der kreditt fortjenes, ble nådig levert av «swirch» på MSDN-forumene:
http://social.msdn.microsoft.com/Forums/en-US/sharepointcustomization/thread/aeda905b-9bc6-40c4-bd22-21306c5cb0d2/
Last ned XSL-stilarket (aging.zip) jeg har satt sammen som finner her:
https://OneDrive.live.com/?cid=c262e8e2d59a86d9&permissionsChanged=1&id=C262E8E2D59A86D9!104
Når du åpner dette i ditt favoritt tekstredigeringsprogram vil du se massevis av normal SharePoint XSL-markering for gjengivelse av visningene, hvis du fortsetter å rulle ned til linje 357 vil du se starten på de egendefinerte malene som jeg la til markeringen, den første er «DateDiff»-malen etterfulgt av «calculate-julian-day» og «FieldRef_printTableCell_EcbAllowed.Days_x0020_At_x0020_Status». Dette er våre tre maler som vil utføre og vise beregningene våre i våre visninger. Hvis du skal bruke andre feltnavn enn det som ble angitt tidligere i denne artikkelen, må du gå gjennom disse malene og erstatte eventuelle referanser til andre navn. Husk at til dette vil du bruke det INTERNE navnet på feltet, ikke visningsnavnet.
Når du er fornøyd med at malen er klar til bruk, kan du gå til stilbiblioteket og laste den opp under mappen XSL-stilark, og deretter kopiere koblingen til filen. Dette gjør at vi enkelt kan gjøre endringer i det senere, eller legge det til i forskjellige deler av nettstedet som vi vil.
Deretter går du til listen og velger visningen du opprettet tidligere i denne artikkelen. Fra "Nettstedshandlinger"-menyen klikker du på "Rediger side".
Finn nettdelen for listevisning på siden, og åpne nettdelmenyen ved å klikke den lille pilen som peker nedover i øvre høyre hjørne. Fra denne menyen velger du Rediger nettdel.
Dette åpner nettdelens meny på høyre side av nettleservinduet.
Klikk på + for delen "Diverse", og finn egenskapen "XSL Link".
Lim inn koblingen til XSL-filen i stilbiblioteket som du kopierte ned tidligere (dette kan være en relativ eller absolutt kobling).
Klikk på OK for å lagre endringene, og klikk deretter på Stopp redigering-knappen på båndet øverst på siden.
Hvis alt var riktig konfigurert, skal du nå se tall i «Dager med status»-kolonnen.
Og til slutt, her er hvordan det vil se ut med noen testdata fra forskjellige datoer:
Sammendrag:
Der er den: en pent formatert, robust og bedre ytelse måte å opprette en aldrende rapport i SharePoint., komplett med en enkel implementering uten kode. Dette har ganske mange potensielle bruksområder bortsett fra det ene brukstilfellet vi utforsket her. Et annet vanlig scenario for denne typen rapport er å knytte den til en oppgaveliste, slik at du raskt kan se hvor lang tid det har gått siden en oppgave ble opprettet.
Kos deg!
--Justin
Justin Joyce, LANtek
Kommentarer
Trinn mangler
08.10.2012 03:51
OK, jeg har fulgt trinnene, men det må mangle noe – hvordan vet XSL hvilken dato som skal brukes, eller hvilket felt du skal legge til dager siden i? Jeg hater når skritt går glipp av.
Ingen kode, avtalt!
30/8/2012 12:12
Jeg er enig - jeg tror egentlig ikke dette teller som "ingen kode".
Interessant nok, gjennom litt skru av SharePoint, har jeg en fungerende beregnet kolonne som bruker I dag ... ikke sikker på hvordan eller hvorfor fordi jeg ikke kan få den til å gjøre det igjen, men den ene er fortsatt der og fungerer.
Formel for beregnet kolonne for «Dager med status»?
02.05.2012 07:39
Justin – Hva er formelen du brukte for kolonnen med beregnede nettsteder for «Dager med status» (plassholderkolonne)? Var det «=i dag»?
SharePoint 2007
02.12.2011 11:29
For øyeblikket har jeg ikke prøvd å bruke denne løsningen i SharePoint 2007, men jeg ser på det. Dessverre vises ingen XslLink-egenskap på nettdelen gjennom brukergrensesnittet.
Flott innlegg
30/11/2011 09:53
Hei,
Flott innlegg.
Jeg bruker SharePoint 2007.
Jeg har ikke en Diverse-seksjon som nevnt ovenfor.
Har du fremgangsmåter for en SP2007-konfigurasjon?
Takk.
Re: Løsning uten kode: Viser dagene etter at et SharePoint-listeelement sist ble endret
11.10.2011 08:24
Hei, Chris.
Flott funn!
Jeg skal ta en titt på hva du la ut forhåpentligvis senere i dag og se om jeg kan gjøre denne løsningen litt mer robust.
Jeg er glad du likte innlegget, og jeg er veldig glad for at du klarte å finne en løsning på det europeiske datoformatet. :)
-Justin
Løsning for europeiske datoformater
10/11/2011 6:45 AM
Hei igjen Justin!
FYI, jeg fant en løsning på problemet jeg nevnte tidligere på denne siden;
https://sharepointbydummies.wordpress.com/2011/07/13/possible-work-around-to-date-format-issue-sharepoint-2010/
Europeiske datoformater
07.10.2011 03:59
Hei, Justin!
Dette er en veldig god løsning takk, og akkurat den typen ting jeg har brukt de siste to dagene på å lete etter! Imidlertid har jeg litt av et problem med det, og jeg håpet du kunne hjelpe meg.
Jeg har endret koden din litt for å beregne antall dager til noe skjer, i stedet for siden, ved å bytte variablene i den siste linjen i "DateDiff"-funksjonen;
<xsl:value-of select="$JulianToday - $JulianStartDate"></xsl:value-of>
Imidlertid klarer jeg bare å få den til å beregne forskjellen riktig halvparten av tiden. Så for eksempel med denne datoen (format dd/MM/åååå);
30/12/2011
Den beregner riktig, men med denne datoen (samme format)
12/10/2011
Den beregner som om 10-des-2011 i stedet for 12-okt-2011.
Jeg prøvde ganske enkelt å bytte posisjonene til dag- og månedsverdiene i "JulianStartDate"-variabelen, slik;
<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)"/>
Og dette løste problemet med den andre datoen, men det var da feil for den første datoen!
Jeg har også prøvd å endre FormatDateTime-kallene til å bruke europeiske LCID-er og forskjellige endringer i den siste parameteren i FormatDateTime (f.eks. ddMMyyyy, MMddyyyy) med de riktige justeringene av understrengens posisjonsparametere uten å lykkes.
Jeg vil sette stor pris på alle råd du kan gi.
Vennlig hilsen
Kristian
No-Code
21.09.2011 04:27
Jeg tror ikke at XSL kvalifiserer som en "no-code"-løsning, siden det å forstå XSL-språket ikke er for alle - men det involverer ikke programmering. Utenom det: Fin løsning, takk!