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