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