Как настроить фильтр по вычисляемому полю в динамическом списке Управление отгрузкой в УТ 11?

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

При работе с комплексными рабочими местами в 1С:Управление торговлей 11, такими как Управление отгрузкой на ордерном складе, разработчики часто сталкиваются с необходимостью кастомизации списков. Одной из типичных задач является добавление информации о наличии документов-оснований для расходных ордеров и последующая фильтрация по этому признаку. Однако стандартный подход через событие ПриПолученииДанных в данном случае заводит в тупик: визуально колонка заполнена, а фильтр по ней не работает. Разберем подробно, почему так происходит и как правильно решить эту задачу.

Анализ проблемы: почему OnGetData не подходит для фильтрации

Рассмотрим архитектуру работы динамического списка. Когда мы открываем форму, платформа 1С формирует SQL-запрос к базе данных, получает порцию данных и отображает их. Событие ПриПолученииДанных (OnGetData) или ПриВыводеСтроки (в старых версиях) срабатывает уже после того, как основные данные получены из базы. Это чисто визуальный слой оформления ячеек на форме.

Когда мы накладываем отбор через КомпоновщикНастроек или программный метод УстановитьЭлементОтбораДинамическогоСписка, платформа пытается модифицировать SQL-запрос, добавляя в него секцию WHERE. Проблема заключается в том, что сервер базы данных «ничего не знает» о тех значениях, которые вы программно вычислили и подставили в колонки на клиенте. Для сервера этих данных просто не существует в таблицах. Именно поэтому, даже если вы видите в ячейке значение Ложь, фильтр по этому значению будет игнорироваться или возвращать пустой результат.

Решение №1: Модификация запроса динамического списка

Чтобы фильтрация стала возможной, поле должно присутствовать в тексте запроса динамического списка. Только тогда компоновщик компоновки данных (СКД) сможет передать условие отбора в итоговый запрос к СУБД. Разберем по шагам, как это реализовать в расширении для формы управления отгрузкой.

  1. Создадим расширение для конфигурации и добавим в него форму обработки УправлениеОтгрузкой.
  2. Найдем динамический список ОрдераВРаботе.
  3. В свойствах списка перейдем к редактированию текста запроса. Нам нужно включить флаг Произвольный запрос.
  4. В тексте запроса нам необходимо связать таблицу расходных ордеров с их основаниями. Проанализируем ситуацию: распоряжением у РасходныйОрдерНаТовары может быть заказ, накладная или перемещение.

Пример модифицированного запроса для динамического списка:


ВЫБРАТЬ
    ТаблицаОрдеров.Ссылка КАК Ссылка,
    ТаблицаОрдеров.Дата КАК Дата,
    ТаблицаОрдеров.Номер КАК Номер,
    ВЫБОР
        КОГДА ДокументыОснования.Ссылка ЕСТЬ NULL ТОГДА ЛОЖЬ
        ИНАЧЕ ИСТИНА
    КОНЕЦ КАК ЕстьСсылкаНаДокумент
ИЗ
    Документ.РасходныйОрдерНаТовары КАК ТаблицаОрдеров
    ЛЕВОЕ СОЕДИНЕНИЕ Документ.РеализацияТоваровУслуг КАК ДокументыОснования
        ПО ТаблицаОрдеров.Распоряжение = ДокументыОснования.Ссылка
// Здесь могут быть дополнительные соединения для других типов распоряжений

После добавления поля ЕстьСсылкаНаДокумент непосредственно в ВЫБРАТЬ, оно становится полноправным участником выборки. Теперь мы можем использовать стандартные механизмы отбора.

Решение №2: Программная установка отбора

После того как поле добавлено в запрос, мы можем наложить фильтр программно, например, в событии ПриСозданииНаСервере или по нажатию кнопки. Рассмотрим пример кода, который использует типовые механизмы БСП (Библиотеки стандартных подсистем):


// Используем стандартную процедуру из общего модуля
ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбораДинамическогоСписка(
    ОрдераВРаботе, 
    "ЕстьСсылкаНаДокумент", 
    Ложь, 
    ВидСравненияКомпоновкиДанных.Равно,
    "Ордера без оснований",
    Истина
);

Если же мы хотим действовать через низкоуровневые настройки компоновщика, проанализируем следующий пример:


ЭлементОтбора = ОрдераВРаботе.КомпоновщикНастроек.ФиксированныеНастройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ЕстьСсылкаНаДокумент");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбора.ПравоеЗначение = Ложь;
ЭлементОтбора.Использование = Истина;

Важный нюанс: использование ФиксированныеНастройки предпочтительнее, если вы не хотите, чтобы пользователь мог случайно отключить или изменить этот отбор через стандартное меню настройки списка.

Особенности ордерного склада в УТ 11

Разберем специфику именно этой конфигурации. В обработке Управление отгрузкой список ордеров часто зависит от выбранного склада и текущей вкладки (Распоряжения, Ордера и т.д.). Система может динамически перестраивать текст запроса в коде модуля формы.

Проанализируем процедуру ПриАктивизацииСтроки или методы обновления списков в этой обработке. Если ваш отбор «слетает» после переключения вкладок, проверьте, не вызывается ли метод ОрдераВРаботе.ТекстЗапроса = ... где-то в недрах типового кода. В этом случае вам придется перехватывать момент установки текста запроса через &После в расширении и внедрять туда свое поле ЕстьСсылкаНаДокумент повторно.

Производительность и оптимизация

Выясним причину возможного замедления списка. Если на складе десятки тысяч ордеров, использование ЛЕВОЕ СОЕДИНЕНИЕ в динамическом списке может сказаться на скорости открытия формы.

Рекомендации по оптимизации:

  1. Убедитесь, что поле, по которому идет соединение (например, Распоряжение), проиндексировано.
  2. Вместо соединения с тяжелыми таблицами документов, попробуйте использовать проверку типа ссылки через ССЫЛКА, если логика позволяет определить наличие основания без соединения.
  3. Если задача стоит только в определении "пустое основание или нет", иногда достаточно проверить встроенный реквизит Распоряжение на значение НЕОПРЕДЕЛЕНО или NULL прямо в условии отбора, не добавляя новых колонок в запрос.

Подведем итог: для корректной работы фильтров в 1С всегда придерживайтесь правила — данные для фильтрации должны поступать из запроса, а не из визуального оформления. Метод ПриПолученииДанных отлично подходит для раскраски строк (например, выделить красным ордера без документов), но совершенно бесполезен для поиска и отбора этих строк в базе данных.

← На главную