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