Механизм подбора в 1С 8.3: от типовой кнопки до своей обработки с корзиной
Содержание
Подбор в 1С 8.3 реализуют так: из формы документа открывают форму выбора или свою обработку с параметром ЗакрыватьПриВыборе = Ложь, передают владельцем саму форму документа, а строки получают в событии ОбработкаВыбора. Подборщик отдаёт результат методом ОповеститьОВыборе — одним значением, массивом или адресом во временном хранилище.
Частая ошибка — считать подбор отдельным объектом платформы, который «включается галочкой». Такого объекта нет. Подбор товаров и услуг в типовых конфигурациях — это обычная форма с корзиной, написанная разработчиками. Значит, свой механизм подбора можно сделать в любой конфигурации, а типовой — доработать расширением, не снимая поддержку.
Как устроен типовой подбор и где он есть
В табличных частях документов продаж и закупок типовых конфигураций над таблицей товаров стоит кнопка Подбор. В 1С:Управление торговлей 11 команда называется Подобрать товары. Нажатие открывает отдельную форму: слева дерево групп номенклатуры, в центре список позиций, внизу — подобранные строки.
Что обычно умеет типовая форма подбора:
- 📦 показывает остатки на складе из шапки документа;
- 💰 подставляет цену по виду цен документа;
- 🔎 ищет по наименованию, артикулу и штрихкоду;
- 🧺 копит позиции в корзине и переносит их в документ одной командой.
Где искать кнопку в документах:
| Конфигурация | Документ | Где команда |
|---|---|---|
| Бухгалтерия предприятия 3.0 | Реализация, Поступление, Счёт покупателю | Командная панель табличной части «Товары» / «Услуги» |
| Управление торговлей 11 | Заказ клиента, Реализация товаров и услуг | Командная панель табличной части «Товары» |
Если кнопки не видно, проверьте Ещё → Изменить форму: команду могли скрыть в пользовательских настройках формы. Там же её возвращают на место.
Как доработать стандартный подбор: колонки и фильтры
Простые вещи пользователь делает сам, без программиста:
- Откройте форму подбора.
- В меню
ЕщёвыберитеИзменить форму. - Отметьте скрытые колонки (например, артикул или единицу измерения) и перетащите их в нужный порядок.
- Нажмите
OK— настройка сохранится для этого пользователя.
Новые колонки и отборы, которых в форме нет, добавляют через расширение конфигурации . Снимать типовую конфигурацию с поддержки ради подбора не нужно: обновления потом придётся объединять вручную.
Порядок работы в расширении:
- В конфигураторе откройте
Конфигурация → Расширения конфигурации, создайте расширение. - В дереве основной конфигурации найдите форму подбора. Проще всего — через модуль формы документа: в обработчике команды подбора виден вызов
ОткрытьФормус полным именем формы. - Через контекстное меню формы выберите
Добавить в расширение. - Добавьте реквизит формы, например
ТолькоВНаличии(тип «Булево»), и разместите его над списком. - В модуле заимствованной формы напишите обработчик изменения флажка, который ставит отбор на список.
Если форма построена на динамическом списке, отбор проще всего ставить через Список.Отбор или параметр запроса списка — так фильтрует СУБД, а не клиент.
&НаКлиенте
Процедура РасшТолькоВНаличииПриИзменении(Элемент)
Список.Параметры.УстановитьЗначениеПараметра("ТолькоВНаличии", ТолькоВНаличии);
КонецПроцедуры
Пример работает, только если в тексте запроса списка есть параметр &ТолькоВНаличии. В типовой форме его нет. Если запрос менять нельзя, используйте отбор по существующему полю списка.
Своя обработка подбора: пошагово с кодом
Своя обработка нужна, когда типовой формы нет (самописная конфигурация) или она не подходит: другой учёт остатков, своя логика цен, подбор услуг по договору.
Шаг 1. Создайте обработку и форму
Создайте обработку ПодборТоваров с одной управляемой формой. На форме:
- 📋 динамический список
Списокпо справочнику номенклатуры; - 🧺 реквизит
Корзинатипа «ТаблицаЗначений» с колонкамиНоменклатура,Количество,Цена; - 🔘 команда
ПеренестиВДокумент.
Шаг 2. Откройте подбор из документа
В форме документа добавьте команду Подбор и разместите её в командной панели табличной части.
&НаКлиенте
Процедура Подбор(Команда)
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("Склад", Объект.Склад);
ПараметрыФормы.Вставить("ЗакрыватьПриВыборе", Ложь);
ОткрытьФорму("Обработка.ПодборТоваров.Форма.Форма", ПараметрыФормы, ЭтотОбъект);
КонецПроцедуры
Третий параметр ЭтотОбъект делает документ владельцем формы. Без него ОповеститьОВыборе некому будет отдать результат.
Шаг 3. Добавляйте позиции в корзину
Двойной щелчок по строке списка вызывает событие Выбор. Перехватываем его и спрашиваем количество.
&НаКлиенте
Процедура СписокВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
ДанныеСтроки = Элементы.Список.ТекущиеДанные;
Контекст = Новый Структура("Номенклатура, Цена", ВыбраннаяСтрока, ДанныеСтроки.Цена);
Оповещение = Новый ОписаниеОповещения("ПослеВводаКоличества", ЭтотОбъект, Контекст);
ПоказатьВводЧисла(Оповещение, 1, "Количество", 15, 3);
КонецПроцедуры
&НаКлиенте
Процедура ПослеВводаКоличества(Число, Контекст) Экспорт
Если Число = Неопределено Или Число <= 0 Тогда
Возврат;
КонецЕсли;
Найденные = Корзина.НайтиСтроки(Новый Структура("Номенклатура", Контекст.Номенклатура));
Если Найденные.Количество() > 0 Тогда
Найденные[0].Количество = Найденные[0].Количество + Число;
Иначе
НоваяСтрока = Корзина.Добавить();
НоваяСтрока.Номенклатура = Контекст.Номенклатура;
НоваяСтрока.Количество = Число;
НоваяСтрока.Цена = Контекст.Цена;
КонецЕсли;
КонецПроцедуры
Ввод количества сделан немодально, через ОписаниеОповещения. Модальные окна в веб-клиенте и мобильной платформе не работают, поэтому лучше сразу писать так.
Шаг 4. Перенесите корзину в документ
&НаКлиенте
Процедура ПеренестиВДокумент(Команда)
Результат = Новый Массив;
Для Каждого Строка Из Корзина Цикл
Результат.Добавить(Новый Структура("Номенклатура, Количество, Цена",
Строка.Номенклатура, Строка.Количество, Строка.Цена));
КонецЦикла;
ЗакрыватьПриВыборе = Истина;
ОповеститьОВыборе(Результат);
КонецПроцедуры
Перед вызовом ставим ЗакрыватьПриВыборе = Истина, чтобы форма закрылась после переноса. Пока пользователь копит корзину, она остаётся открытой.
Шаг 5. Примите строки в документе
&НаКлиенте
Процедура ОбработкаВыбора(ВыбранноеЗначение, ИсточникВыбора)
Если ИсточникВыбора.ИмяФормы <> "Обработка.ПодборТоваров.Форма.Форма" Тогда
Возврат;
КонецЕсли;
Для Каждого Позиция Из ВыбранноеЗначение Цикл
Найденные = Объект.Товары.НайтиСтроки(Новый Структура("Номенклатура", Позиция.Номенклатура));
Если Найденные.Количество() > 0 Тогда
СтрокаТЧ = Найденные[0];
СтрокаТЧ.Количество = СтрокаТЧ.Количество + Позиция.Количество;
Иначе
СтрокаТЧ = Объект.Товары.Добавить();
СтрокаТЧ.Номенклатура = Позиция.Номенклатура;
СтрокаТЧ.Количество = Позиция.Количество;
СтрокаТЧ.Цена = Позиция.Цена;
КонецЕсли;
СтрокаТЧ.Сумма = СтрокаТЧ.Количество * СтрокаТЧ.Цена;
КонецЦикла;
Модифицированность = Истина;
КонецПроцедуры
Проверка ИмяФормы нужна, потому что ОбработкаВыбора срабатывает на любой выбор, где документ — владелец: выбор контрагента, склада, договора.
Подбор с остатками, ценами и характеристиками
Остатки и цены в подборе показывают одним запросом динамического списка. Включите у списка флажок «Произвольный запрос», основной таблицей укажите справочник номенклатуры.
Ниже пример для самописной конфигурации с регистром накопления ОстаткиТоваров и регистром сведений ЦеныНоменклатуры. Имена регистров замените на свои: в типовых конфигурациях они другие.
ВЫБРАТЬ
Номенклатура.Ссылка КАК Ссылка,
Номенклатура.Наименование КАК Наименование,
Номенклатура.Артикул КАК Артикул,
ЕСТЬNULL(Остатки.КоличествоОстаток, 0) КАК Остаток,
ЕСТЬNULL(Цены.Цена, 0) КАК Цена
ИЗ
Справочник.Номенклатура КАК Номенклатура
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиТоваров.Остатки(, Склад = &Склад) КАК Остатки
ПО Остатки.Номенклатура = Номенклатура.Ссылка
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(, ВидЦены = &ВидЦены) КАК Цены
ПО Цены.Номенклатура = Номенклатура.Ссылка
ГДЕ
НЕ Номенклатура.ЭтоГруппа
И (НЕ &ТолькоВНаличии ИЛИ ЕСТЬNULL(Остатки.КоличествоОстаток, 0) > 0)
Параметры заполняют при создании формы:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Список.Параметры.УстановитьЗначениеПараметра("Склад", Параметры.Склад);
Список.Параметры.УстановитьЗначениеПараметра("ВидЦены", Справочники.ВидыЦен.Розничная);
Список.Параметры.УстановитьЗначениеПараметра("ТолькоВНаличии", Ложь);
КонецПроцедуры
Предопределённый элемент Розничная — для примера. В рабочей обработке вид цены приходит из документа так же, как склад.
Характеристики и серии
Если товары учитывают по характеристикам (размер, цвет), остаток хранится в разрезе пары «номенклатура + характеристика». Тогда:
- Добавьте
Характеристикав корзину и в табличную часть документа. - Ищите строку корзины по двум полям:
Новый Структура("Номенклатура, Характеристика", ...). - Для товара с характеристиками после выбора открывайте второй список — остатки по характеристикам этой позиции. Пользователь выбирает размер, а не видит сто строк «Футболка».
Услуги
У услуг нет остатков. Флажок «Только в наличии» для них отключайте, иначе услуги пропадут из списка. Удобно разделить подбор на две вкладки: товары с остатками и услуги без них.
Как ускорить подбор на большой базе
Медленный подбор — почти всегда вопрос запроса, а не «тяжёлого клиента». Что проверить:
- ⚙️ Условия в параметрах виртуальной таблицы.
Остатки(, Склад = &Склад)фильтрует на стороне регистра. Условие на склад вГДЕпосле соединения заставит СУБД посчитать остатки по всем складам. - ⚙️ Динамическое считывание. У динамического списка оно включено по умолчанию. Список читает данные порциями по мере прокрутки, а не весь справочник сразу.
- ⚙️ Один вызов сервера на перенос. Корзину передают целиком одним массивом. Цикл с серверным вызовом на каждую строку при 300 позициях даст 300 обращений к серверу.
- ⚙️ Временное хранилище для больших корзин. Если в корзине тысячи строк, выгрузите её на сервере в таблицу значений, поместите
ПоместитьВоВременноеХранилищеи передайте черезОповеститьОВыборетолько адрес. Документ заберёт данныеПолучитьИзВременногоХранилищав серверной процедуре. - ⚙️ Поиск по штрихкоду. Штрихкоды держат в отдельном регистре сведений с измерением «Штрихкод». Поиск по измерению идёт по индексу и не перебирает справочник.
Не вычисляйте остаток функцией в каждой строке списка (через обращение к серверу из события строки). При 50 видимых строках это 50 отдельных запросов на каждую прокрутку.
Подбор в мобильном приложении 1С
На мобильной платформе работает та же схема: ОткрытьФорму с владельцем, ОповеститьОВыборе, ОбработкаВыбора. Меняется интерфейс.
Что учесть при разработке:
- 📱 Без модальности. Все вопросы и ввод числа — только через
ОписаниеОповещения. Код из шага 3 переносится как есть. - 📱 Поиск вместо дерева. Дерево групп на маленьком экране неудобно. Строка поиска по наименованию и артикулу работает быстрее.
- 📱 Крупные кнопки «+» и «−». Вместо ввода количества с клавиатуры добавьте в строку списка две команды, меняющие количество на единицу.
- 📱 Сканирование камерой. Мобильная платформа умеет читать штрихкод камерой через объект
СредстваМультимедиа. Перед вызовом проверьте, что устройство поддерживает сканирование. - 📱 Автономная работа. Если приложение работает без связи, остатки и цены приходят в мобильную базу обменом. Показывайте дату последней синхронизации прямо в форме подбора, чтобы торговый представитель видел, насколько свежи остатки.
Подбор из внешних источников: файлы, сайт, терминалы сбора данных
Не каждый подбор делается мышкой в форме. Три частых сценария:
| Источник | Как попадает в 1С | На что смотреть |
|---|---|---|
| Таблица Excel от клиента | Загрузка в табличную часть: сопоставление колонок с полями | Ключ поиска товара — артикул или штрихкод, не наименование |
| Корзина интернет-магазина | HTTP-сервис или обмен создаёт заказ с готовыми строками | Цены берите из 1С, а не из корзины сайта |
| Терминал сбора данных | Выгрузка отсканированных штрихкодов в документ | Неизвестные штрихкоды выводите списком, а не пропускайте молча |
Для всех трёх сценариев полезно одно и то же решение: вынести «добавление строки в табличную часть» в общий серверный модуль. Тогда подбор из формы, загрузка из файла и обмен с сайтом пересчитывают суммы и сворачивают дубли одинаково.
Ошибки при разработке подбора и как их найти
Отдельно про суммы. Если в документе есть скидки или НДС, считайте сумму строки той же процедурой, что срабатывает при ручном вводе количества. Иначе подобранная строка и строка, введённая руками, разойдутся на копейки, и это всплывёт при сверке.