Как правильно настроить выбор документов с отбором по запросу в 1С

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Введение: анализ проблемы и типичные ошибки разработчиков

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

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

Также важно обратить внимание на тип данных реквизита. Если реквизит имеет тип Строка, хранение ссылок на документы становится неэффективным. При записи ссылки в текстовое поле сохраняется лишь строковое представление (например, "Реализация товаров и услуг №15 от 12.05.2026"). Вся метаструктура и связь с базой данных теряются. Мы настоятельно рекомендуем изменить тип реквизита на ссылку соответствующего документа (например, ДокументСсылка.РеализацияТоваровУслуг) или использовать тип ЛюбаяСсылка. Если же строковый тип неизбежен, ниже мы разберем специальный обходной путь.

Вариант 1. Использование параметра "ДанныеВыбора" в управляемых формах

Рассмотрим наиболее изящный способ реализации быстрого выбора без открытия громоздких диалоговых окон. Начиная с платформы 8.3, в обработчике события НачалоВыбора доступен параметр ДанныеВыбора. Если мы заполним его списком значений на сервере и установим стандартную обработку в значение Ложь, платформа сама отобразит пользователю аккуратное выпадающее меню прямо под полем ввода.

Разберем этот метод по шагам на примере кода:


&НаКлиенте
Процедура СписокДокументовНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
    
    // Шаг 1. Отменяем стандартное открытие тяжелой формы выбора
    СтандартнаяОбработка = Ложь;
    
    // Шаг 2. Вызываем серверный контекст для выполнения запроса
    СписокДляВыбора = ПолучитьСписокДокументовНаСервере();
    
    // Шаг 3. Передаем сформированный список в платформенный параметр
    ДанныеВыбора = СписокДляВыбора;
    
КонецПроцедуры

Теперь спроектируем серверную функцию, которая выполняет запрос к базе данных и собирает ссылки в объект СписокЗначений:


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

Вариант 2. Асинхронный метод "ПоказатьВыборИзСписка" для строковых реквизитов

Что делать, если тип реквизита на форме действительно должен оставаться строковым, но нам все равно нужно дать пользователю возможность выбрать документ из ограниченного списка? Проанализируем современный асинхронный подход, соответствующий стандартам разработки 1С под интерфейс "Такси" без использования модальных окон.

Для этого мы воспользуемся методом ПоказатьВыборИзСписка. Этот метод выводит список значений и ожидает действия пользователя, после чего передает управление в процедуру-обработчик оповещения.

Реализуем данный алгоритм:


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

После того как пользователь кликнет по нужному документу в списке, платформа вызовет следующую экспортную процедуру:


&НаКлиенте
Процедура ПослеВыбораДокументаИзСписка(ВыбранныйЭлемент, ДополнительныеПараметры) Экспорт
    
    // Проверяем, что пользователь не закрыл меню без выбора
    Если ВыбранныйЭлемент <> Неопределено Тогда
        // Записываем представление выбранной ссылки в наш строковый реквизит
        Объект.СписокДокументов = ВыбранныйЭлемент.Представление;
    КонецЕсли;
    
КонецПроцедуры

Вариант 3. Открытие полноценной формы выбора с фильтрацией (ФиксированныеНастройки)

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

Для решения этой задачи в управляемом интерфейсе используется передача параметра ФиксированныеНастройки в открываемую форму. Это позволяет передать структуру отборов компоновки данных динамическому списку формы выбора.

Посмотрим на пример практической реализации:


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

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


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

Вариант 4. Реализация в обычных формах (Обычное приложение)

Если вы работаете с конфигурациями на обычных формах (например, Управление торговлей 10.3 или Управление производственным предприятием 1.3), подход будет иным. В обычных формах мы можем напрямую получить объект формы выбора, обратиться к настройкам отбора ее табличного поля и открыть ее.

Рассмотрим, как это реализуется в процедуре события НачалоВыбора:


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

Сводная таблица методов и рекомендации по выбору решения

Чтобы вам было проще сориентироваться, какой из методов применить в вашем конкретном случае, мы составили рекомендации:

  1. Малый объем данных (до 20-30 документов): Используйте Вариант 1 (ДанныеВыбора). Это быстро, не требует открытия дополнительных окон и выглядит очень современно в интерфейсе.
  2. Большой объем данных и сложная структура: Используйте Вариант 3 (ФиксированныеНастройки). Пользователь сможет использовать стандартный поиск платформы внутри предварительно отфильтрованного списка.
  3. Нетипичные или строковые реквизиты: Используйте Вариант 2 (ПоказатьВыборИзСписка). Это гарантирует бесперебойную работу асинхронного интерфейса без модальных вызовов.

Следуя этим практическим рекомендациям и избегая использования устаревших модальных методов, вы сможете создавать надежные и интуитивно понятные интерфейсы для пользователей ваших решений на платформе 1С:Предприятие.

← На главную