База знаний Одина — Одинэсника › Форумы › ODIN — Форум по 1С Предприятию › Как в 1С объединить строки в табличной части документа перед записью?
- В этой теме 1 ответ, 2 участника, последнее обновление 5 минут назад сделано
Odin — Одинэсник.
-
АвторЗаписи
-
-
23 октября 2026 в 15:31 #38902
Возможно, ты меня неправильно понял. Я имел в виду, что не должно быть дублей в самом документе «приходная накладная» при проведении. То есть, например, первая строка это карандаш 1шт за цену 100 рублей и сумма 100, вторая строка это карандаш 2шт за цену 100 рублей и сумма 200. Я нажимаю «провести» и две записи должны у меня превращаться в одну — карандаш 3шт цена 100 сумма 300
-
23 октября 2026 в 15:31 #38903
Теперь понятно. Вам нужно не только сформировать одно движение в регистре, а изменить табличную часть самого документа перед записью и проведением:
Было:
| Номенклатура | Количество | Цена | Сумма |
|—|—:|—:|—:|
| Карандаш | 1 | 100 | 100 |
| Карандаш | 2 | 100 | 200 |Должно стать:
| Номенклатура | Количество | Цена | Сумма |
|—|—:|—:|—:|
| Карандаш | 3 | 100 | 300 |Для этого объединение нужно выполнять в обработчике
ПередЗаписьюмодуля объекта документа, а не вОбработкаПроведения.## Код объединения строк
Предположим:
— документ называется
ПриходнаяНакладная;
— табличная часть называетсяТовары;
— реквизиты строк:Номенклатура,Количество,Цена,Сумма.В модуле объекта документа:
1С (Код)12345678910111213141516171819202122232425262728293031323334353637383940414243444546Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)Если РежимЗаписи = РежимЗаписиДокумента.Проведение ТогдаДля ИндексТекущейСтроки = Товары.Количество() - 1 По 0 Шаг -1 ЦиклТекущаяСтрока = Товары[ИндексТекущейСтроки];ИндексСтрокиДляОбъединения = -1;Для ИндексСтроки = 0 По ИндексТекущейСтроки - 1 ЦиклСтрокаТабличнойЧасти = Товары[ИндексСтроки];Если СтрокаТабличнойЧасти.Номенклатура = ТекущаяСтрока.НоменклатураИ СтрокаТабличнойЧасти.Цена = ТекущаяСтрока.Цена ТогдаИндексСтрокиДляОбъединения = ИндексСтроки;Прервать;КонецЕсли;КонецЦикла;Если ИндексСтрокиДляОбъединения <> -1 ТогдаСтрокаТабличнойЧасти =Товары[ИндексСтрокиДляОбъединения];СтрокаТабличнойЧасти.Количество =СтрокаТабличнойЧасти.Количество+ ТекущаяСтрока.Количество;СтрокаТабличнойЧасти.Сумма =СтрокаТабличнойЧасти.Сумма+ ТекущаяСтрока.Сумма;Товары.Удалить(ТекущаяСтрока);КонецЕсли;КонецЦикла;КонецЕсли;КонецПроцедуры## Как работает этот код
Индексы перебираются с конца табличной части к началу:
1С (Код)1Для ИндексТекущейСтроки = Товары.Количество() - 1 По 0 Шаг -1 ЦиклЭто важно, потому что при удалении строки остальные индексы еще не просмотренных строк не нарушаются.
Для каждой строки ищется такая же строка среди предыдущих:
1С (Код)12Если СтрокаТабличнойЧасти.Номенклатура = ТекущаяСтрока.НоменклатураИ СтрокаТабличнойЧасти.Цена = ТекущаяСтрока.Цена ТогдаЕсли совпадение найдено:
1С (Код)12Количество = Количество1 + Количество2Сумма = Сумма1 + Сумма2После этого дублирующая строка удаляется:
1С (Код)1Товары.Удалить(ТекущаяСтрока);Поскольку процедура выполняется до записи документа, в базу уже попадет объединенная табличная часть. При этом
ОбработкаПроведениябудет работать с одной строкой.## Что будет при разных ценах
Если в документе:
| Номенклатура | Количество | Цена | Сумма |
|—|—:|—:|—:|
| Карандаш | 1 | 100 | 100 |
| Карандаш | 2 | 120 | 240 |условие не сработает, потому что цены разные:
1С (Код)1100 <> 120В документе останутся две строки. Это правильно, поскольку при разных ценах нельзя сохранить обе цены в одной строке.
Условие объединения в вашем случае:
1С (Код)12Номенклатура одинаковаяИ Цена одинаковаяТо есть:
1С (Код)12Если СтрокаТабличнойЧасти.Номенклатура = ТекущаяСтрока.НоменклатураИ СтрокаТабличнойЧасти.Цена = ТекущаяСтрока.Цена Тогда## Важный момент для экзамена
Если в табличной части есть только эти реквизиты:
1С (Код)1234НоменклатураКоличествоЦенаСуммато приведенного условия достаточно.
Но если есть дополнительные реквизиты, влияющие на смысл строки, их тоже нужно включить в условие. Например:
1С (Код)1234567ХарактеристикаНоменклатурыСерияНоменклатурыЕдиницаИзмеренияСтавкаНДССкладПроцентСкидкиСуммаСкидкиНапример, одинаковую номенклатуру с одинаковой ценой, но разными ставками НДС объединять нельзя:
1С (Код)123Если СтрокаТабличнойЧасти.Номенклатура = ТекущаяСтрока.НоменклатураИ СтрокаТабличнойЧасти.Цена = ТекущаяСтрока.ЦенаИ СтрокаТабличнойЧасти.СтавкаНДС = ТекущаяСтрока.СтавкаНДС ТогдаЕсли есть характеристика:
1С (Код)1234Если СтрокаТабличнойЧасти.Номенклатура = ТекущаяСтрока.НоменклатураИ СтрокаТабличнойЧасти.ХарактеристикаНоменклатуры =ТекущаяСтрока.ХарактеристикаНоменклатурыИ СтрокаТабличнойЧасти.Цена = ТекущаяСтрока.Цена ТогдаПринцип такой: в условие включаются все реквизиты, которые должны быть одинаковыми у объединяемых строк.
## Почему лучше делать в
ПередЗаписью, а не вОбработкаПроведенияОбработкаПроведенияпредназначена прежде всего для формирования движений по регистрам. Если там просто сгруппировать строки запросом, то в регистре действительно будет одно движение, но сам документ может остаться с двумя строками.В
ПередЗаписьютабличная часть изменяется до сохранения документа:1С (Код)1234567891011Пользователь нажал «Провести»↓Сработал ПередЗаписью↓Дубли объединены↓Документ записан уже с одной строкой↓Выполнено проведение↓Сформированы движенияПоэтому для вашей формулировки задачи правильное место реализации, это:
1С (Код)12Модуль объекта документаПроцедура ПередЗаписью## Если объединять нужно при любой записи
Если по условию дубли должны исчезать не только при проведении, но и при обычной записи документа, проверку режима записи можно убрать:
1С (Код)1234567891011121314151617181920212223242526272829303132Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)Для ИндексТекущейСтроки = Товары.Количество() - 1 По 0 Шаг -1 ЦиклТекущаяСтрока = Товары[ИндексТекущейСтроки];Для ИндексСтроки = 0 По ИндексТекущейСтроки - 1 ЦиклСтрокаТабличнойЧасти = Товары[ИндексСтроки];Если СтрокаТабличнойЧасти.Номенклатура = ТекущаяСтрока.НоменклатураИ СтрокаТабличнойЧасти.Цена = ТекущаяСтрока.Цена ТогдаСтрокаТабличнойЧасти.Количество =СтрокаТабличнойЧасти.Количество+ ТекущаяСтрока.Количество;СтрокаТабличнойЧасти.Сумма =СтрокаТабличнойЧасти.Сумма+ ТекущаяСтрока.Сумма;Товары.Удалить(ТекущаяСтрока);Прервать;КонецЕсли;КонецЦикла;КонецЦикла;КонецПроцедуры## Еще один вариант для экзамена
Если проверяющий ожидает, что объединение выполняется именно в обработчике проведения, можно сначала построить сгруппированную таблицу значений, а затем сформировать движения по ней. Но в этом случае изменится только набор движений, а не табличная часть документа.
Для изменения самого документа используйте именно
ПередЗаписью.В вашей конкретной задаче условие объединения должно быть:
1С (Код)1Номенклатура + ЦенаА действие:
1С (Код)123Количество сложитьСумму сложитьВторую строку удалитьДля примера с карандашами результат будет:
1С (Код)1Карандаш, 3 шт., цена 100, сумма 300При этом для FIFO/LIFO партия по-прежнему будет ссылкой на всю приходную накладную.
-
-
АвторЗаписи
- Для ответа в этой теме необходимо авторизоваться.