При разработке отчетов в Системе компоновки данных (СКД) (поможет консоль запросов и СКД для разработчика) часто возникает задача предоставить пользователю возможность фильтровать данные не по конкретному документу (ссылке), а по его типу. Например, если отчет строится по регистру накопления, в котором регистраторами выступают ПоступлениеТоваровУслуг, РеализацияТоваровУслуг и ПеремещениеТоваров, пользователю может понадобиться увидеть данные только по реализациям. Рассмотрим несколько эффективных способов решения этой задачи, проанализируем типичные ошибки и разберем программные методы автоматизации процесса.
Этот метод является наиболее простым в реализации и интуитивно понятным для конечного пользователя. Суть заключается в том, чтобы на уровне запроса преобразовать тип документа в строку, по которой система сможет выполнить группировку или отбор.
Рассмотрим пример запроса (для анализа структуры которого пригодится процессор схемы запроса), где мы извлекаем данные из виртуальной таблицы остатков и оборотов. Мы добавим специальное поле, которое будет содержать строковое представление типа регистратора:
ВЫБРАТЬ
МатериалыОстатки.Регистратор КАК Документ,
МатериалыОстатки.Номенклатура КАК Номенклатура,
МатериалыОстатки.КоличествоКонечныйОстаток КАК Остаток,
ПРЕДСТАВЛЕНИЕ(ТИПЗНАЧЕНИЯ(МатериалыОстатки.Регистратор)) КАК ТипДокумента
ИЗ
РегистрНакопления.МатериалыНаОбъекте.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, Запись, , ) КАК МатериалыОстатки
В настройках СКД на вкладке "Отбор" теперь можно выбрать поле ТипДокумента. Система автоматически соберет все уникальные названия типов документов, и пользователь сможет выбрать нужные из списка. Важный нюанс: использование функции ПРЕДСТАВЛЕНИЕ в условиях ГДЕ (или сравнение строки с представлением ссылки) может замедлять работу запроса на больших объемах данных, так как это требует вычисления строкового значения для каждой записи.
Если мы хотим, чтобы пользователь выбирал именно объект метаданных (тип), а не просто строку, нам следует использовать возможности параметров СКД. Это более "чистый" подход с точки зрения архитектуры 1С.
Разберем ситуацию по шагам:
ВыбранныйТипДокумента.ОписаниеТипов.Теперь отредактируем запрос, добавив условие фильтрации:
ВЫБРАТЬ
Данные.Регистратор,
Данные.Количество
ИЗ
РегистрНакопления.Продажи КАК Данные
ГДЕ
ТИПЗНАЧЕНИЯ(Данные.Регистратор) = &ВыбранныйТипДокумента
При таком подходе в пользовательском режиме при нажатии на выбор параметра откроется стандартное окно выбора типа данных, где будут перечислены документы. Однако стоит помнить, что если параметр не заполнен, отчет может вернуть пустой результат. Чтобы этого избежать, в выражении параметра или в настройках отбора следует предусмотреть проверку на незаполненное значение.
Проанализируем ситуацию, когда типов документов немного (3-5 штук). В этом случае эффективнее использовать оператор ССЫЛКА. Он работает быстрее, чем ТИПЗНАЧЕНИЯ, так как транслируется платформой в более простой SQL-запрос (проверка таблицы по внутреннему идентификатору типа).
Мы можем создать вычисляемое поле или использовать логику в запросе для присвоения понятных имен:
ВЫБРАТЬ
Регистратор,
ВЫБОР
КОГДА Регистратор ССЫЛКА Документ.ПоступлениеТоваровУслуг ТОГДА "Поступление"
КОГДА Регистратор ССЫЛКА Документ.РеализацияТоваровУслуг ТОГДА "Реализация"
ИНАЧЕ "Прочие документы"
КОНЕЦ КАК ВидОперации
ИЗ
РегистрНакопления.ТоварыНаСкладах
Это позволяет жестко типизировать отбор и избежать ошибок, связанных с изменением синонимов документов в конфигурации.
Иногда список документов в конфигурации часто меняется, и мы не хотим каждый раз вручную обновлять список "Доступных значений" в параметрах СКД. Выясним, как автоматизировать этот процесс с помощью встроенного языка.
Для этого в модуле отчета воспользуемся событием ПриКомпоновкеРезультата. Нам нужно получить доступ к параметру схемы и заполнить его список доступных значений актуальными данными из метаданных:
Процедура ПриКомпоновкеРезультата(ДанныеРасшифровки, СтандартнаяОбработка)
// Получаем схему
Схема = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
Параметр = Схема.Параметры.Найти("ВыбранныйТип");
// Очищаем старые значения
Параметр.ДоступныеЗначения.Очистить();
// Перебираем метаданные документов
Для Каждого Док Из Метаданные.Документы Цикл
// Здесь можно добавить фильтр по принадлежности к регистру
Параметр.ДоступныеЗначения.Добавить(Тип("ДокументСсылка." + Док.Имя), Док.Синоним);
КонецЦикла;
КонецПроцедуры
Этот код гарантирует, что пользователь всегда будет видеть актуальный список документов с их человекочитаемыми названиями (синонимами). В качестве Значения мы передаем сам тип, а в качестве Представления — синоним из метаданных. Это решает проблему "цифр вместо названий", упомянутую в обсуждении на форуме.
Рассмотрим ситуацию, когда программист настраивает отбор Регистратор В (&СписокТипов), но при выполнении отчет оказывается пустым. Причина кроется в подмене понятий "Тип" и "Ссылка".
Когда в СКД выбирается тип данных ДокументСсылка.РеализацияТоваровУслуг, система ожидает конкретный экземпляр документа (конкретную накладную). Если же мы хотим сравнивать именно типы, то тип параметра должен быть строго "Тип" (объект метаданных). Если в запросе используется ТИПЗНАЧЕНИЯ(Поле), то и в параметре должно лежать значение, полученное функцией Тип("ДокументСсылка.ИмяДокумента"), а не пустая ссылка на этот документ.
Подводя итог, выделим лучшие практики:
ПРЕДСТАВЛЕНИЕ(ТИПЗНАЧЕНИЯ(...)).ССЫЛКА предпочтительнее в условиях ГДЕ, если перечень типов заранее известен и ограничен.Применяя эти методы, мы сможем создать гибкий и удобный интерфейс для пользователей, позволяя им анализировать данные в разрезе различных хозяйственных операций без необходимости выбирать каждый документ по отдельности.