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

Программист 1С v8.3 (Управляемые формы) Управленческий учет Промышленность, строительство и АПК
← На главную

В процессе разработки на платформе 1С:Предприятие 8.3 часто возникает задача ограничить список выбора в форме документа. Например, при выборе документа РеализацияТоваровУслуг из формы ОтчетПроизводстваЗаСмену необходимо показать только те реализации, которые соответствуют определенным критериям (номеру, периоду или составу товаров). Рассмотрим подробнее, как реализовать этот функционал правильно и эффективно.

Причина возникновения сложности

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

Решение 1. Использование события НачалоВыбора и ручная настройка формы

Этот метод считается классическим для управляемых форм. Мы перехватываем стандартную обработку выбора, самостоятельно получаем форму и накладываем на ее основной список нужные нам элементы отбора. Разберем по шагам, как это реализовать:

  1. Установите у элемента формы свойство СтандартнаяОбработка в значение Ложь.
  2. Используйте метод ПолучитьФорму для инициализации формы выбора.
  3. Обратитесь к свойству Отбор динамического списка формы.

Пример кода для реализации такого подхода:


&НаКлиенте
Процедура СН_СсылкиРеализацияТоваровиУслугНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
    
    // Отменяем стандартное открытие, чтобы управлять процессом вручную
    СтандартнаяОбработка = Ложь;
    
    // Получаем форму выбора нужного документа
    ПараметрыФормы = Новый Структура;
    ФормаВыбора = ПолучитьФорму("Документ.РеализацияТоваровУслуг.ФормаВыбора", ПараметрыФормы, Элемент);
    
    // Создаем новый элемент отбора в динамическом списке формы
    ЭлементОтбора = ФормаВыбора.Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
    ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Номер");
    ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
    ЭлементОтбора.Использование = Истина;
    ЭлементОтбора.ПравоеЗначение = "00000000050"; // Пример конкретного номера
    
    // Открываем настроенную форму
    ФормаВыбора.Открыть();
    
КонецПроцедуры

Решение 2. Использование типовой функции БСП

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

Важно: Всегда проверяйте порядок параметров! Типичная ошибка — перепутать имя поля и значение. Синтаксис функции следующий:

УстановитьЭлементОтбораДинамическогоСписка(Список, ИмяПоля, ПравоеЗначение, ВидСравнения)

Рассмотрим пример использования:


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

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

ф.Открыть();

Решение 3. Передача отбора через параметры формы (Рекомендуемый метод)

Существует еще более современный и "чистый" способ — передача структуры отбора напрямую в метод ОткрытьФорму. Платформа 1С автоматически применит эти настройки к динамическому списку, который является основным реквизитом открываемой формы. Выясним, в чем преимущество: вам не нужно вручную создавать элементы компоновки, система сделает это за вас.


&НаКлиенте
Процедура ВыборДокументаРеализации(Элемент)
    
    ПараметрыОтбора = Новый Структура;
    ПараметрыОтбора.Вставить("Номер", "00000000050");
    
    // Помещаем отбор в структуру параметров формы
    ПараметрыВыбора = Новый Структура;
    ПараметрыВыбора.Вставить("Отбор", ПараметрыОтбора);
    
    // Открываем форму с уже готовыми фильтрами
    ОткрытьФорму("Документ.РеализацияТоваровУслуг.ФормаВыбора", ПараметрыВыбора, Элемент);
    
КонецПроцедуры

Сложный отбор: фильтрация по списку значений на основе запроса

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

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


&НаСервере
Функция ПолучитьСписокПодходящихРеализаций(ВыбраннаяНоменклатура)
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   РеализацияТоваровУслугТовары.Ссылка КАК Ссылка
        |ИЗ
        |   Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
        |ГДЕ
        |   РеализацияТоваровУслугТовары.Номенклатура = &Номенклатура";
    
    Запрос.УстановитьПараметр("Номенклатура", ВыбраннаяНоменклатура);
    
    РезультатЗапроса = Запрос.Выполнить();
    Возврат РезультатЗапроса.Выгрузить().ВыгрузитьКолонку("Ссылка");
    
КонецФункции

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

Технические нюансы и важные советы

Чтобы ваш код работал надежно, обратите внимание на следующие моменты:

  1. Фильтрация по Ссылке, а не по Номеру: Поиск по строковому номеру — плохая практика. Номера могут повторяться в разных периодах или иметь разные префиксы. Всегда старайтесь делать отбор по полю Ссылка.
  2. Фиксированные настройки: Если вы хотите, чтобы пользователь не мог программно отключить ваш отбор через настройки списка, используйте свойство ФиксированныеНастройки компоновщика настроек динамического списка.
  3. Отказ от модальности: Избегайте использования метода ОткрытьФормуМодально. В современных конфигурациях это может вызвать ошибку. Используйте ОткрытьФорму с указанием владельца (параметр Элемент), тогда выбранное значение автоматически попадет в поле ввода.
  4. Путь к данным: Убедитесь, что имя поля, которое вы указываете в отборе (например, "Номер" или "Ссылка"), совпадает с именем колонки в самом динамическом списке формы выбора. Если в списке используется сложный запрос с псевдонимами, нужно указывать псевдоним.

Таким образом, мы рассмотрели несколько способов установки отбора. Самым гибким является программное добавление элементов в Список.Отбор.Элементы, а самым быстрым и простым — передача структуры Отбор через параметры формы при ее открытии.

← На главную