Механизм подбора в 1С 8.3: от типовой кнопки до своей обработки с корзиной

· 10 мин

Содержание

Подбор в 1С 8.3 реализуют так: из формы документа открывают форму выбора или свою обработку с параметром ЗакрыватьПриВыборе = Ложь, передают владельцем саму форму документа, а строки получают в событии ОбработкаВыбора. Подборщик отдаёт результат методом ОповеститьОВыборе — одним значением, массивом или адресом во временном хранилище.

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

Как устроен типовой подбор и где он есть

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

Что обычно умеет типовая форма подбора:

  • 📦 показывает остатки на складе из шапки документа;
  • 💰 подставляет цену по виду цен документа;
  • 🔎 ищет по наименованию, артикулу и штрихкоду;
  • 🧺 копит позиции в корзине и переносит их в документ одной командой.

Где искать кнопку в документах:

КонфигурацияДокументГде команда
Бухгалтерия предприятия 3.0Реализация, Поступление, Счёт покупателюКомандная панель табличной части «Товары» / «Услуги»
Управление торговлей 11Заказ клиента, Реализация товаров и услугКомандная панель табличной части «Товары»

Если кнопки не видно, проверьте Ещё → Изменить форму: команду могли скрыть в пользовательских настройках формы. Там же её возвращают на место.

Как доработать стандартный подбор: колонки и фильтры

Простые вещи пользователь делает сам, без программиста:

  1. Откройте форму подбора.
  2. В меню Ещё выберите Изменить форму.
  3. Отметьте скрытые колонки (например, артикул или единицу измерения) и перетащите их в нужный порядок.
  4. Нажмите OK — настройка сохранится для этого пользователя.

Новые колонки и отборы, которых в форме нет, добавляют через расширение конфигурации . Снимать типовую конфигурацию с поддержки ради подбора не нужно: обновления потом придётся объединять вручную.

Порядок работы в расширении:

  1. В конфигураторе откройте Конфигурация → Расширения конфигурации, создайте расширение.
  2. В дереве основной конфигурации найдите форму подбора. Проще всего — через модуль формы документа: в обработчике команды подбора виден вызов ОткрытьФорму с полным именем формы.
  3. Через контекстное меню формы выберите Добавить в расширение.
  4. Добавьте реквизит формы, например ТолькоВНаличии (тип «Булево»), и разместите его над списком.
  5. В модуле заимствованной формы напишите обработчик изменения флажка, который ставит отбор на список.

Если форма построена на динамическом списке, отбор проще всего ставить через Список.Отбор или параметр запроса списка — так фильтрует СУБД, а не клиент.

&НаКлиенте
Процедура РасшТолькоВНаличииПриИзменении(Элемент)
	Список.Параметры.УстановитьЗначениеПараметра("ТолькоВНаличии", ТолькоВНаличии);
КонецПроцедуры

Пример работает, только если в тексте запроса списка есть параметр &ТолькоВНаличии. В типовой форме его нет. Если запрос менять нельзя, используйте отбор по существующему полю списка.

Своя обработка подбора: пошагово с кодом

Своя обработка нужна, когда типовой формы нет (самописная конфигурация) или она не подходит: другой учёт остатков, своя логика цен, подбор услуг по договору.

Шаг 1. Создайте обработку и форму

Создайте обработку ПодборТоваров с одной управляемой формой. На форме:

  • 📋 динамический список Список по справочнику номенклатуры;
  • 🧺 реквизит Корзина типа «ТаблицаЗначений» с колонками Номенклатура, Количество, Цена;
  • 🔘 команда ПеренестиВДокумент.

Шаг 2. Откройте подбор из документа

В форме документа добавьте команду Подбор и разместите её в командной панели табличной части.

&НаКлиенте
Процедура Подбор(Команда)
	ПараметрыФормы = Новый Структура;
	ПараметрыФормы.Вставить("Склад", Объект.Склад);
	ПараметрыФормы.Вставить("ЗакрыватьПриВыборе", Ложь);
	ОткрытьФорму("Обработка.ПодборТоваров.Форма.Форма", ПараметрыФормы, ЭтотОбъект);
КонецПроцедуры

Третий параметр ЭтотОбъект делает документ владельцем формы. Без него ОповеститьОВыборе некому будет отдать результат.

Шаг 3. Добавляйте позиции в корзину

Двойной щелчок по строке списка вызывает событие Выбор. Перехватываем его и спрашиваем количество.

&НаКлиенте
Процедура СписокВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
	СтандартнаяОбработка = Ложь;
	ДанныеСтроки = Элементы.Список.ТекущиеДанные;
	Контекст = Новый Структура("Номенклатура, Цена", ВыбраннаяСтрока, ДанныеСтроки.Цена);
	Оповещение = Новый ОписаниеОповещения("ПослеВводаКоличества", ЭтотОбъект, Контекст);
	ПоказатьВводЧисла(Оповещение, 1, "Количество", 15, 3);
КонецПроцедуры

&НаКлиенте
Процедура ПослеВводаКоличества(Число, Контекст) Экспорт
	Если Число = Неопределено Или Число <= 0 Тогда
		Возврат;
	КонецЕсли;
	Найденные = Корзина.НайтиСтроки(Новый Структура("Номенклатура", Контекст.Номенклатура));
	Если Найденные.Количество() > 0 Тогда
		Найденные[0].Количество = Найденные[0].Количество + Число;
	Иначе
		НоваяСтрока = Корзина.Добавить();
		НоваяСтрока.Номенклатура = Контекст.Номенклатура;
		НоваяСтрока.Количество = Число;
		НоваяСтрока.Цена = Контекст.Цена;
	КонецЕсли;
КонецПроцедуры

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

Шаг 4. Перенесите корзину в документ

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

Перед вызовом ставим ЗакрыватьПриВыборе = Истина, чтобы форма закрылась после переноса. Пока пользователь копит корзину, она остаётся открытой.

Шаг 5. Примите строки в документе

&НаКлиенте
Процедура ОбработкаВыбора(ВыбранноеЗначение, ИсточникВыбора)
	Если ИсточникВыбора.ИмяФормы <> "Обработка.ПодборТоваров.Форма.Форма" Тогда
		Возврат;
	КонецЕсли;
	Для Каждого Позиция Из ВыбранноеЗначение Цикл
		Найденные = Объект.Товары.НайтиСтроки(Новый Структура("Номенклатура", Позиция.Номенклатура));
		Если Найденные.Количество() > 0 Тогда
			СтрокаТЧ = Найденные[0];
			СтрокаТЧ.Количество = СтрокаТЧ.Количество + Позиция.Количество;
		Иначе
			СтрокаТЧ = Объект.Товары.Добавить();
			СтрокаТЧ.Номенклатура = Позиция.Номенклатура;
			СтрокаТЧ.Количество = Позиция.Количество;
			СтрокаТЧ.Цена = Позиция.Цена;
		КонецЕсли;
		СтрокаТЧ.Сумма = СтрокаТЧ.Количество * СтрокаТЧ.Цена;
	КонецЦикла;
	Модифицированность = Истина;
КонецПроцедуры

Проверка ИмяФормы нужна, потому что ОбработкаВыбора срабатывает на любой выбор, где документ — владелец: выбор контрагента, склада, договора.

Проверка своей обработки подбора
Выполнено: 0 / 6

Подбор с остатками, ценами и характеристиками

Остатки и цены в подборе показывают одним запросом динамического списка. Включите у списка флажок «Произвольный запрос», основной таблицей укажите справочник номенклатуры.

Ниже пример для самописной конфигурации с регистром накопления ОстаткиТоваров и регистром сведений ЦеныНоменклатуры. Имена регистров замените на свои: в типовых конфигурациях они другие.

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

Параметры заполняют при создании формы:

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	Список.Параметры.УстановитьЗначениеПараметра("Склад", Параметры.Склад);
	Список.Параметры.УстановитьЗначениеПараметра("ВидЦены", Справочники.ВидыЦен.Розничная);
	Список.Параметры.УстановитьЗначениеПараметра("ТолькоВНаличии", Ложь);
КонецПроцедуры

Предопределённый элемент Розничная — для примера. В рабочей обработке вид цены приходит из документа так же, как склад.

Характеристики и серии

Если товары учитывают по характеристикам (размер, цвет), остаток хранится в разрезе пары «номенклатура + характеристика». Тогда:

  1. Добавьте Характеристика в корзину и в табличную часть документа.
  2. Ищите строку корзины по двум полям: Новый Структура("Номенклатура, Характеристика", ...).
  3. Для товара с характеристиками после выбора открывайте второй список — остатки по характеристикам этой позиции. Пользователь выбирает размер, а не видит сто строк «Футболка».

Услуги

У услуг нет остатков. Флажок «Только в наличии» для них отключайте, иначе услуги пропадут из списка. Удобно разделить подбор на две вкладки: товары с остатками и услуги без них.

Как ускорить подбор на большой базе

Медленный подбор — почти всегда вопрос запроса, а не «тяжёлого клиента». Что проверить:

  • ⚙️ Условия в параметрах виртуальной таблицы. Остатки(, Склад = &Склад) фильтрует на стороне регистра. Условие на склад в ГДЕ после соединения заставит СУБД посчитать остатки по всем складам.
  • ⚙️ Динамическое считывание. У динамического списка оно включено по умолчанию. Список читает данные порциями по мере прокрутки, а не весь справочник сразу.
  • ⚙️ Один вызов сервера на перенос. Корзину передают целиком одним массивом. Цикл с серверным вызовом на каждую строку при 300 позициях даст 300 обращений к серверу.
  • ⚙️ Временное хранилище для больших корзин. Если в корзине тысячи строк, выгрузите её на сервере в таблицу значений, поместите ПоместитьВоВременноеХранилище и передайте через ОповеститьОВыборе только адрес. Документ заберёт данные ПолучитьИзВременногоХранилища в серверной процедуре.
  • ⚙️ Поиск по штрихкоду. Штрихкоды держат в отдельном регистре сведений с измерением «Штрихкод». Поиск по измерению идёт по индексу и не перебирает справочник.

Не вычисляйте остаток функцией в каждой строке списка (через обращение к серверу из события строки). При 50 видимых строках это 50 отдельных запросов на каждую прокрутку.

Подбор в мобильном приложении 1С

На мобильной платформе работает та же схема: ОткрытьФорму с владельцем, ОповеститьОВыборе, ОбработкаВыбора. Меняется интерфейс.

Что учесть при разработке:

  • 📱 Без модальности. Все вопросы и ввод числа — только через ОписаниеОповещения. Код из шага 3 переносится как есть.
  • 📱 Поиск вместо дерева. Дерево групп на маленьком экране неудобно. Строка поиска по наименованию и артикулу работает быстрее.
  • 📱 Крупные кнопки «+» и «−». Вместо ввода количества с клавиатуры добавьте в строку списка две команды, меняющие количество на единицу.
  • 📱 Сканирование камерой. Мобильная платформа умеет читать штрихкод камерой через объект СредстваМультимедиа. Перед вызовом проверьте, что устройство поддерживает сканирование.
  • 📱 Автономная работа. Если приложение работает без связи, остатки и цены приходят в мобильную базу обменом. Показывайте дату последней синхронизации прямо в форме подбора, чтобы торговый представитель видел, насколько свежи остатки.

Подбор из внешних источников: файлы, сайт, терминалы сбора данных

Не каждый подбор делается мышкой в форме. Три частых сценария:

ИсточникКак попадает в 1СНа что смотреть
Таблица Excel от клиентаЗагрузка в табличную часть: сопоставление колонок с полямиКлюч поиска товара — артикул или штрихкод, не наименование
Корзина интернет-магазинаHTTP-сервис или обмен создаёт заказ с готовыми строкамиЦены берите из 1С, а не из корзины сайта
Терминал сбора данныхВыгрузка отсканированных штрихкодов в документНеизвестные штрихкоды выводите списком, а не пропускайте молча

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

Сопоставление полей
Артикул в файле→Номенклатура (поиск по артикулу)
Количество→Количество
Штрихкод→Номенклатура и характеристика (поиск в регистре штрихкодов)
Цена из файла→Не переносить, взять по виду цен документа

Ошибки при разработке подбора и как их найти

Диагностика: выберите симптом

Отдельно про суммы. Если в документе есть скидки или НДС, считайте сумму строки той же процедурой, что срабатывает при ручном вводе количества. Иначе подобранная строка и строка, введённая руками, разойдутся на копейки, и это всплывёт при сверке.

Частые вопросы

Можно ли сделать подбор без программирования?
Только в рамках готовой формы: показать скрытые колонки через «Изменить форму», сохранить отборы. Новые поля и своя логика требуют расширения или доработки конфигурации.
Чем подбор отличается от обычного выбора из списка?
Выбор возвращает одно значение и закрывает форму. Подбор оставляет форму открытой и копит несколько позиций, которые переносятся в документ сразу.
Слетит ли доработка подбора при обновлении типовой конфигурации?
Расширение при обновлении сохраняется. Если разработчики переименуют элементы заимствованной формы, расширение выдаст ошибку при проверке, и его придётся поправить.
Можно ли подбирать сразу в несколько табличных частей?
Да. Передайте в параметрах формы имя табличной части, а в ОбработкаВыбора раскладывайте строки по этому признаку: товары в одну таблицу, услуги в другую.
Как показать в подборе фото товара?
Добавьте на форму поле картинки и выводите в него изображение текущей строки списка при её активизации. Получать картинку лучше по ссылке на файл, а не хранить её прямо в справочнике.