od Justina Joycea, LANtek
Poznámka
Tento článok je súčasťou kolekcie príspevkov zo štyroch rokov blogu Get the Point pre koncových používateľov SharePointu.
Prehľad: Vlastné zostavy s dátumom splatnosti bez kódu
Jednou z často požadovaných funkčných častí lokality SharePoint je zostava o starnutí pre úlohy alebo položky zoznamu. Inými slovami, koľko dní alebo mesiacov uplynulo od poslednej úpravy tejto položky zoznamu?
Na prvý pohľad sa to zdá byť veľmi jednoduchá požiadavka. Koniec koncov, máme k dispozícii dátumy pre vytvárané a upravované položky, máme možnosť ukladať vlastné dátumy uskutočnenia určitých zmien položiek prostredníctvom príjemcov udalostí. Vypočítali sme stĺpce, do ktorých môžeme pre prácu s informáciami zahrnúť vzorce podobné Excelu. Zdá sa to ako celkom priamočiary návrh. Vyberieme pole s dátumom, vytvoríme vypočítavaný stĺpec a potom urobíme vzorec podobne ako [DátumovéPole] – [Dnes]. Ach, nie tak rýchlo! Ako vie každý, kto sa pokúšal o túto "jednoduchú" úlohu, snaha o použitie niečoho ako [Dnes] vo vypočítavanom stĺpci spôsobuje problémy. Skúste vložiť text [Dnes] do poľa vzorca vypočítaného stĺpca a zobrazí sa chybové hlásenie podobné tomuto:
Prečo to tak je? Súvisí to so spôsobom výpočtu vypočítavaných stĺpcov.
Zoberme si ako príklad jednoduchý vzorec:
= IF( [Stĺpec1]<=[Stĺpec2]; "OK"; "Nie je to OK")
Znamená to len to, že ak je hodnota Stĺpec1 menšia alebo rovná ako Stĺpec2, zobrazí sa OK, inak sa zobrazí Nie je to OK. Toto je pomerne typický základný vzorec pre vypočítavaný stĺpec a vychádza zo základného predpokladu pre položku zoznamu, ktorá obsahuje tieto stĺpce: Hodnoty pre Stĺpec1 a Stĺpec2 sa nikdy nedajú zmeniť bez udalosti aktualizácie pre položku zoznamu.
Je to tak, vypočítané stĺpce sa prepočítajú až po aktualizácii (alebo vytvorení) zoznamu, pretože predpokladajú, že vypočítavané informácie sú obsiahnuté v samotnej položke. Vznikne tak problém, keď sa pokúšate použiť niečo, čo sa mení nezávisle od polí položky, ako je napríklad dnešný dátum.
Nebol som na stretnutí, kde sa rozhodli, že toto je spôsob, akým budú fungovať vypočítavané stĺpce, ale ak by som mal urobiť kvalifikovaný odhad, predpokladal by som, že fungujú týmto spôsobom pre výkon. Predstavte si, že by ste mali zoznam niekoľkých tisíc položiek a každá z nich obsahovala vypočítavaný stĺpec, ktorý je potrebné aktualizovať "naživo". To by znamenalo, že nejaký mechanizmus, napríklad úloha časovača, by musel občas iterovať cez každú položku, ktorá obsahuje daný vypočítaný stĺpec, a aktualizovať jeho hodnotu. To môže byť mimoriadne náročné z hľadiska výkonu, pretože pri väčších nasadeniach môže táto úloha neustále fungovať a meniť veci. To je len môj odhad, ale dáva to dosť zmysel, keď sa nad tým zamyslíte.
Existuje niekoľko návrhov na podobné riešenia, ktoré zahŕňajú oklamanie SharePointu tak, aby prijal hodnotu Dnes tak, že najskôr vytvoríte stĺpec s názvom Dnes, potom ho pridáte do vzorca a nakoniec ho odstránite. To všetko je v poriadku, ale pamätajte, čo som povedal o aktualizácii vypočítavaných stĺpcov. Táto hodnota sa zmení iba pri aktualizácii položky, čo znamená, že hodnoty budú čoskoro nesprávne, najmä pri výpočte jedného dňa.
Videl som ostatných, ktorí používali šikovný JavaScript na zapisovanie hodnôt na stránku. To by tiež fungovalo, ale som dosť kategoricky proti klientskemu skriptu, keď sa tomu dá vyhnúť.
Implementácia:
Čo teda robiť? Vypočítavané stĺpce neprichádzajú do úvahy pri tzv. nestálych funkciách, akou je funkcia Today. Je možné, že by sme mohli vyvinúť nejaký vlastný kód, ktorý by sa o to postaral, napríklad vypočítaný stĺpec, úlohu časovača alebo naplánovaný proces, ktorý by sa objavil a aktualizoval každú jednu položku, na ktorej je potrebné vykonať tento výpočet. To nás však privádza späť k problému výkonu, ktorý som spomenul v poslednom odseku, a navyše je to krehké riešenie, ktoré by bolo veľmi špecifické pre príslušnú stránku/zoznam/stĺpec. Okrem týchto dvoch obáv by ste museli nájsť aj hlúpeho chlapíka, ako som ja, ktorý vie kódovať a presvedčiť ho, aby pre vás vyvinul toto riešenie. Existuje však jednoduchší spôsob.
Ak máte oprávnenia na vytváranie polí a úpravu stránok na lokalite a určité znalosti o jazyku XSLT a vytváraní zobrazení, môžete zostaviť šablónu XSL, ktorú je možné začleniť do zobrazenia zoznamu a ktorá bude verne vypočítavať vašu hodnotu vždy, keď sa zobrazí požiadavka na stránku. Tento scenár nás zbavuje obáv o výkon a nevyžaduje vývoj a nasadenie vlastného kódu prostredníctvom riešenia.
Perfektné. Ako to teda urobíme?
- Vytvorte alebo vyberte pole, ktoré bude slúžiť ako zdroj. Musí byť typu dátum.
- Vytvorte naše pole, ktoré bude slúžiť ako zástupný objekt pre vypočítavanú hodnotu.
- Pridajte obe tieto polia do typu obsahu a pridajte daný typ obsahu do zoznamu.
- Vytvorte zobrazenie zoznamu, ktoré obsahuje zdrojový aj zástupný stĺpec.
- Nahrajte šablónu XSL do knižnice štýlov.
- Nastavte vlastnosť Prepojenie XSL webovej časti Zobrazenie zoznamu cez používateľské rozhranie.
- Úspech!
Preskúmajme príklad prípadu použitia a prevedieme ho implementáciou. Náš zákazník chcel mať k dispozícii zobrazenie svojho hlavného zoznamu, ktoré by mu umožnilo zistiť, ako dlho sa určitá položka zoznamu držala vo svojom stave. Tento zoznam obsahoval vlastný typ obsahu lokality odvodený od typu Položka a pridaný do zoznamu. Už tam bol príjemca udalostí, ktorý zaznamená každú zmenu poľa stavu v položke zoznamu a uloží tento dátum do stĺpca s názvom Dátum zmeny stavu. Všetko toto zapojenie nie je potrebné a dá sa vykonať s AKÝMKOĽVEK dátumovým poľom (zhodou okolností je to naša implementácia, ale pokojne experimentujte). Úplné minimum, ktoré budete potrebovať, je pole zdrojového dátumu a zástupné pole na uloženie výpočtu (viac o tom v nasledujúcom odseku) pridaného do zoznamu, aj keď odporúčam použiť stĺpce lokality a typy obsahu lokality pre prípad, že chcete toto riešenie znova použiť na iných miestach na svojej lokalite.
Máme teda náš zdrojový dátum, ktorý môžeme vo výpočte použiť oproti dnešnému dátumu. Teraz môžeme vytvoriť vlastný stĺpec lokality, ktorý sa použije ako kontajner pre vypočítanú hodnotu. V tomto prípade som sa rozhodol použiť vypočítaný stĺpec, pretože ho nebude možné zmeniť vo formulári pre nové alebo úpravy položiek, ale bude možné ho vybrať na zobrazenie v zobrazeniach, pretože nechceme, aby používatelia do tohto stĺpca zadávali ľubovoľné hodnoty. Mohlo by to byť mätúce, prečo sa to nezobrazuje v zobrazeniach atď.
Teraz, keď máme stĺpec lokality, môžeme ho pridať do typov obsahu, ktoré sa budú používať v našom zozname. Ďalej musíme vytvoriť zobrazenie, ktoré neskôr prispôsobíme pomocou XSLT. Uistite sa, že ste vytvorili štandardné zobrazenie obsahujúce stĺpec zdrojového dátumu a nový vypočítaný stĺpec, ktorý bude slúžiť ako zástupný objekt pre vypočítanú hodnotu.
Teraz máme všetko, čo budeme potrebovať na podporu našej vlastnej správy o starnutí. Zostáva už len vytvoriť šablónu XSL, nahrať ju do knižnice štýlov lokality a prepojiť ju so zobrazením zoznamu. Šablóna XSL, ktorú budeme používať, bude obsahovať niektoré bežné značky generované SharePointom na generovanie zobrazenia, ako aj naše vlastné značky, ktoré sa používajú na prepísanie určitých častí a výpočet našej požadovanej hodnoty.
Ak uvediem kredit, šablóny XSL na vykonávanie skutočných výpočtov, ktoré používam pre toto riešenie, boli láskavo poskytnuté službou "swirch" na fórach MSDN:
http://social.msdn.microsoft.com/Forums/en-US/sharepointcustomization/thread/aeda905b-9bc6-40c4-bd22-21306c5cb0d2/
Stiahnite si šablónu štýlov XSL (aging.zip), ktorú som zostavil a ktorá sa nachádza tu:
https://OneDrive.live.com/?cid=c262e8e2d59a86d9&permissionsChanged=1&id=C262E8E2D59A86D9!104
Keď ju otvoríte vo svojom obľúbenom textovom editore, uvidíte množstvo bežných značiek SharePoint XSL na vykresľovanie zobrazení, ak sa budete posúvať nadol na riadok 357, uvidíte začiatok vlastných šablón, ktoré som pridal do značky, prvou je šablóna "DateDiff" nasledovaná "calculate-julian-day" a "FieldRef_printTableCell_EcbAllowed.Days_x0020_At_x0020_Status". Toto sú naše tri šablóny, ktoré budú robiť a zobrazovať naše výpočty v našich zobrazeniach. Ak budete používať iné názvy polí, než ste špecifikovali vyššie v tomto článku, budete musieť tieto šablóny prejsť a nahradiť všetky odkazy na ostatné názvy. Nezabudnite, že v tomto prípade budete chcieť použiť INTERNÝ názov poľa, nie zobrazovaný názov.
Keď sa presvedčíte, že je šablóna pripravená na používanie, prejdite do knižnice štýlov, nahrajte ju do priečinka Šablóny štýlov XSL. Potom skopírujte prepojenie na súbor. Umožní nám to neskôr jednoducho vykonať zmeny alebo ho pridať do rôznych častí stránky podľa potreby.
Potom prejdite do zoznamu a vyberte zobrazenie, ktoré ste vytvorili vyššie v tomto článku. V ponuke Akcie lokality kliknite na položku Upraviť stránku.
Vyhľadajte na stránke webovú časť Zobrazenie zoznamu a kliknutím na malú šípku nadol v pravom hornom rohu otvorte ponuku webovej časti. V tejto ponuke vyberte položku Upraviť webovú časť.
Na pravej strane okna prehliadača sa otvorí ponuka webovej časti.
Kliknite na + pre časť "Rôzne" a vyhľadajte vlastnosť "Prepojenie XSL".
Prilepte prepojenie na súbor XSL v knižnici štýlov, ktoré ste predtým skopírovali (môže to byť relatívne alebo absolútne prepojenie).
Kliknutím na tlačidlo OK uložte zmeny a potom kliknite na tlačidlo Zastaviť úpravy na páse s nástrojmi Stránka v hornej časti stránky.
Ak bolo všetko nakonfigurované správne, mali by sa teraz v stĺpci Dni s daným stavom zobrazovať čísla.
Na záver si pozrite, ako by to vyzeralo s niekoľkými testovými údajmi s rôznymi dátumami:
Súhrn:
Tu je: úhľadne naformátovaný, robustný a výkonnejší spôsob, ako vytvoriť zostavu o starnutí v SharePointe, doplnený jednoduchou implementáciou bez použitia kódu. Má to pomerne veľa potenciálnych aplikácií okrem jedného prípadu použitia, ktorý sme tu preskúmali. Ďalším bežným scenárom pre tento typ zostavy je jej priloženie do zoznamu úloh, aby ste mohli okamžite zistiť, koľko času uplynulo od vytvorenia úlohy.
Príjemnú zábavu!
--Jakub
Justin Joyce, LANtek
Komentáre
Chýbajú kroky
8.10.2012 3:51
Postupoval som podľa pokynov, ale niečo musí chýbať – ako XSL vie, ktorý dátum sa má použiť alebo do ktorého poľa sa majú pridať dni? Neznášate, keď sa vynechajú kroky.
Bez kódu, súhlasiť!
30.8.2012 12:12
Súhlasím - nemyslím si, že sa to skutočne počíta ako "žiadny kód".
Zaujímavé je, že cez nejaký prešpik SharePointu mám vypočítaný stĺpec pomocou funkcie Dnes... neviem ako alebo prečo, pretože to neviem prinútiť urobiť znova, ale ten je stále tam a funguje.
Vzorec pre vypočítavaný stĺpec Dni s daným stavom?
2.5.2012 7:39
Jakub – aký vzorec ste použili vo vypočítavanom stĺpci lokality s dňami s daným stavom (zástupný stĺpec)? Bolo to "=dnes"?
SharePoint 2007
2.12.2011 11:29
Momentálne som sa nepokúšal použiť toto riešenie v SharePointe 2007, no pozerám sa naň. Žiaľ, vo webovej časti sa prostredníctvom používateľského rozhrania nezobrazuje žiadna vlastnosť XslLink.
Skvelý príspevok
30.11.2011 9:53
Dobrý deň,
Skvelý príspevok.
Používam SharePoint 2007.
Nemám sekciu Rôzne, ako je uvedené vyššie.
Máte kroky na konfiguráciu balíka SP2007?
Ďakujeme.
Re: Riešenie bez kódu: Zobrazenie dní od poslednej zmeny položky zoznamu SharePointu
11.10.2011 8:24
Dobrý deň, Chris.
Skvelé nájdenie!
Dúfam, že neskôr dnes sa pozriem na to, čo ste uverejnili, a uvidím, či dokážem urobiť toto riešenie trochu robustnejším.
Som rád, že sa vám príspevok páčil a som veľmi rád, že sa vám podarilo nájsť riešenie európskeho formátu dátumu. :)
-Jakub
Riešenie pre európske formáty dátumu
11.10.2011 6:45
Ahoj ešte raz Justin.
Pre vašu informáciu, našiel som riešenie problému, ktorý som už spomenul na tejto stránke;
https://sharepointbydummies.wordpress.com/2011/07/13/possible-work-around-to-date-format-issue-sharepoint-2010/
Európske formáty dátumu
7.10.2011 3:59
Dobrý deň, Justin.
Toto je naozaj dobré riešenie, ďakujem, a presne také, aké som posledné dva dni hľadal! Mám s tým však trochu problém a dúfal som, že mi môžete pomôcť.
Mierne som zmenil váš kód, aby som vypočítal počet dní, kým sa niečo nestane, namiesto toho, aby som zmenil premenné v poslednom riadku funkcie "DateDiff";
<xsl:hodnota-výberu="$JulianToday - $JulianStartDate"></xsl:hodnota-of>
Som však schopný to správne vypočítať rozdiel len v polovici času. Takže napríklad s týmto dátumom (formát dd/MM/rrrr);
30/12/2011
Vypočíta sa správne, ale s týmto dátumom (rovnaký formát)
12/10/2011
Vypočíta sa, ako keby bol 10-Dec-2011 a nie 12-Okt-2011.
Skúsil som jednoducho prepnúť pozície hodnôt dňa a mesiaca v premennej "JulianStartDate", takto;
<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)"/>
A to vyriešilo problém s druhým rande, avšak pri prvom rande to bolo nesprávne!
Tiež som sa neúspešne pokúsil zmeniť volania FormatDateTime tak, aby používali európske LCID, a rôzne zmeny posledného parametra FormatDateTime (napr. ddMMyyyy, MMddyyyy) s príslušnými úpravami parametrov polohy podreťazca.
Veľmi by som ocenil akúkoľvek radu, ktorú môžete ponúknuť.
Ďakujeme!
Michal
No-Code
21.9.2011 4:27
Nemyslím si, že XSL sa kvalifikuje ako riešenie "bez kódu", pretože pochopenie jazyka XSL nie je pre každého - nezahŕňa to však programovanie. Okrem toho: Pekné riešenie, ďakujeme!