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