Джастин Joyce (Justin Joyce), LANtek
Примечание
Эта статья входит в коллекцию записей, опубликованных за четыре года в блоге Get the Point для конечных пользователей SharePoint.
Обзор: создание собственных отчетов по срокам без программирования
Одной из часто запрашиваемых функций сайта SharePoint является отчет по срокам для задач и элементов списков. Другими словами, пользователям интересно знать, сколько дней и месяцев прошло с момента последнего изменения элемента списка.
На первый взгляд, этот запрос кажется очень простым. У нас есть даты создания и изменения элементов, а также возможность сохранять настраиваемые даты при определенных изменениях элементов с помощью приемников событий. Также существуют вычисляемые столбцы, которые могут включать формулы в стиле Excel для работы с информацией. На первый взгляд, все очень просто. Нужно выбрать поле даты, создать вычисляемый столбец, а затем ввести примерно такую формулу, как [DateField] – [Сегодня]. К сожалению, это не сработает. Любой, кто пытался решить эту "простую" задачу, знает, что попытка использовать что-то вроде [Сегодня] в вычисляемом столбце вызывает проблемы. Если попытаться вставить [Сегодня] в поле формулы вычисляемого столбца, появится сообщение об ошибке примерно такого содержания:
Почему это происходит? Это связано с тем, как вычисляются столбцы .
Возьмем для примера простую формулу:
= ЕСЛИ( [Столбец1]<=[Столбец2], "ОК", "Не ОК")
Она означает, что если значение "Столбец1" не больше значения "Столбец2", нужно вывести "ОК", а в противном случае — "Неверно". Это типичная простая формула для вычисляемого столбца, которая предполагает следующее об элементе списка, содержащем эти столбцы: значения "Столбец1" и "Столбец2" никогда не смогут изменяться без обновления элемента списка.
Верно, вычисляемые столбцы пересчитываются только при обновлении (или создании) списка, так как предполагается, что вычисляемые сведения содержатся в самом элементе. Это создает проблему, когда вы пытаетесь использовать что-то, что изменяется независимо от полей элемента, например текущую дату.
Я не был на совещании, где они решили, что вычисляемые столбцы будут работать именно так, однако, если бы мне пришлось сделать обоснованное предположение, я бы предположил, что они работают таким образом для производительности. Представьте, что у вас есть список из нескольких тысяч элементов, каждый из которых содержит вычисляемый столбец, нуждающийся в «живом» обновлении. Это означает, что некий алгоритм, возможно, задание таймера, должен был бы регулярно выполнять итерацию по всем элементам с вычисляемыми столбцами и обновлять их значения. Это бы значительно ухудшило производительность, так как при крупных развертываниях это задание бы постоянно выполнялось и вносило изменения. Это всего лишь мое предположение, но это имеет довольно много смысла, если подумать.
В Интернете можно найти похожие решения, которые позволяют обмануть SharePoint и заставить его принять значение "Сегодня", создав столбец с именем "Сегодня, "добавив его в формулу, а затем удалив его. Это решение сработает, но не забывайте, что я говорил о том, когда обновляются вычисляемые столбцы. Это значение будет изменяться только при обновлении элемента и поэтому скоро станет неверным, особенно в случае вычисления дня.
Я видел, как другие используют умный JavaScript для записи значений на страницу. Это также сработает, но я категорически против использования клиентских сценариев, когда этого можно избежать.
Реализация:
Так что же делать? Вычисляемые столбцы не обсуждаются для так называемых "изменчивых" функций, таких как Today. Возможно, мы могли бы разработать какой-то пользовательский код, чтобы позаботиться об этом за нас, например, вычисляемый столбец, задание таймера или запланированный процесс, чтобы обновлять каждый элемент, который нуждается в этом расчете. Это возвращает нас к проблеме производительности, о которой я упоминал в последнем абзаце, и, кроме того, это хрупкое решение, которое будет очень специфичным для рассматриваемого сайта/списка/столбца. Помимо этих двух проблем, вам также нужно будет найти занудного парня, такого как я, который знает, как программировать, и убедить его разработать это решение для вас. Но есть более простой способ!
Если у вас есть права на создание полей и редактирование страниц на сайте, а также немного знаний о XSLT и создании представлений, вы можете создать шаблон XSL, добавить его в представление списка, и он будет вычислять значение при каждом запросе страницы. Этот сценарий устраняет нашу проблему с производительностью и не требует разработки и развертывания пользовательского кода с помощью решения.
Разве это не идеал? Так что же нужно сделать?
- Создайте или выберите поле, которое будет являться источником. Оно должно иметь тип даты.
- Создайте поле, которое будет являться заполнителем для вычисляемого значения.
- Добавьте оба поля в тип контента, а затем добавьте тип контента в список.
- Создайте представление этого списка, содержащее исходный столбец и столбец-заполнитель.
- Добавьте шаблон XSL в библиотеку стилей.
- Установите свойство "XSL Link" для веб-части представления списка с помощью пользовательского интерфейса.
- Готово!
Рассмотрим пример использования и рассмотрим реализацию. Нашему клиенту было нужно представление основного списка, в котором показывалось, как долго определенный элемент списка имел текущее состояние. Список включал данные пользовательского типа контента сайта, который был создан на основе типа "Элемент" и добавлен в список. Уже был установлен приемник событий, который фиксирует каждое изменение поля состояния в элементе списка и сохраняет эту дату в столбце с именем "Дата изменения состояния". Такие настройки не являются обязательными, и способ можно применять для ЛЮБОГО поля даты (в нашей реализации уже были такие настройки, но вы можете попробовать обойтись без них). По минимуму вам потребуются исходное поле даты и поле-заполнитель для хранения результатов вычисления (подробнее об этом в следующем абзаце), которые были добавлены в список, хотя я рекомендую использовать столбцы сайта и типы контента сайта, на случай если вы захотите повторно использовать это решение для других объектов на сайте.
Таким образом, у нас есть исходная дата, которую мы можем использовать в наших расчетах с сегодняшней датой. Теперь мы можем создать пользовательский столбец сайта, который будет использоваться в качестве контейнера для вычисленного значения. В этом случае я решил использовать вычисляемый столбец, поскольку его нельзя будет изменить в формах создания или редактирования элементов, но его можно выбрать для отображения в представлениях, поскольку мы не хотим, чтобы пользователи вводили произвольные значения в этот столбец. Могут возникать вопросы о том, почему он не отображается в представлениях, и т. д.
Теперь, когда у нас есть столбец сайта, мы можем добавить его к типам контента, которые будут использоваться в списке. Затем нужно создать представление, которое мы позже настроим с помощью XSLT. Обязательно создайте стандартное представление, содержащее исходный столбец даты и новый вычисляемый столбец, который будет использоваться в качестве заполнителя для вычисленного значения.
Мы создали все, что нужно для настраиваемого отчета по срокам. Осталось только создать наш шаблон XSL, загрузить его в библиотеку стилей сайта и связать его с нашим представлением списка. Шаблон XSL, который мы будем использовать, будет содержать обычную разметку SharePoint для создания представления, а также нашу собственную разметку, переопределяющую ее некоторые части и вычисляющую нужное значение.
Надо отдать должное, шаблоны XSL для выполнения фактических вычислений, которые я использую для этого решения, были любезно предоставлены "swirch" на форумах 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
Открыв его в своем любимом текстовом редакторе, вы увидите множество обычной разметки SharePoint XSL для отрисовки представлений, если вы продолжите прокручивать вниз до строки 357, вы увидите начало пользовательских шаблонов, которые я добавил в разметку, первым из которых является шаблон "DateDiff", за которым следуют "calculate-julian-day" и "FieldRef_printTableCell_EcbAllowed.Days_x0020_At_x0020_Status". Это три шаблона, которые позволяют создавать и отображать вычисления в наших представлениях. Если вы собираетесь использовать имена полей, отличные от тех, которые были указаны ранее в этой статье, необходимо просмотреть эти шаблоны и заменить ссылки на другие имена. Помните, что для этого нужно использовать ВНУТРЕННЕЕ имя поля, а не отображаемое имя.
Убедившись, что шаблон готов к использованию, перейдите в библиотеку стилей и загрузите его в папку «Таблицы стилей XSL», а затем скопируйте ссылку на файл. Это позволит при желании легко вносить в него изменения или добавлять его в различные части сайта.
Затем перейдите к списку и выберите представление, которое вы создали выше в этой статье. В меню «Действия сайта» выберите «Изменить страницу».
Найдите на странице веб-часть представления списка и откройте меню веб-части, щелкнув маленькую стрелку вниз в правом верхнем углу. В этом меню выберите "Изменить веб-часть".
В правой части окна браузера откроется меню веб-части.
Щелкните + для раздела "Разное" и найдите свойство "XSL Link".
Вставьте ссылку в XSL-файл в библиотеке стилей, который вы скопировали в нее (ссылка может быть относительной или абсолютной).
Нажмите кнопку "ОК", чтобы сохранить изменения, а затем нажмите кнопку "Остановить редактирование" на ленте "Страница" в верхней части страницы.
Если все было настроено правильно, вы должны увидеть числа в столбце «Состояние в днях».
Вот как страница выглядит с различными тестовыми датами:
Сводка
Итак, вот он: надежный способ создания отчета по возрасту элементов в SharePoint, обеспечивающий привлекательное форматирование и хорошую производительность, а также не требующий программирования для реализации. Он может пригодиться в различных ситуациях в дополнение к той, которую мы здесь рассмотрели. Другой распространенный сценарий для этого типа отчета — прикрепление его к списку задач, чтобы вы могли сразу увидеть, сколько времени прошло с момента создания задачи.
Надеюсь, вам понравилась эта статья.
-Джастин
Джастин Joyce (Justin Joyce), LANtek
Комментарии
Отсутствуют шаги
08.10.2012 г. 3:51
Итак, я выполнил инструкции, но, должно быть, чего-то не хватает - как XSL узнает, какую дату использовать или в какое поле добавить дни с тех пор? Ненавидь, когда шаги пропускаются.
No-Code, договорились!
30.08.2012 12:12
Я согласен - я не думаю, что это действительно считается "без кода".
Интересно, что благодаря какой-то ошибке в SharePoint у меня есть работающий вычисляемый столбец с "Сегодня"... Не знаю, как и почему это произошло, так как больше этот фокус не проходит, но старый столбец на месте и работает.
Формула для вычисляемого столбца "Дни в статусе"?
02.05.2012 г. 7:39
Джастин: Какую формулу вы использовали для вычисляемого столбца сайта "Дни в статусе" (столбец-заполнитель)? Может быть, "=today"?
SharePoint 2007
02.12.2011 11:29
В настоящее время я не пытался применить это решение к SharePoint 2007, однако я изучаю его. К сожалению, свойство XslLink недоступно в веб-части через пользовательский интерфейс.
Отличный пост
30.11.2011 г. 9:53
Здравствуйте!
Отличный пост.
Я использую SharePoint 2007.
У меня нет раздела "Разное", как указано выше.
Есть ли у вас инструкции по настройке 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/
Европейские форматы дат
07.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) с соответствующими корректировками позиционных параметров подстроки.
Я был бы рад твоему совету.
Благодарю за внимание,
Крис (Chris)
No-Code
21.09.2011 4:27
Я не думаю, что XSL можно квалифицировать как решение "без кода", так как понимание языка XSL не для всех, однако оно не включает в себя программирование. За исключением этого, отличное решение, спасибо!