Работа с формами выбора в 1С:Предприятие — одна из самых частых задач, с которыми сталкиваются разработчики. Но что делать, если нужно не просто открыть форму выбора, а передать в неё готовый отбор? Например, когда пользователю требуется выбрать только активные контрагентов, документы за текущий месяц или номенклатуру определённой группы. Без правильной передачи отбора форма покажет все записи без фильтрации, что снизит удобство работы и может привести к ошибкам.

В этой статье разберём три основных способа передачи отбора в форму выбора: через параметры открытия формы, программное формирование отбора и использование расширений конфигурации. Каждый метод имеет свои плюсы и минусы, а также подходит для разных сценариев — от простых задач до сложных интеграций. Особое внимание уделим типичным ошибкам, которые допускают даже опытные программисты, и покажем, как их избежать.

Если вы только начинаете работать с формами в , рекомендуем сначала ознакомиться с базовыми принципами их создания. Для опытных разработчиков статья станет сборником проверенных решений с примерами кода, которые можно сразу использовать в своих проектах.

1. Передача отбора через параметры формы выбора

Самый распространённый способ — передача отбора непосредственно при открытии формы. Этот метод подходит для большинства стандартных задач и не требует глубоких изменений в конфигурации. Основной инструмент здесь — параметр Отбор, который можно передать в метод ОткрытьФорму() или ОткрытьЗначение().

Рассмотрим пример передачи отбора для формы выбора справочника Номенклатура, где нужно показать только товары определённой группы:

Отбор = Новый Структура("Родитель", СсылкаНаГруппуНоменклатуры);

ПараметрыФормы = Новый Структура("Отбор, Заголовок", Отбор, "Выберите номенклатуру из группы: " + СсылкаНаГруппуНоменклатуры.Наименование);

ОткрытьФорму("Справочник.Номенклатура.ФормаВыбора", ПараметрыФормы);

В этом коде:

  • 📌 Структура Отбор содержит имя поля (Родитель) и значение для фильтрации.
  • 🔹 ПараметрыФормы передаются во второй аргумент метода ОткрытьФорму().
  • 📝 Заголовок формы можно кастомизировать для удобства пользователя.
💡

Если отбор содержит несколько условий, используйте структуру с несколькими ключами: Отбор = Новый Структура("ПометкаУдаления, ВидНоменклатуры", Ложь, Перечисление.ВидыНоменклатуры.Товар);

Если имя указано неверно, отбор просто проигнорируется без ошибки. Это одна из самых распространённых причин, почему фильтрация не работает.

2. Программное формирование отбора в модуле формы

Когда стандартная передача отбора через параметры не подходит (например, если нужно динамически менять условия или работать с нестандартными формами), можно формировать отбор непосредственно в модуле формы выбора. Этот метод требует доступа к конфигурации и умения работать с событиями форм.

Рассмотрим пошаговую инструкцию:

  1. Откройте форму выбора в конфигураторе (например, Справочник.Контрагенты.ФормаВыбора).
  2. В модуле формы найдите процедуру ПриСозданииНаСервере() или создайте её, если отсутствует.
  3. Добавьте код для обработки переданных параметров и формирования отбора:
    Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    

    Если Параметры.Свойство("ОтборПоДатеРегистрации") Тогда

    Элементы.Список.Отбор.ДатаРегистрации.УстановитьЗначение(Параметры.ОтборПоДатеРегистрации);

    КонецЕсли;

    КонецПроцедуры

Преимущества этого метода:

  • 🔧 Гибкость: можно реализовать любую логику формирования отбора.
  • 🔄 Динамичность: отбор может изменяться в зависимости от действий пользователя.
  • 🛠️ Возможность добавления дополнительных элементов управления (например, чекбоксов для включения/отключения фильтров).

Создать копию стандартной формы выбора|Проверить права доступа к объекту|Определить список полей для отбора|Протестировать отбор на тестовых данных-->

Однако у этого подхода есть и недостатки. Изменение стандартных форм может привести к проблемам при обновлении конфигурации, поэтому всегда сохраняйте оригинальные формы и документируйте внесённые изменения. Кроме того, такой метод требует больше времени на реализацию и тестирование.

3. Использование расширений конфигурации для передачи отбора

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

Алгоритм работы с расширениями:

  1. Создайте новое расширение в дереве конфигурации.
  2. Добавьте в него форму выбора (например, Справочник.Номенклатура.ФормаВыбора).
  3. В модуле формы расширения переопределите процедуру ПриСозданииНаСервере() для обработки отбора.
  4. Используйте механизм подписок на события, чтобы передавать отбор из основного кода.

Пример кода для расширения:

Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) Экспорт

Если Параметры.Свойство("ОтборПоГруппе") Тогда

Элементы.Список.Отбор.Родитель.УстановитьЗначение(Параметры.ОтборПоГруппе);

Элементы.Список.Отбор.Родитель.Видимость = Ложь; // Скрываем поле отбора, если нужно

КонецЕсли;

КонецПроцедуры

Преимущества использования расширений:

КритерийРасширенияПрямое изменение формы
Совместимость с обновлениями✅ Сохраняется❌ Может сломаться
Время реализации⏳ Дольше⚡ Быстрее
Гибкость✅ Высокая✅ Высокая
Безопасность✅ Не затрагивает исходный код❌ Риск ошибок
📊 Какой метод передачи отбора вы используете чаще?
Через параметры формы
Программно в модуле
Через расширения
Другой вариант

Расширения идеально подходят для крупных проектов, где важна поддержка и совместимость с будущими обновлениями. Однако для простых задач этот метод может быть избыточным.

4. Типичные ошибки и как их избежать

Даже опытные разработчики иногда сталкиваются с проблемами при передаче отбора в формы выбора. Рассмотрим самые распространённые ошибки и способы их решения:

  • 🚫 Несовпадение имён полей: Если имя поля в структуре отбора не совпадает с именем реквизита в форме, отбор не применяется. Всегда проверяйте имена в метаданных.
    ⚠️ Внимание: В 1С:Предприятие 8.3.20+ появилась возможность использовать псевдонимы полей в отборе, но это требует дополнительной настройки.
  • 🔄 Неправильный тип данных: Передача строки вместо ссылки или даты вместо числа приведёт к ошибке. Например, для поля Родитель нужно передавать ссылку на элемент справочника, а не его наименование.
  • 🔒 Отсутствие прав: Если у пользователя нет прав на просмотр фильтруемых данных, форма может открыться пустой. Проверьте роли и права доступа.
  • 📥 Передача пустого отбора: Если структура отбора пустая или содержит Неопределён, фильтрация не сработает. Всегда проверяйте заполненность параметров.

Одна из самых коварных ошибок — невидимые символы в именах полей. Например, если имя поля скопировано из другого источника, в нём могут остаться непечатаемые символы (пробелы, табуляции). Всегда вводите имена полей вручную или используйте синтакс-помощник.

Как отладить неработающий отбор?

1. Проверьте, доходят ли параметры до формы (используйте отладчик).

2. Убедитесь, что имя поля в отборе совпадает с именем в метаданных (включите отображение синонимов в конфигураторе).

3. Проверьте типы данных: например, для поля "Дата" нужно передавать значение типа Дата, а не строку.

4. Если отбор применяется, но не виден в интерфейсе, проверьте настройки видимости колонок в форме.

5. Практический пример: отбор по нескольким условиям

Рассмотрим реальный кейс: нужно открыть форму выбора документов РеализацияТоваровУслуг с отбором по дате, контрагенту и организации. Вот как это можно реализовать:

// Формируем структуру отбора

Отбор = Новый Структура();

Отбор.Вставить("Дата", НачалоДня(ТекущаяДата()));

Отбор.Вставить("Контрагент", ВыбранныйКонтрагент);

Отбор.Вставить("Организация", ТекущаяОрганизация());

// Добавляем заголовок и другие параметры

ПараметрыФормы = Новый Структура();

ПараметрыФормы.Вставить("Отбор", Отбор);

ПараметрыФормы.Вставить("Заголовок", "Выбор реализаций за сегодня");

ПараметрыФормы.Вставить("РежимВыбора", Истина); // Разрешаем множественный выбор

// Открываем форму

РезультатВыбора = ОткрытьФорму("Документ.РеализацияТоваровУслуг.ФормаСписка", ПараметрыФормы);

В этом примере: Отбор по дате использует функцию НачалоДня(), чтобы исключить влияние времени — это критично для корректной фильтрации документов по календарной дате.

Если нужно передать отбор в форму выбора, которая открывается не напрямую, а через другой объект (например, из формы документа), используйте механизм ПараметрыФормы для передачи данных между формами:

Процедура ОткрытьФормуВыбораНоменклатуры(Команда)

Параметры = Новый Структура();

Параметры.Вставить("ОтборПоГруппе", ТекущийДокумент.ГруппаНоменклатуры);

ОткрытьФорму("Справочник.Номенклатура.ФормаВыбора", Параметры);

КонецПроцедуры

6. Работа с динамическими отборами

Иногда отбор нужно формировать динамически — например, в зависимости от текущего пользователя, его ролей или других условий. В таких случаях удобно использовать функции-обработчики, которые возвращают структуру отбора.

Пример динамического отбора для формы выбора контрагентов:

Функция ПолучитьОтборПоКонтрагентам()

Отбор = Новый Структура();

// Фильтр по активным контрагентам

Отбор.Вставить("ПометкаУдаления", Ложь);

// Если пользователь принадлежит к региональному офису, фильтруем по региону

Если ТекущийПользователь.Регион <> Неопределено Тогда

Отбор.Вставить("Регион", ТекущийПользователь.Регион);

КонецЕсли;

Возврат Отбор;

КонецФункции

// Использование

ПараметрыФормы = Новый Структура("Отбор", ПолучитьОтборПоКонтрагентам());

ОткрытьФорму("Справочник.Контрагенты.ФормаВыбора", ПараметрыФормы);

Преимущества динамических отборов:

  • 🔄 Адаптивность: отбор меняется в зависимости от контекста.
  • 🔒 Безопасность: можно ограничивать данные по ролям пользователей.
  • 📊 Гибкость: легко добавлять новые условия без изменения основного кода.
💡

Динамические отборы особенно полезны в системах с большим количеством пользователей и сложной структурой данных, где права доступа и бизнес-логика часто меняются.

Для сложных сценариев можно комбинировать динамические отборы с расширениями конфигурации. Например, создать универсальную функцию формирования отбора в расширении и вызывать её из разных мест кода.

7. Оптимизация производительности при работе с отборами

Неправильно сформированные отборы могут значительно замедлить работу формы выбора, особенно если речь идёт о больших объёмах данных. Вот несколько советов по оптимизации:

  • 🚀 Используйте индексированные поля: Отбор по индексированным полям (например, Ссылка, Дата) работает быстрее.
  • 🧹 Ограничивайте количество полей: Не передавайте в отбор поля, которые не используются для фильтрации.
  • 🔍 Избегайте сложных выражений: Отбор вида Наименование Содержит "Товар" работает медленнее, чем ВидНоменклатуры = Перечисление.ВидыНоменклатуры.Товар.
  • 📈 Используйте серверные процедуры: Формируйте отбор на сервере, а не на клиенте.

Пример оптимизированного отбора для справочника Номенклатура:

Отбор = Новый Структура();

Отбор.Вставить("Родитель", ГруппаНоменклатуры); // Индексированное поле

Отбор.Вставить("ВидНоменклатуры", Перечисление.ВидыНоменклатуры.Товар); // Точное совпадение

Отбор.Вставить("ПометкаУдаления", Ложь); // Фильтр по системному полю

// Используем серверную функцию для открытия формы

Параметры = Новый Структура("Отбор, РежимОтображения", Отбор, РежимОтображенияСписка.Иерархический);

ОткрытьФормуНаСервере("Справочник.Номенклатура.ФормаВыбора", Параметры);

Для крупных справочников (более 100 000 записей) рассмотрите возможность использования виртуальных таблиц или предопределённых отборов в конфигураторе. Это позволит снизить нагрузку на базу данных.

FAQ: Частые вопросы по передаче отбора в формы выбора

Можно ли передать отбор в стандартную форму выбора без изменения конфигурации?

Да, можно использовать первый метод — передачу отбора через параметры формы. Это не требует изменения конфигурации и работает для большинства стандартных форм выбора в .

Почему отбор не применяется, хотя параметры передаются правильно?

Чаще всего это связано с несовпадением имён полей в структуре отбора и в метаданных формы. Убедитесь, что:

  • Имена полей указаны точно (включая регистр).
  • Типы данных совпадают (например, для поля Дата передаётся значение типа Дата, а не строка).
  • Поле, по которому делается отбор, не скрыто и доступно для фильтрации.

Как передать отбор в форму выбора, которая открывается из другой формы?

Используйте механизм параметров при открытии формы. Например, если форма выбора открывается из формы документа, в обработчике команды добавьте код:

Процедура ВыбратьНоменклатуру(Команда)

Параметры = Новый Структура();

Параметры.Вставить("ОтборПоГруппе", Объект.ГруппаНоменклатуры);

ОткрытьФорму("Справочник.Номенклатура.ФормаВыбора", Параметры);

КонецПроцедуры

Можно ли передать отбор в форму выбора, если она открывается через ОткрытьЗначение()?

Да, метод ОткрытьЗначение() также поддерживает передачу параметров, включая отбор. Пример:

Параметры = Новый Структура("Отбор, Заголовок", Отбор, "Выберите значение");

ОткрытьЗначение(Новый ОписаниеТипов("СправочникСсылка.Номенклатура"), , , , Параметры);

Как передать отбор в форму выбора для управляемого интерфейса?

В управляемом интерфейсе принципы те же, но нужно учитывать, что формы открываются через клиент-серверное взаимодействие. Пример:

Параметры = Новый Структура();

Параметры.Вставить("Отбор", Отбор);

Параметры.Вставить("КлючОтбора", "МояФормаВыбора"); // Опционально, для идентификации

ОткрытьФорму("Справочник.Номенклатура.ФормаВыбора", Параметры,,,, Истина); // Последний параметр - признак управляемого интерфейса