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