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