В процессе разработки в среде 1С часто возникает задача создания нестандартного интерфейса для выбора товаров. Стандартные формы выбора справочника Номенклатура не всегда удовлетворяют потребностям бизнеса, особенно когда пользователю критически важно видеть актуальные остатки в момент подбора. Рассмотрим подробно, как создать функциональное окно выбора, которое будет отображать данные вашего собственного запроса.
Если ваша конфигурация работает на управляемых формах, наиболее технологичным и производительным решением будет использование динамического списка с произвольным запросом. Этот механизм позволяет платформе самостоятельно оптимизировать получение данных и обеспечивать стандартные функции поиска и сортировки.
Разберем алгоритм настройки по шагам:
ФормаВыбораСКартинкамиИОстатками.ДинамическийСписок.Номенклатура с виртуальной таблицей остатков (например, ТоварыНаСкладахОстатки).Пример запроса для динамического списка:
ВЫБРАТЬ
СпрНоменклатура.Ссылка КАК Ссылка,
СпрНоменклатура.Код КАК Код,
СпрНоменклатура.Наименование КАК Наименование,
ЕСТЬNULL(ТоварыНаСкладахОстатки.ВНаличииОстаток, 0) КАК Остаток
ИЗ
Справочник.Номенклатура КАК СпрНоменклатура
ЛЕВОЕ СОЕДИНЕНИЕ
РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, Склад = &Склад) КАК ТоварыНаСкладахОстатки
ПО
СпрНоменклатура.Ссылка = ТоварыНаСкладахОстатки.Номенклатура
ГДЕ
НЕ СпрНоменклатура.ЭтоГруппа
Проанализируем ситуацию с параметрами: чтобы список корректно отображал остатки по конкретному складу, нам нужно передать значение параметра Склад из основной формы в форму выбора. Это делается в обработчике ПриСозданииНаСервере открываемой формы:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Устанавливаем параметры динамического списка
Список.Параметры.УстановитьЗначениеПараметра("Период", ТекущаяДата());
Список.Параметры.УстановитьЗначениеПараметра("Склад", Параметры.ТекущийСклад);
КонецПроцедуры
Бывают случаи, когда данные для окна выбора формируются сложным алгоритмом, который невозможно уложить в один запрос динамического списка (например, расчет прогнозируемых остатков или сбор данных из внешних систем). В этой ситуации мы используем Таблицу Значений (ТЗ).
Выясним причину, почему нельзя просто передать ТЗ как параметр. Таблица значений не является типом, который можно напрямую передать между клиентом и сервером в параметрах формы без потери производительности или ограничений платформы. Правильный путь — использование временного хранилища.
Рассмотрим пошагово реализацию этого метода:
Код в основной форме:
&НаКлиенте
Процедура КомандаОткрытьПодбор(Команда)
ДанныеДляВыбора = СформироватьТаблицуОстатковНаСервере();
АдресХранилища = ПоместитьВоВременноеХранилище(ДанныеДляВыбора, УникальныйИдентификатор);
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("АдресДанных", АдресХранилища);
ОткрытьФорму("Обработка.МояОбработка.Форма.ФормаВыбораОстатков", ПараметрыФормы, ЭтаФорма);
КонецПроцедуры
В самой форме выбора нам нужно получить эти данные и отобразить их. Для этого создадим реквизит формы с типом ТаблицаЗначений и выведем его на форму как таблицу.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если Параметры.Свойство("АдресДанных") Тогда
ТЗ = ПолучитьИзВременногоХранилища(Параметры.АдресДанных);
// Загружаем данные в реквизит формы "ТаблицаОстатков"
ЗначениеВРеквизитФормы(ТЗ, "ТаблицаОстатков");
КонецЕсли;
КонецПроцедуры
Важнейшим этапом является передача выбранного товара обратно в основную форму. Для этого используется метод ОповеститьОВыборе. Рассмотрим, как это реализовать при двойном клике по строке или нажатии кнопки выбора.
В форме выбора создадим обработчик события Выбор для таблицы:
&НаКлиенте
Процедура ТаблицаОстатковВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь; // Отменяем стандартные действия
ТекущиеДанные = Элементы.ТаблицаОстатков.ТекущиеДанные;
Если ТекущиеДанные <> Неопределено Тогда
ОповеститьОВыборе(ТекущиеДанные.Ссылка);
КонецЕсли;
КонецПроцедуры
В основной форме (владельце) необходимо создать обработчик события ОбработкаВыбора. Именно сюда «прилетят» данные после вызова ОповеститьОВыборе.
&НаКлиенте
Процедура ОбработкаВыбора(ВыбранноеЗначение, ИсточникВыбора)
Если ТипЗнч(ВыбранноеЗначение) = Тип("СправочникСсылка.Номенклатура") Тогда
// Добавляем выбранный товар в нашу корзину или документ
ДобавитьТоварВДокумент(ВыбранноеЗначение);
КонецЕсли;
КонецПроцедуры
Если задача стоит так, чтобы пользователь мог выбрать сразу несколько позиций, не закрывая окно после каждого клика (типичный режим "Подбора"), нам нужно внести небольшие изменения в настройки формы:
ЗакрыватьПриВыборе в значение Ложь.ОповеститьОВыборе можно использовать метод Оповестить, передав имя события, например: Оповестить("ТоварВыбран", ТекущиеДанные.Ссылка).ОбработкаОповещения для ловли этих событий.Чтобы форма была по-настоящему удобной, проанализируем возможности Условного оформления. Мы можем подсвечивать строки в зависимости от величины остатка. Например:
Остаток <= 0 — текст строки становится серым.Остаток < МинимальныйПорог — поле остатка выделяется красным цветом.Это настраивается в свойствах формы (вкладка "Условное оформление") или программно в процедуре ПриСозданииНаСервере. Использование таких визуальных индикаторов значительно сокращает время работы пользователя и минимизирует ошибки при оформлении заказов.
Если вы работаете в старых конфигурациях, алгоритм сохраняется, но меняется инструментарий. Вместо ЗначениеВРеквизитФормы вы будете напрямую работать с объектом ТабличноеПоле, установив ему тип значения ТаблицаЗначений. Кнопка выбора в этом случае будет просто закрывать форму с передачей значения, если у формы установлено свойство РежимВыбора = Истина.
Таким образом, мы разобрали два основных архитектурных подхода к созданию окна выбора с остатками. Динамический список — это стандарт и производительность для простых связей. Таблица значений — это гибкость для сложных расчетов. Выбирайте метод в зависимости от сложности вашего запроса и требований к интерфейсу.