Как реализовать подбор товаров с остатками по партиям в табличную часть документа

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке специализированных форм подбора номенклатуры с отображением остатков в разрезе партий разработчики часто сталкиваются с техническими ограничениями динамических списков на управляемых формах 1С. Рассмотрим типичные проблемы и разберем по шагам надежные способы реализации подбора.

Анализ причин проблемы

Проанализируем две распространенные ситуации, возникающие при попытке построить произвольный запрос в динамическом списке с левым соединением справочника номенклатуры и регистра остатков:

  1. Указана основная таблица динамического списка: если в свойствах списка выбрана основная таблица (например, Справочник.Номенклатура), платформа ожидает, что поле Ссылка будет уникальным идентификатором каждой строки. Когда у одной номенклатурной позиции есть несколько партий с остатками, результат запроса возвращает несколько строк с одинаковой ссылкой. Это приводит к ошибке платформы о дублировании ключевых значений.
  2. Основная таблица не указана: при очистке свойства Основная таблица ошибка дублирования исчезает, однако отключается стандартный механизм выбора ссылки. Платформа больше не понимает, какое именно значение нужно вернуть в вызывающую форму, и стандартный выбор в табличную часть перестает автоматически переносить данные. Кроме того, табличная часть документа не умеет автоматически распределять составные данные (номенклатуру, партию и остаток) по своим реквизитам.

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

Способ 1. Использование формы подбора с передачей структуры данных

Разберем вариант, при котором запрос динамического списка остается без указания основной таблицы, а передача данных в документ настраивается вручную через программные обработчики.

В форме подбора у динамического списка оставляем свойство Основная таблица пустым. В свойствах таблицы списка отключаем стандартную обработку выбора и настраиваем событие Выбор:


&НаКлиенте
Процедура СписокВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    ДанныеСтроки = Элемент.ТекущиеДанные;
    
    Если ДанныеСтроки <> Неопределено Тогда
        СтруктураВыбора = Новый Структура;
        СтруктураВыбора.Вставить("Номенклатура", ДанныеСтроки.Ссылка);
        СтруктураВыбора.Вставить("Партия", ДанныеСтроки.Партия);
        СтруктураВыбора.Вставить("Остаток", ДанныеСтроки.Остаток);
        
        ОповеститьОВыборе(СтруктураВыбора);
    КонецЕсли;
КонецПроцедуры

В форме документа, из которой вызывается подбор, открываем форму подбора и передаем текущую форму в качестве владельца:


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

В модуле формы документа описываем обработчик события ОбработкаВыбора, который принимает структуру и добавляет строку в табличную часть:


&НаКлиенте
Процедура ОбработкаВыбора(ВыбранноеЗначение, ИсточникВыбора)
    Если ТипЗнч(ВыбранноеЗначение) = Тип("Структура") Тогда
        НоваяСтрока = Объект.Товары.Добавить();
        НоваяСтрока.Номенклатура = ВыбранноеЗначение.Номенклатура;
        НоваяСтрока.Партия = ВыбранноеЗначение.Партия;
        НоваяСтрока.Количество = 1;
    КонецЕсли;
КонецПроцедуры

Способ 2. Архитектура с двумя связанными таблицами (Мастер-деталь)

Рассмотрим более удобный с точки зрения интерфейса и быстродействия подход. Форма подбора разделяется на две области:

  1. Верхняя таблица (Мастер): динамический список номенклатуры с установленной основной таблицей Справочник.Номенклатура. В нем отсутствуют соединения с партиями, что исключает дубли и сохраняет быстрый стандартный поиск и дерево групп.
  2. Нижняя таблица (Деталь): динамический список остатков по партиям, который отбирается по текущей выбранной номенклатуре из верхней таблицы.

Посмотрим на пример настройки связи. В событии ПриАктивизацииСтроки верхней таблицы передаем ссылку на товар в параметры запроса нижнего списка:


&НаКлиенте
Процедура СписокНоменклатураПриАктивизацииСтроки(Элемент)
    ТекущиеДанные = Элемент.ТекущиеДанные;
    Если ТекущиеДанные <> Неопределено Тогда
        СписокПартии.Параметры.УстановитьЗначениеПараметра("Номенклатура", ТекущиеДанные.Ссылка);
    КонецЕсли;
КонецПроцедуры

Выбор значения в документ в этом случае выполняется двойным кликом по конкретной партии из нижней таблицы с вызовом процедуры ОповеститьОВыборе().

Способ 3. Подбор через корзину на основе таблицы значений

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

  1. Остатки и партии считываются запросом на сервере и помещаются в реквизит формы с типом ТаблицаЗначений.
  2. Пользователь выбирает позиции и указывает количество, заполняя корзину прямо в форме подбора.
  3. По нажатию кнопки Перенести в документ массив или таблица выбранных строк передается в форму документа через механизм оповещений или стандартное оповещение о выборе.

Данный подход полностью снимает ограничения динамических списков и дает максимальный контроль над валидацией вводимых количеств и остатков.

← На главную