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

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

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

Метод 1: Использование динамического списка (рекомендуемый для управляемых форм)

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

Разберем алгоритм настройки по шагам:

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

Пример запроса для динамического списка:


ВЫБРАТЬ
    СпрНоменклатура.Ссылка КАК Ссылка,
    СпрНоменклатура.Код КАК Код,
    СпрНоменклатура.Наименование КАК Наименование,
    ЕСТЬNULL(ТоварыНаСкладахОстатки.ВНаличииОстаток, 0) КАК Остаток
ИЗ
    Справочник.Номенклатура КАК СпрНоменклатура
ЛЕВОЕ СОЕДИНЕНИЕ
    РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, Склад = &Склад) КАК ТоварыНаСкладахОстатки
ПО
    СпрНоменклатура.Ссылка = ТоварыНаСкладахОстатки.Номенклатура
ГДЕ
    НЕ СпрНоменклатура.ЭтоГруппа

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


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

Метод 2: Работа с таблицей значений и временным хранилищем

Бывают случаи, когда данные для окна выбора формируются сложным алгоритмом, который невозможно уложить в один запрос динамического списка (например, расчет прогнозируемых остатков или сбор данных из внешних систем). В этой ситуации мы используем Таблицу Значений (ТЗ).

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

Рассмотрим пошагово реализацию этого метода:

  1. В основной форме выполняем запрос и выгружаем результат в ТЗ.
  2. Помещаем ТЗ во временное хранилище и получаем адрес.
  3. Открываем форму выбора, передавая этот адрес в параметрах.

Код в основной форме:


&НаКлиенте
Процедура КомандаОткрытьПодбор(Команда)
    
    ДанныеДляВыбора = СформироватьТаблицуОстатковНаСервере();
    АдресХранилища = ПоместитьВоВременноеХранилище(ДанныеДляВыбора, УникальныйИдентификатор);
    
    ПараметрыФормы = Новый Структура;
    ПараметрыФормы.Вставить("АдресДанных", АдресХранилища);
    
    ОткрытьФорму("Обработка.МояОбработка.Форма.ФормаВыбораОстатков", ПараметрыФормы, ЭтаФорма);
    
КонецПроцедуры

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


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

Механизм возврата выбранного значения

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

В форме выбора создадим обработчик события Выбор для таблицы:


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

В основной форме (владельце) необходимо создать обработчик события ОбработкаВыбора. Именно сюда «прилетят» данные после вызова ОповеститьОВыборе.


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

Режим многократного подбора

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

  1. В форме выбора установите свойство ЗакрыватьПриВыборе в значение Ложь.
  2. Вместо ОповеститьОВыборе можно использовать метод Оповестить, передав имя события, например: Оповестить("ТоварВыбран", ТекущиеДанные.Ссылка).
  3. В основной форме используйте обработчик ОбработкаОповещения для ловли этих событий.

Улучшение UX: Визуальное оформление остатков

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

Это настраивается в свойствах формы (вкладка "Условное оформление") или программно в процедуре ПриСозданииНаСервере. Использование таких визуальных индикаторов значительно сокращает время работы пользователя и минимизирует ошибки при оформлении заказов.

Особенности для обычных форм (ОФ)

Если вы работаете в старых конфигурациях, алгоритм сохраняется, но меняется инструментарий. Вместо ЗначениеВРеквизитФормы вы будете напрямую работать с объектом ТабличноеПоле, установив ему тип значения ТаблицаЗначений. Кнопка выбора в этом случае будет просто закрывать форму с передачей значения, если у формы установлено свойство РежимВыбора = Истина.

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

← На главную