SSRS. Уникальные значения из списка SharePoint
При создании отчетов с помощью Report Builder'а или BI DevStudio (читай "Visual Studio") в качестве источника данных можно использовать списки и/или библиотеки документов, расположенные на сайте SharePoint. Для извлечения данных в этом случае используются CAML-запросы, что означает отсутствие стандартного механизма получения уникальных значения столбца.
А необходимость такая есть, хотя бы для заполнения списков параметров:
Диспозиция
Итак, имеем отчет со списком SharePoint в качестве источника данных (DataSource), набор данных (DataSet), выбирающий значения из одного столбца списка/библиотеки и параметр (Parameter), который отображает (должен отображать) уникальные значения из набора данных.
Если запустить отчет как есть, то в выпадающем списке параметра мы увидим дубликаты значений (см. картинку выше). Т.е. ровно то, что возвращает набор данных:
System.Linq
Чтобы обработать данные перед тем как передавать их параметры нам надо "пропустить" их через функцию (VB.NET уже близок), которая отсортирует переданный ей массив и удалит из него дубликаты.
Для таких случаев отчет позволяет использовать свой код либо в виде сборки, с указанием ссылки на неё, либо в виде простого текста. В случае с текстом писать придется на VB.NET, т.к. поддержка C# здесь не реализована.
Установка построителя отчетов (Report Builder) ровно как и Visual Studio 2010 требует наличия .Net Framework 3.5, что позволяет нам смело использовать Linq. Сначала добавим ссылку на сборку System.Core:
Теперь, перейдя к вкладке Код (Code), укажем свою статическую функцию, принимающую параметр отчета и возвращающая уникальные значения из этого параметра:
- Public Shared Function GetUniqueValues(parameter As Parameter) As String()
- Dim items As Object() = parameter.Label
- System.Array.Sort(items)
- Dim res As [String]() = System.Linq.Enumerable.ToArray(System.Linq.Enumerable.Cast(Of String)(System.Linq.Enumerable.Distinct(items)))
- Return res
- End Function
Если надо использовать не текст параметра, а его значения, то вместо свойства Label надо использовать Value. Должно получится примерно вот так:
Брать значения из набора данных при использовании выражений (Expression) в параметрах нельзя. В результате мы имеем два параметра: один скрытый параметр, который извлекает данные из набора данных, второй - фильтрующий эти данные и отображающий их пользователю:
Производительность в таком случае будет проседать на больших списках, но другого пути я придумать не мог. Могу только добавить, что долгое время ожидания построения отчета может быть заменено на подписку. Что позволяет получать оперативную отчетность, например на электронную почту в формате PDF каждое утро в 8:30.
Пользователю не придется "гоняться" за информацией и сидеть в ожидании. Информация сама придет к нему в удобное для него время. К тому же корпоративная почта доступна почти всегда, чего нельзя сказать о корпоративном портале.
Файл демонстрационного отчета можно скачать здесь.