При работе в конфигурациях на базе 1С:ERP (УТ 11, КА 2, ERP) пользователи часто сталкиваются с тем, что в справочнике Партнеры отбор по сегментам работает гибко, включая динамические сегменты, а в справочнике Номенклатура — нет. Давайте разберем, почему разработчики 1С приняли такое решение, как устроена архитектура хранения сегментов и какими способами можно обойти это ограничение, чтобы сделать работу пользователей удобной.
Для начала проанализируем, чем отличаются способы формирования сегментов в системе. В типовых решениях предусмотрено три основных варианта:
Рассмотрим техническую сторону. Когда мы выбираем способы «Вручную» или «Периодически», система записывает данные в специализированный регистр сведений НоменклатураСегмента. Форма списка справочника Номенклатура в своем динамическом списке имеет заранее настроенную связь с этим регистром. Это позволяет выполнять отбор мгновенно, так как СУБД просто сопоставляет две таблицы.
В случае с динамическим сегментом таблицы в базе нет. Есть только схема компоновки данных (СКД), которая должна выполниться, чтобы получить список GUID товаров. Наложить такой «виртуальный» список на динамический список справочника, где могут быть сотни тысяч записей, — крайне ресурсоемкая задача.
Выясним причину такой избирательности. Ответ кроется в производительности и типичных объемах данных. Количество партнеров (клиентов и поставщиков) в средней базе редко превышает несколько тысяч или десятков тысяч записей. Выполнение вложенного запроса для динамического сегмента в списке партнеров не вызывает критических зависаний интерфейса.
Справочник Номенклатура — самый нагруженный объект в торговых системах. Помимо огромного количества записей, форма списка постоянно обрабатывает остатки, цены, характеристики и упаковки. Добавление к этому массиву еще и динамического расчета сегмента при каждом скроллинге или поиске привело бы к тому, что работа со списком товаров стала бы невозможной из-за постоянных «фризов» интерфейса. Именно поэтому разработчики 1С на уровне кода ограничили выбор только теми сегментами, данные по которым уже лежат в регистре НоменклатураСегмента.
Это самый правильный способ с точки зрения типовой логики системы. Мы переводим сегмент из динамического режима в режим хранимых данных, но автоматизируем процесс обновления.
Разберем по шагам:
Очистка и заполнение сегментов номенклатуры.После первого выполнения задания данные попадут в регистр, и сегмент станет доступен для выбора в стандартном фильтре списка номенклатуры. Пользователям больше не придется нажимать кнопку «Сформировать» вручную.
Если нам критически важно видеть актуальный состав динамического сегмента «прямо сейчас» (например, после массового изменения реквизитов товаров), лучше использовать отчеты, а не форму списка. Рассмотрим, почему это удобно:
В отчетах, таких как Прайс-лист или Остатки и доступность товаров, используется полноценный механизм СКД. В настройках отчета (через «Изменить вариант») можно добавить отбор по полю Номенклатура.Входит в сегмент. В этом случае система корректно отработает даже динамический сегмент, так как отчет по своей природе предназначен для длительной обработки данных и формирования тяжелых запросов.
Если бизнес-процесс требует именно динамического отбора в форме списка, мы можем реализовать это через расширение конфигурации. Нам потребуется изменить запрос динамического списка Список формы ФормаСписка справочника Номенклатура.
Проанализируем примерный алгоритм действий в коде:
ПриСозданииНаСервере или через изменение текста запроса добавим левое соединение с результатами запроса динамического сегмента.Важный момент: динамические сегменты описываются через СКД, поэтому просто «прилепить» один запрос к другому не получится. Придется программно инициализировать схему сегмента, получать ее текст запроса и вставлять его как вложенный запрос в основной ТекстЗапроса динамического списка.
Пример схемы того, как может выглядеть программная модификация (упрощенно):
// В расширении для формы списка
&НаСервере
Процедура ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
// Получаем текст запроса динамического списка
ТекстЗапроса = Список.ТекстЗапроса;
// Здесь должна быть логика анализа выбранного динамического сегмента
// и внедрение подзапроса в ТекстЗапроса.
// ВНИМАНИЕ: Это существенно замедлит работу формы!
Список.ТекстЗапроса = ТекстЗапроса;
КонецПроцедуры
Важно: Мы крайне не рекомендуем использовать этот метод, если в базе более 50 000 позиций номенклатуры, так как это вызовет недовольство пользователей скоростью работы программы.
Мы выяснили, что отсутствие динамических сегментов в списке номенклатуры — это не ошибка, а осознанное ограничение для обеспечения высокого быстродействия. Чтобы решить задачу автоматизации:
Это позволит сохранить стабильность системы и при этом обеспечит необходимый функционал для анализа товарного ассортимента.