Решение без код: Показване на дните след последната промяна на елемент от списък

от Джъстин Джойс, LANtek

Забележка

Тази статия е част от колекция от публикации от четири години на блога Get the Point за крайни потребители на SharePoint.

Общ преглед: Отчети за стареенето по избор без код

Една от най-често исканите функционални части на сайта на SharePoint е отчетът за стареенето на задачите или елементите от списък. С други думи, колко дни/месеци са изминали от последната промяна на този елемент от списъка?

На пръв поглед това изглежда много просто искане. В края на краищата имаме дати за създаване и промяна на елементи, имаме възможност да съхраняваме дати по избор, когато определени промени в елементи се извършват чрез получатели на събития. Изчислихме колони, в които можем да включим подобни на Excel формули, за да работим с нашата информация. Това изглежда като доста просто предложение. Избираме поле за дата, създаваме изчисляема колона и след това правим формула нещо от рода на [DateField] – [Today]. Ах, не толкова бързо, обаче! Всеки, който е опитвал тази "проста" задача, знае, опитът да се използва нещо като [Today] в изчисляема колона създава проблеми. Опитайте да вмъкнете [Today] в полето за формула на изчисляемата колона и ще видите съобщение за грешка подобно на това:

Съобщение за грешка

Защо е така? Това е свързано с начина, по който се изчисляват изчисляемите колони.

Да вземем за пример една проста формула:

= IF( [Колона1]<=[Колона2]; "OK"; "Не е OK")

Това само казва, че ако "Колона1" е по-малка или равна на "Колона2", тогава се показва OK, в противен случай се показва "Не е OK". Това е доста типична основна формула за изчисляема колона и тя прави основното предположение за елемента от списъка, който съдържа тези колони: Стойностите за "Колона1" и "Колона2" няма да могат да се променят без събитие Update за елемента от списъка.

Точно така, изчисляемите колони ще се преизчисляват само когато списъкът се актуализира (или създава), тъй като предполагат, че информацията, която изчислявате, се съдържа в самия елемент. Това създава проблем, когато се опитвате да използвате нещо, което се променя независимо от полетата на елемента, като например днешната дата.

Сега не бях на срещата, където решиха, че това е начинът, по който ще функционират изчисляемите колони, но ако трябва да направя обосновано предположение, бих предположил, че те функционират по този начин за производителност. Представете си, че имате списък с няколко хиляди елемента, всеки от които съдържа изчисляема колона, която се нуждае от актуализация на живо. Това би означавало, че някакъв механизъм, може би работа с таймер, ще трябва да претърсва всеки елемент, който съдържа тази изчисляема колона от време на време, и да актуализира стойността й. Това може да бъде изключително натоварващо от гледна точка на производителността, защото при по-големи разполагания тази задача може постоянно да се изпълнява и да променя нещата. Това е само моето предположение, но има доста смисъл, ако се замислите.

Има някои предложения за подобни решения, които включват подмаждане на SharePoint да приеме стойност на днешна дата чрез първо създаване на колона с име "Днес", след което добавянето й към вашата формула и изтриването й. Всичко това е добре, но не забравяйте какво казах за това кога се актуализират изчисляемите колони. Тази стойност ще се промени само когато елементът бъде актуализиран, което означава, че вашите стойности скоро ще бъдат неправилни, особено в случай на изчисление на ден.

Виждал съм други да използват умен JavaScript, за да запишат стойностите в страницата. Това също би свършило работа, но аз съм категорично против клиентския скрипт, когато може да се избегне.

Изпълнение:

И така, какво да направите? За изчисляеми колони не може да става и дума за т.нар. "непостоянни" функции, като например Today. Възможно е да разработим някакъв персонализиран код, който да се погрижи за това вместо нас, като например изчислена колона, задача с таймер или планиран процес, които да се появит и да актуализират всеки един елемент, който изисква това изчисление. Това ни връща към проблема с производителността, който споменах в последния абзац обаче, и освен това това е крехко решение, което би било много специфично за въпросния сайт/списък/колона. На всичкото отгоре тези две притеснения, ще трябва да намерите и маниак като мен, който знае как да кодира и да го убеди да разработи това решение за вас. Но има и по-лесен начин!

Ако имате права за създаване на полета и редактиране на страници във вашия сайт и имате малко познания за XSLT и създаването на изгледи, можете да съставите XSL шаблон, който може да бъде включен в списъчен изглед и ще изчислява достоверно вашата стойност всеки път, когато страницата е поискана. Този сценарий премахва притесненията ни за производителността и не изисква персонализиран код да бъде разработен и разположен чрез решение.

Перфектен. И така, как да го направим?

  1. Създайте или изберете полето, което ще служи като наш източник. Трябва да е тип дата.
  2. Създайте наше поле, което ще служи като контейнер за стойността, която се изчислява.
  3. Добавете и двете полета към тип съдържание и добавете този тип съдържание към списък.
  4. Създайте изглед на този списък, съдържащ колоните източник и колоните контейнери.
  5. Качете XSL шаблона в библиотеката със стилове.
  6. Задайте свойството "XSL връзка" за уеб частта за списъчен изглед чрез потребителския интерфейс.
  7. Успех!

Нека разгледаме примерен случай на използване и да преминем през реализацията. Нашият клиент искаше да има изглед на основния си списък, който да му подскаже колко време определен елемент от списъка е бил в своето състояние. Този списък съдържаше тип съдържание на сайт по избор, извлечен от типа "Елемент" и добавен към списъка. Вече имаше регистриран получател на събития, който записва всеки път, когато това поле за състояние в елемента от списъка е променено, и записва тази дата в колона, наречена "Дата на промяна на състоянието". Цялото това окабеляване не се изисква и може да се направи с ВСЯКО поле за дата (просто така се случва, че това е нашето изпълнение, но не се колебайте да експериментирате). Минимумът, от който ще се нуждаете, е вашето поле за дата на източник и поле за контейнер, за да добавите изчислението (повече за това в следващия параграф), добавено към списъка ви, въпреки че ви предлагам да използвате колони на сайт и типове съдържание на сайт, в случай че искате да използвате отново това решение на други места във вашия сайт.

Така имаме нашата изходна дата, която можем да използваме в изчислението спрямо днешната дата. Сега можем да създадем колона за сайт по избор, която да използваме като контейнер за нашата изчислена стойност. В този случай избрах да използвам изчисляема колона, тъй като тя няма да може да се променя във формулярите за нови или редактиране на елементи, но ще може да бъде избрана за показване в изгледите, тъй като не искаме потребителите да въвеждат произволни стойности в тази колона. Може да е объркващо защо не се показва в изгледите и т.н.

След като вече имаме нашата колона "Сайт", можем да я добавим към нашите типове съдържание, които ще се използват в списъка ни. След това трябва да създадем наш изглед, който по-късно ще бъде персонализиран с нашия XSLT. Уверете се, че сте създали стандартен изглед, съдържащ вашата колона с дата на източника и вашата нова изчисляема колона, която ще действа като контейнер за изчисляемата стойност.

Сега разполагаме с всичко, което ще ни е необходимо, за да поддържаме нашия персонализиран отчет за стареене. Остава само да създадем нашия XSL шаблон, да го качим в библиотеката със стилове на сайта и да го свържем с нашия списъчен изглед. XSL шаблонът, който ще използваме, ще съдържа нормална коректура, генерирана от SharePoint за генериране на изгледа, както и нашата собствена персонализирана коректура, използвана за заместване на определени части от това и изчисляване на желаната стойност за нас.

Отдавайки дължимото, XSL шаблоните за извършване на действителните изчисления, които използвам за това решение, бяха любезно предоставени от "вихър" във форумите на MSDN:
http://social.msdn.microsoft.com/Forums/en-US/sharepointcustomization/thread/aeda905b-9bc6-40c4-bd22-21306c5cb0d2/

Изтеглете XSL листа със стилове (aging.zip), който събрах тук:
https://OneDrive.live.com/?cid=c262e8e2d59a86d9&permissionsChanged=1&id=C262E8E2D59A86D9!104

Като отворите това в любимия си текстов редактор, ще видите много нормални XSL корекции на SharePoint за рендиране на изгледите, а ако продължите да превъртате надолу до ред 357, ще видите началото на шаблоните по избор, които добавих към коректурата, като първият беше шаблонът "DateDiff", последван от "calculate-julian-day" и "FieldRef_printTableCell_EcbAllowed.Days_x0020_At_x0020_Status". Това са нашите три шаблона, които ще правят и показват нашите изчисления в нашите изгледи. Ако ще използвате различни имена на полета от указаните по-рано в тази статия, ще трябва да преминете през тези шаблони и да заместите всички препратки към другите имена. Не забравяйте, че за това ще искате да използвате ВЪТРЕШНОТО име на полето, а не показваното име.

След като сте доволни и смятате, че шаблонът е готов за работа, отидете във вашата библиотека със стилове и го качете под папката "XSL листове със стилове", след което копирайте надолу връзката във файла. Това ще ни позволи лесно да правим промени в него по-късно или да го добавяме към различни части на сайта, както пожелаем.

След това отидете на вашия списък и изберете изгледа, който създадохте по-рано в тази статия. От менюто "Действия за сайта" щракнете върху "Редактиране на страница".

Команда

Намерете вашата уеб част за списъчен изглед на страницата и отворете менюто на уеб частта, като щракнете върху малката стрелка надолу в горния десен ъгъл. От това меню изберете "Редактиране на уеб част".

Командата за редактиране на уеб част в менюто

Това ще отвори менюто на уеб частта от дясната страна на прозореца на браузъра.

Меню на уеб компонент

Щракнете върху + за секцията "Разни" и намерете свойството "XSL връзка".

Свойството

Поставете връзката към вашия XSL файл в библиотеката със стилове, която копирахте по-рано (това може да бъде относителна или абсолютна връзка).

Поставена връзка към XSL файл

Щракнете върху "OK", за да запишете промените, след което щракнете върху бутона "Спиране на редактирането" на лентата "Страница" в горната част на страницата.

Бутон за спиране на редактирането на раздела

Ако всичко е конфигурирано правилно, сега би трябвало да виждате числа в колоната "Дни в състояние".

Колона

И накрая, ето как би изглеждало с някои тестови данни с различни дати:

Отчет за стареене, който показва тестови данни

Обобщение:

Ето го: добре форматиран, стабилен и по-добре работещ начин за създаване на отчет за остаряне в SharePoint, допълнен с проста реализация без писане на програмен код. Това има доста потенциални приложения, освен единия случай на употреба, който разгледахме тук. Друг често срещан сценарий за този тип отчет е прикачването му към списък със задачи, така че да можете да видите с един поглед колко време е изминало от създаването на дадена задача.

Наслаждавайте се!

--Джъстин

Джъстин Джойс, LANtek

Коментари

Липсващи стъпки
8.10.2012 г. 3:51 ч.
Добре, следвах стъпките, но сигурно нещо липсва - как XSL ще знае коя дата да използва или в кое поле да добави дните след това? Мразите, когато стъпките са пропуснати.

Без код, съгласен съм!
30.8.2012 г. 12:12 ч.
Съгласен съм - не мисля, че това наистина се брои за "без код".
Интересното е, че поради някаква грешка в SharePoint имам работеща изчисляема колона, използваща Today... не съм сигурен как или защо, защото не мога да го накарам да го направи отново, но този все още е там и работи.

Формула за изчисляема колона "Дни в състояние"?
2.5.2012 г. 7:39 ч.
Джъстин: Каква е формулата, която използвахте за вашата колона с изчисляеми сайтове "Дни в състояние" (колона контейнер)? Беше ли "=днес"?

SharePoint 2007
2.12.2011 г. 11:29 ч.
В момента не съм се опитвал да приложа това решение към SharePoint 2007, но го разглеждам. За съжаление, няма свойство XslLink, показано в уеб частта чрез потребителския интерфейс.

Чудесна публикация
30.11.2011 г. 9:53 ч.
Здравейте,
Страхотна публикация.
Използвам SharePoint 2007.
Нямам раздел Misc, както беше отбелязано по-горе.
Имате ли стъпки за конфигуриране на SP2007?
Благодарим ви.

Re: Решение без код: Показване на дните, откакто елемент от списък на SharePoint е бил последно променен
11.10.2011 г. 8:24 ч.
Здравей, Крис.
Страхотна находка!
Ще разгледам какво публикувахте, надявам се, по-късно днес, и ще видя дали мога да направя това решение малко по-стабилно.
Радвам се, че публикацията ви хареса и много се радвам, че успяхте да намерите решение за европейския формат на датата. :)
-Джъстин

Решение за европейски формати на датата
11.10.2011 г. 6:45 ч.
Здравейте отново Джъстин,
За ваша информация, намерих решение на проблема, който споменах по-рано на тази страница;
https://sharepointbydummies.wordpress.com/2011/07/13/possible-work-around-to-date-format-issue-sharepoint-2010/

Европейски формати за дата
7.10.2011 г. 3:59 ч.
Здравейте, Джъстин,
Това е наистина добро решение, благодаря, и точно нещото, което прекарах последните два дни в търсене! Въпреки това имам малък проблем с това и се надявах, че можете да ми помогнете.
Промених леко кода ви, за да калкултирам броя на дните, докато нещо се случи, а не след това, като превключих променливите в последния ред на функцията "DateDiff";

<xsl:value-of select="$JulianToday - $JulianStartDate"></xsl:value-of>

Въпреки това, успявам да го накарам да определи правилно разликата само през половината от времето. Така например с тази дата (формат дд/ММ/гггг);

30/12/2011

Изчислява се правилно, но с тази дата (същия формат)

12/10/2011

Изчислява се като 10 декември 2011 г. вместо 12 октомври 2011 г.
Опитах се просто да превключа позициите на стойностите за ден и месец в променливата "JulianStartDate", ето така;

<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)"/>

И това коригира проблема с втората дата, но след това беше неправилен за първата дата!
Опитах се също така да променя FormatDateTime повиквания, за да се използват европейски LCID и различни промени на последния параметър на FormatDateTime (например ddMMyyyy, MMddyyyy) със съответните корекции на позиционните параметри на подниза без успех.
Ще съм много благодарен за всеки съвет, който можете да предложите.
Благодаря,
Крис

No-Code
21.9.2011 г. 4:27 ч.
Не мисля, че XSL се квалифицира като "no-code" решение, тъй като разбирането на езика XSL не е за всеки - но не включва програмиране. Освен това: Добро решение, благодаря!