Rozwiązanie bez kodu: wyświetlanie dni od ostatniej zmiany elementu listy

Autor: Justin Joyce, LANtek

Uwaga

Ten artykuł jest częścią zbioru wpisów z czterech lat prowadzenia blogu Get the Point dla użytkowników końcowych programu SharePoint.

Omówienie: niestandardowe raporty wiekowania bez kodu

Jednym z często żądanych elementów funkcjonalnych witryny programu SharePoint jest raport wiekowania zawierający zadania lub elementy list. Innymi słowy, ile dni/miesięcy upłynęło od ostatniej modyfikacji tego elementu listy?

Na pierwszy rzut oka wydaje się, że jest to bardzo prosta prośba. W końcu mamy daty tworzenia i modyfikowania elementów, mamy możliwość przechowywania niestandardowych dat, gdy pewne zmiany w elementach mają miejsce za pośrednictwem odbiorników zdarzeń. Mamy kolumny obliczeniowe, w których możemy umieszczać formuły podobne do formuł programu Excel do pracy z naszymi informacjami. Wydaje się, że to dość prosta propozycja. Wybieramy pole daty, tworzymy kolumnę obliczeniową, a następnie tworzymy formułę podobną do [Pole_daty] — [Dzisiaj]. Ach, ale nie tak szybko! Każdy, kto próbował wykonać to "proste" zadanie, wie, że próba użycia w kolumnie obliczeniowej czegoś takiego jak [Dzisiaj] powoduje problemy. Próba wstawienia ciągu [Dzisiaj] w polu formuły kolumny obliczeniowej spowoduje wyświetlenie komunikatu o błędzie podobnego do tego:

Komunikat o błędzie

Dlaczego tak się dzieje? Jest to związane ze sposobem obliczania kolumn obliczeniowych.

Weźmy prostą formułę jako przykład:

= JEŻELI([Kolumna1]<=[Kolumna2], "OK";"Nie OK")

Oznacza to jedynie, że jeśli kolumna1 jest mniejsza lub równa kolumnie2, to wyświetl OK, w przeciwnym razie wyświetl wartość Niedobrze. Jest to dość typowa formuła podstawowa dla kolumny obliczeniowej, która przyjmuje podstawowe założenie dotyczące elementu listy zawierającego te kolumny: wartości kolumn1 i kolumny2 nie będą mogły zostać zmienione bez zdarzenia aktualizacji elementu listy.

Zgadza się, kolumny obliczeniowe są obliczane ponownie tylko wtedy, gdy lista zostanie zaktualizowana (lub utworzona), ponieważ zakładają, że obliczane informacje są zawarte w samym elemencie. Stwarza to problem w przypadku próby użycia elementu, który zmienia się niezależnie od pól elementu, na przykład bieżącej daty.

Nie uczestniczyłem w spotkaniu, na którym zdecydowano, że kolumny obliczeniowe będą działać w ten sposób, jednak gdybym miał zgadywać, założyłbym, że działają one w ten sposób ze względu na wydajność. Załóżmy, że masz listę kilku tysięcy elementów, z których każdy zawiera kolumnę obliczeniową, która wymaga aktualizacji "na żywo". Oznaczałoby to, że jakiś mechanizm, być może zadanie czasomierza, musiałby co jakiś czas iterować po każdym elemencie, który zawierał tę kolumnę obliczeniową i aktualizować jej wartość. Może to być bardzo obciążające pod względem wydajności, ponieważ w przypadku większych wdrożeń to zadanie może być stale uruchomione i zmieniać elementy. To tylko moje przypuszczenia, ale ma to sens, jeśli się nad tym zastanowić.

Istnieje kilka sugestii podobnych rozwiązań, które polegają na nakłanianiu programu SharePoint do zaakceptowania dzisiejszej wartości przez utworzenie najpierw kolumny o nazwie Dzisiaj, następnie dodanie jej do formuły, a następnie usunięcie. To wszystko jest wspaniałe, ale pamiętaj, co powiedziałem o aktualizacji kolumn obliczeniowych. Ta wartość zmieni się tylko wtedy, gdy element zostanie zaktualizowany, co oznacza, że wartości wkrótce staną się niepoprawne, szczególnie w przypadku obliczania dnia.

Widziałem, jak inni używają sprytnego JavaScriptu do zapisywania wartości na stronie. To też by zadziałało, ale jestem dość kategorycznie przeciwny skryptom klienckim, gdy można tego uniknąć.

Realizacja:

Więc co robić? Kolumny obliczeniowe nie wchodzą w rachubę w przypadku tak zwanych funkcji "nietrwałych", takich jak Dzisiaj. Możliwe, że moglibyśmy opracować niestandardowy kod, który zajmie się tym za nas, na przykład kolumnę obliczaną, zadanie czasomierza lub zaplanowany proces, który pojawi się i zaktualizuje każdy element, który wymaga wykonania tego obliczenia. To jednak prowadzi nas z powrotem do problemu wydajności, o którym wspomniałem w ostatnim akapicie, a dodatkowo jest to kruche rozwiązanie, które byłoby bardzo specyficzne dla danej witryny/listy/kolumny. Oprócz tych dwóch obaw, musiałbyś również znaleźć nerda, takiego jak ja, który wie, jak kodować i przekonać go do opracowania tego rozwiązania dla Ciebie. Ale jest prostszy sposób!

Jeśli masz uprawnienia do tworzenia pól i edytowania stron w witrynie oraz masz choć trochę wiedzy na temat języka XSLT i tworzenia widoków, możesz utworzyć szablon XSL, który można dołączyć do widoku listy i który będzie wiernie obliczał wartość za każdym razem, gdy żądana jest strona. Ten scenariusz eliminuje nasze obawy dotyczące wydajności i nie wymaga opracowania i wdrożenia niestandardowego kodu za pośrednictwem rozwiązania.

Doskonale. Jak więc to zrobić?

  1. Utwórz lub wybierz pole, które będzie źródłem. Musi to być typ daty.
  2. Utwórz pole, które będzie pełnić rolę symbolu zastępczego dla obliczanej wartości.
  3. Dodaj oba te pola do typu zawartości i dodaj ten typ zawartości do listy.
  4. Utwórz widok tej listy zawierający zarówno kolumnę źródłową, jak i kolumnę symboli zastępczych.
  5. Przekaż szablon XSL do biblioteki stylów.
  6. Ustaw właściwość "Łącze XSL" dla składnika Web Part widoku listy przy użyciu interfejsu użytkownika.
  7. Sukces!

Przyjrzyjmy się przykładowemu przypadkowi użycia i prześledźmy implementację. Nasz klient chciał mieć widok swojej listy głównej, który informowałby go, jak długo dany element listy znajduje się w swoim stanie. Ta lista zawierała niestandardowy typ zawartości witryny utworzony na podstawie typu elementu i dodany do listy. Istniał już odbiornik zdarzeń, który rejestruje każdą zmianę pola stanu w elemencie listy i zapisuje tę datę w kolumnie o nazwie "Data zmiany stanu". Całe to okablowanie nie jest wymagane i można je wykonać za pomocą DOWOLNEGO pola daty (tak się składa, że jest to nasza implementacja, ale nie krępuj się eksperymentować). Absolutne minimum, którego będziesz potrzebować, to pole daty źródłowej i pole zastępcze do przechowywania obliczeń (więcej na ten temat w następnym akapicie) dodanych do listy, chociaż sugeruję użycie kolumn witryny i typów zawartości witryny na wypadek, gdybyś chciał ponownie użyć tego rozwiązania w innych miejscach na swojej stronie.

Mamy więc datę źródłową, której możemy użyć w obliczeniach względem daty bieżącej. Teraz mogę utworzyć niestandardową kolumnę witryny, która będzie używana jako kontener dla obliczonej wartości. W tym przypadku zdecydowałem się użyć kolumny obliczeniowej, ponieważ nie będzie można jej zmienić w formularzu nowego elementu ani edytować elementu, ale można ją wybrać do wyświetlania w widokach, ponieważ nie chcemy, aby użytkownicy wprowadzali dowolne wartości w tej kolumnie. Może być mylące, dlaczego nie jest wyświetlany w widokach itp.

Po utworzeniu kolumny witryny można ją dodać do typów zawartości, które będą używane na liście. Następnie musimy utworzyć widok, który później zostanie dostosowany za pomocą naszego XSLT. Upewnij się, że został utworzony widok standardowy zawierający źródłową kolumnę dat i nową kolumnę obliczeniową, która będzie pełnić rolę symbolu zastępczego obliczonej wartości.

Mamy teraz wszystko to, czego będziemy potrzebować do obsługi naszego niestandardowego raportu wiekowania. Pozostaje tylko utworzyć szablon XSL, przesłać go do biblioteki stylów witryny i połączyć z widokiem listy. Szablon XSL, którego będziemy używać, będzie zawierał normalne znaczniki generowane przez program SharePoint do generowania widoku, a także nasze własne niestandardowe znaczniki używane do zastępowania niektórych części tego i obliczania żądanej wartości dla nas.

Dając kredyt tam, gdzie jest należny, szablony XSL do wykonywania rzeczywistych obliczeń, których używam w tym rozwiązaniu, zostały łaskawie udostępnione przez "swirch" na forach MSDN:
http://social.msdn.microsoft.com/Forums/en-US/sharepointcustomization/thread/aeda905b-9bc6-40c4-bd22-21306c5cb0d2/

Pobierz arkusz stylów XSL (aging.zip), który przygotowałem, znajdujący się tutaj:
https://OneDrive.live.com/?cid=c262e8e2d59a86d9&permissionsChanged=1&id=C262E8E2D59A86D9!104

Otwierając to w swoim ulubionym edytorze tekstu, zobaczysz mnóstwo normalnych znaczników XSL programu SharePoint do renderowania widoków, jeśli będziesz przewijać w dół do wiersza 357, zobaczysz początek niestandardowych szablonów, które dodałem do znaczników, pierwszym z nich jest szablon "DateDiff", a następnie "oblicz-julian-day" i "FieldRef_printTableCell_EcbAllowed.Days_x0020_At_x0020_Status". To są nasze trzy szablony, które utworzą i wyświetlą nasze obliczenia w naszych widokach. Jeśli będą używane inne nazwy pól niż określone wcześniej w tym artykule, należy przejrzeć te szablony i zamienić odwołania do innych nazw. Pamiętaj, że w tym przypadku będziesz używać nazwy WEWNĘTRZNEJ pola, a nie nazwy wyświetlanej.

Po upewnieniu się, że szablon jest gotowy, przejdź do biblioteki stylów i prześlij go do folderu "Arkusze stylów XSL", a następnie skopiuj link do pliku. Umożliwi nam to łatwe wprowadzanie w nim zmian później lub dodawanie go do różnych części witryny, jak nam się podoba.

Następnie przejdź do listy i wybierz widok utworzony wcześniej w tym artykule. W menu "Akcje witryny" kliknij "Edytuj stronę".

Polecenie Edytuj stronę wyświetlane w menu Akcje witryny

Na stronie znajdź składnik Web Part widoku listy, a następnie otwórz menu składnika Web Part, klikając małą strzałkę w dół w prawym górnym rogu. Z tego menu wybierz polecenie "Edytuj składnik Web Part".

Polecenie Edytuj składnik Web Part w menu składnika Web Part

Spowoduje to otwarcie menu składnika Web Part po prawej stronie okna przeglądarki.

Menu składnika Web Part

Kliknij pozycję + odpowiadającą sekcji "Różne" i zlokalizuj właściwość "Łącze XSL".

Właściwość Łącze XSL w menu składnika Web Part

Wklej skopiowany wcześniej link do pliku XSL w bibliotece stylów (może to być link względny lub bezwzględny).

Wklejone łącze do pliku XSL

Kliknij "OK", aby zapisać zmiany, a następnie kliknij przycisk "Zatrzymaj edycję" na wstążce "Strona" u góry strony.

Przycisk Zakończ edycję na karcie Strona

Jeśli wszystko zostało skonfigurowane poprawnie, liczby powinny być teraz widoczne w kolumnie "Dni ze stanem".

Kolumna dni ze stanem wyświetlająca liczbę

I na koniec, oto jak by to wyglądało z niektórymi danymi testowymi z różnych dat:

Raport wiekowania z testowymi danymi

Podsumowanie:

Oto on: ładnie sformatowany, niezawodny i wydajniejszy sposób tworzenia przestarzałego raportu w programie SharePoint wraz z prostą implementacją bez kodu. Ma to sporo potencjalnych zastosowań poza jednym przypadkiem użycia, który tutaj omówiliśmy. Innym typowym scenariuszem dla tego typu raportu jest dołączenie raportu do listy zadań, aby można było szybko sprawdzić, ile czasu upłynęło od utworzenia zadania.

Miłej pracy!

--Justyna

Justin Joyce, LANtek

Komentarze

Brak kroków
08-10-2012 03:51
ok, wykonałem kroki, ale chyba czegoś brakuje - skąd XSL będzie wiedział, której daty użyć lub do którego pola dodać dni od tego czasu? Nienawidzę, gdy kroki są pomijane.

No-Code, zgoda!
30.08.2012 12:12
Zgadzam się - nie sądzę, żeby to naprawdę liczyło się jako "brak kodu".
Co ciekawe, przez jakąś wpadkę w SharePoint, mam działającą kolumnę obliczeniową używającą Dzisiaj... nie jestem pewien, jak i dlaczego, ponieważ nie mogę go zmusić do zrobienia tego ponownie, ale ten nadal tam jest i działa.

Formuła kolumny obliczeniowej "Dni ze stanem"?
2012-05-02 07:39
Justin — Jaka formuła została użyta do obliczania kolumny witryny obliczeniowej (kolumny zastępczej) "Dni w stanie"? Czy to było "=dzisiaj"?

SharePoint 2007
02.12.2011 11:29
Obecnie nie próbowałem stosować tego rozwiązania w programie SharePoint 2007, jednak przyglądam się mu. Niestety, w składniku Web Part za pośrednictwem interfejsu użytkownika nie jest wyświetlana żadna właściwość XslLink.

Świetny post
30-11-2011 09:53
Cześć,
Świetny post.
Korzystam z programu SharePoint 2007.
Nie mam sekcji Różne, jak wspomniano powyżej.
Czy masz kroki dla konfiguracji SP2007?
Dziękujemy.

Re: Rozwiązanie bez kodu: Wyświetlanie dni od ostatniej zmiany elementu listy SharePoint
11.10.2011 08:24
Cześć Chris.
Świetne znalezisko!
Rzucę okiem na to, co napisałeś, mam nadzieję, później dzisiaj i zobaczę, czy mogę sprawić, by to rozwiązanie było trochę bardziej solidne.
Cieszę się, że podobał Ci się post i bardzo się cieszę, że udało Ci się znaleźć rozwiązanie dla europejskiego formatu daty. :)
-Justyna

Rozwiązanie dla europejskich formatów dat
11.10.2011 06:45
Witam ponownie Justin,
FYI, znalazłem rozwiązanie problemu, o którym wspomniałem wcześniej na tej stronie;
https://sharepointbydummies.wordpress.com/2011/07/13/possible-work-around-to-date-format-issue-sharepoint-2010/

Europejskie formaty daty
07-10-2011 03:59
Cześć Justin,
To naprawdę dobre rozwiązanie, dziękuję i właśnie tego szukałem przez ostatnie dwa dni! Mam jednak z tym pewien problem i miałem nadzieję, że mi pomożesz.
Zmieniłem nieco twój kod, aby obliczyć liczbę dni, zanim coś się wydarzy, a nie od tamtego, przełączając zmienne w ostatnim wierszu funkcji "DateDiff";

<xsl:wartość-z-wyboru="$JulianToday - $JulianStartDate"></xsl:wartość->

Jednak jestem w stanie sprawić, by poprawnie obliczył różnicę tylko w połowie przypadków. Czyli na przykład z tą datą (format dd/MM/rrrr);

30/12/2011

Jest obliczana poprawnie, ale z tą datą (w tym samym formacie)

12/10/2011

Obliczenia są wykonywane w taki sposób, jakby to był dzień 10 grudnia 2011 r., a nie 12 października 2011 r.
Próbowałem po prostu zamienić pozycje wartości dnia i miesiąca w zmiennej "JulianStartDate", w ten sposób;

<xsl:with-param name="Miesiąc" 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)"/>

I to rozwiązało problem z drugą datą, jednak była ona niepoprawna dla pierwszej daty!
Próbowałem również zmienić wywołania FormatDateTime, aby używały europejskich LCID i różne zmiany ostatniego parametru FormatDateTime (np. ddMMyyyy, MMddyyyy) z odpowiednimi dostosowaniami parametrów pozycyjnych podstring bez powodzenia.
Byłbym bardzo wdzięczny za każdą radę, której możesz zaoferować.
Dziękujemy
Krzysztof

No-Code
21.09.2011 04:27
Nie sądzę, aby XSL kwalifikował się jako rozwiązanie "no-code", ponieważ zrozumienie języka XSL nie jest dla każdego - jednak nie wymaga programowania. Poza tym: Fajne rozwiązanie, dziękuję!