Разработка прикладных решений в среде 1С:Предприятие 8 часто требует от программиста создания гибких интерфейсов, где пользователь должен выбирать конкретные объекты из справочников или документов. В типовых сценариях работы, когда список потенциальных значений содержит тысячи позиций, критически важно ограничить выборку только релевантными данными. Для этого используется механизм открытия формы выбора с заранее настроенным отбором.
Реализация данной функциональности позволяет не только ускорить работу оператора, избавляя его от необходимости вручную искать нужную позицию в огромном списке, но и предотвратить ошибки ввода неверных данных. В рамках платформы 1С 8.3 существуют различные способы вызова таких форм: от использования стандартных процедур до написания собственного кода с применением объекта ФормаВыбора. Мы разберем наиболее эффективные и актуальные методы.
Правильная настройка фильтрации на клиенте или сервере влияет на производительность всей системы. Неоптимизированный код может привести к длительным паузам при открытии окна подбора. В этой статье мы рассмотрим синтаксические конструкции, особенности работы с динамическими списками и способы передачи параметров в форму выбора для различных типов объектов метаданных.
Базовый синтаксис вызова формы выбора
Самый распространенный и простой способ открыть окно подбора — использование встроенной процедуры ВыбратьЗначение. Этот метод является универсальным и поддерживается как в обычных формах, так и в управляемых приложениях. Он позволяет передать в качестве параметров тип значения, текущее значение и, что самое важное для нашей темы, структуру отбора.
Для установки фильтра необходимо создать объект типа Структура или Соответствие, где ключами будут являться имена реквизитов справочника, а значениями — условия фильтрации. Важно понимать, что имена полей должны строго соответствовать именам реквизитов в метаданных, а не заголовкам колонок в табличном документе.
Рассмотрим пример вызова для справочника "Номенклатура", где требуется выбрать товар только определенной группы и с указанием конкретного вида номенклатуры:
Отбор = Новый Структура;
Отбор.Вставить("Владелец", ТекущийВладелец);
Отбор.Вставить("ВидНоменклатуры", Справочники.ВидыНоменклатуры.НайтиПоНаименованию("Товар"));
- 📌 Используйте
Структурадля простых условий равенства реквизитов. - 📌 Применяйте
Соответствие, если ключами выступают сложные типы данных или объекты. - 📌 Убедитесь, что типы данных в отборе совпадают с типами реквизитов справочника.
Если вы передаете в отбор ссылку на объект, убедитесь, что она не пустая. Пустая ссылка в условии отбора может привести к тому, что форма выбора вернет пустой результат, даже если данные существуют.
После формирования структуры отбора она передается третьим параметром в процедуру ВыбратьЗначение. Платформа автоматически преобразует эту структуру в условия запроса, которые будут применены к динамическому списку формы выбора. Это стандартный механизм, который не требует дополнительных настроек со стороны разработчика.
⚠️ Внимание: Имена реквизитов в структуре отбора чувствительны к регистру и должны точно совпадать с именами в конфигураторе. Использование синонимов или заголовков приведет к ошибке выполнения или игнорированию условия фильтрации.
Использование объекта ФормаВыбора для гибкой настройки
В ситуациях, когда стандартной процедуры ВыбратьЗначение недостаточно, разработчики прибегают к прямому созданию объекта ФормаВыбора. Этот подход дает полный контроль над поведением окна, позволяя настраивать не только отбор, но и заголовок, модальность, а также доступные действия пользователя.
Объект ФормаВыбора создается методом ПолучитьФормуВыбора у объекта метаданных или у конкретного объекта ссылки. Основное преимущество этого метода заключается в возможности программного изменения списка доступных команд и кнопок перед показом формы. Вы можете скрыть кнопку создания нового элемента, если бизнес-логика это запрещает.
ФормаВыбора = Справочники.Контрагенты.ПолучитьФормуВыбора();
ФормаВыбора.Заголовок = "Выберите покупателя из списка";
Для установки отбора в этом объекте используется свойство Отбор, которое представляет собой коллекцию условий. В отличие от структуры в ВыбратьЗначение, здесь вы можете задавать сложные условия, включая сравнения "Больше", "Меньше", "В периоде" и логические операторы.
Разница между методами
Метод ВыбратьЗначение проще в реализации и подходит для 90% задач. Объект ФормаВыбора необходим, когда нужно изменить заголовок окна, отключить кнопку "Создать" или добавить свои команды в форму выбора перед её открытием.
После настройки всех параметров форма открывается методом ОткрытьМодально или Открыть. Возвращаемое значение будет содержать выбранный объект или значение типа Неопределено, если пользователь нажал "Отмена". Такой подход требует больше строк кода, но обеспечивает максимальную гибкость интерфейса.
Сложные условия отбора и работа с периодами
Часто бизнес-требования диктуют необходимость фильтрации данных не только по точному совпадению, но и по диапазонам значений или датам. Например, при выборе документа "Реализация" пользователю могут быть интересны только документы за текущий месяц или с суммой выше определенного порога.
Для реализации таких сценариев при использовании объекта ФормаВыбора необходимо добавлять элементы в коллекцию Отбор с указанием вида сравнения. Платформа 1С 8.3 поддерживает enum ВидСравнения, который позволяет гибко настраивать логику фильтрации.
| Вид сравнения | Описание | Пример использования |
|---|---|---|
Равно |
Точное совпадение значения | Выбор конкретного склада |
Больше |
Значение больше указанного | Документы с суммой > 10000 |
ВПериоде |
Значение попадает в интервал | Документы за январь 2026 |
НеРавно |
Исключение конкретного значения | Все товары, кроме "Услуги" |
При работе с датами и периодами важно учитывать часовой пояс и время сервера, если система распределенная. Условие ВПериоде часто используется для отбора документов по дате проведения или создания. Синтаксис предполагает установку свойств Начало и Конец у элемента отбора.
Пример установки отбора по периоду для документа:
ЭлементОтбора = ФормаВыбора.Отбор.Добавить("Дата", ВидСравнения.ВПериоде);
ЭлементОтбора.Использование = Истина;
ЭлементОтбора.Начало = НачалоМесяца(ТекущаяДата());
ЭлементОтбора.Конец = КонецМесяца(ТекущаяДата());
Динамические списки и оптимизация производительности
При открытии формы выбора с отбором система выполняет запрос к базе данных. Если отбор наложен на реквизиты, не имеющие индексов, или если выборка получается слишком большой, интерфейс может "подвисать". Критически важно понимать, как платформа обрабатывает эти условия.
Динамические списки в 1С автоматически оптимизируют запросы, но разработчик должен помогать системе. Избегайте установки отборов по полям, которые вычисляются в моменте или зависят от сложных виртуальных таблиц, если это возможно. Лучше фильтровать по основным регистрационным реквизитам.
Если вы работаете с большими объемами данных, рассмотрите возможность использования ограничения количества выводимых строк. Это можно сделать программно, установив свойство МаксимальноеКоличествоСтрок у формы выбора, хотя стандартными средствами это делается не всегда явно и зависит от версии платформы.
⚠️ Внимание: Установка отбора по полям табличных частей или ресурсам регистров накопления непосредственно в форме выбора может привести к значительному замедлению работы. В таких случаях лучше предварительно отобрать данные запросом и передать пользователю готовый список.
Производительность формы выбора напрямую зависит от наличия индексов в базе данных по полям, используемым в отборе. Проверяйте настройку индексов в конфигураторе для часто фильтруемых реквизитов.
Также стоит помнить о сетевом взаимодействии. Если база данных расположена на удаленном сервере, передача больших объемов данных для первичного отображения списка перед наложением клиентского фильтра может занять время. Серверный отбор всегда предпочтительнее клиентского.
Особенности открытия формы выбора в управляемых формах
В режиме управляемого приложения (УФ) существует специфика работы с формами выбора. Здесь важно различать контекст выполнения кода: клиент или сервер. Процедура ВыбратьЗначение является клиентской, и все вычисления для формирования отбора должны происходить на стороне клиента.
Попытка вызвать эту процедуру из серверного модуля объекта или модуля менеджера приведет к ошибке выполнения. Если данные для отбора хранятся на сервере, их необходимо предварительно передать в клиентский контекст через параметры формы или глобальные переменные сеанса.
Кроме того, в управляемых формах существует понятие "список выбора" как отдельного объекта. Вы можете программно управлять видимостью колонок в форме выбора, скрывая лишние поля, чтобы не загромождать интерфейс пользователя. Это делается через свойство СписокВыбора объекта формы.
☑️ Чек-лист перед открытием формы
Для сложных сценариев, когда состав отбора зависит от прав доступа пользователя, рекомендуется использовать механизм RLS (ограничение доступа на уровне записей) в сочетании с формой выбора. Это гарантирует, что пользователь не увидит те данные, к которым у него нет прав, даже если попытается изменить отбор вручную в форме.
Обработка результатов и возврат значений
После того как форма выбора была закрыта пользователем, необходимо корректно обработать результат. Если был выбран объект, он возвращается как значение соответствующего типа (Ссылка, ДокументСсылка и т.д.). Если пользователь нажал "Отмена", возвращается значение Неопределено.
Типичный паттерн обработки выглядит следующим образом: сначала проверяется тип возвращенного значения, и только затем происходит присваивание его в реквизиты основной формы. Игнорирование проверки на Неопределено может привести к ошибкам при попытке обратиться к свойствам несуществующего объекта.
ВыбранноеЗначение = Неопределено;
Если ВыбратьЗначение(ВыбранноеЗначение, Справочники.Номенклатура, , Отбор) Тогда
Если ТипЗнч(ВыбранноеЗначение) = Тип("СправочникСсылка.Номенклатура") Тогда
Объект.Номенклатура = ВыбранноеЗначение;
КонецЕсли;
КонецЕсли;
В некоторых случаях требуется получить не просто ссылку, а сразу провести дополнительные действия с выбранным объектом, например, прочитать его дополнительные реквизиты без дополнительного обращения к базе. Для этого можно использовать чтение объекта сразу после выбора, если он еще не прочитан в память клиента.
⚠️ Внимание: При работе в тонком клиенте в режиме предприятия, закрытие формы выбора по нажатию клавиши Escape также возвращает
Неопределено. Учитывайте это при проектировании логики отмены действий пользователем.
Часто задаваемые вопросы (FAQ)
Как открыть форму выбора, если тип значения не определен заранее?
В таком случае используйте параметр ТипЗначения равный Неопределено или передайте список возможных типов. Однако установка отбора в этом случае будет затруднена, так как структура отбора привязана к конкретным реквизитам типа. Лучше использовать универсальные реквизиты, такие как "Наименование" или "Код", если они есть у всех типов.
Можно ли установить отбор по нескольким реквизитам одновременно?
Да, структура отбора или коллекция условий формы выбора поддерживает неограниченное количество полей. Все условия объединяются логическим оператором "И". Для реализации логики "ИЛИ" потребуется более сложная настройка через запрос или предварительную выборку данных.
Почему форма выбора открывается пустой, хотя данные в базе есть?
Наиболее вероятная причина — неверно указанные имена реквизитов в структуре отбора или несовпадение типов данных. Также проверьте, не перекрыт ли доступ к данным правами доступа (RLS) или конкретными настройками пользователя в интерфейсе.
Как запретить создание нового элемента в форме выбора?
При использовании объекта ФормаВыбора найдите команду с именем "Создать" в списке команд формы и установите её свойство Доступность в значение Ложь перед вызовом метода ОткрытьМодально.
Влияет ли отбор на скорость открытия формы?
Да, влияет. Чем сложнее условия отбора и чем меньше индексированных полей в них используется, тем дольше формируется выборка. Старайтесь использовать простые условия равенства по основным реквизитам для максимальной производительности.