При разработке отчетов или обработок в 1С часто возникает задача, когда необходимо объединить данные из двух разных таблиц, не имеющих однозначной связи «один-к-одному». Типичный пример: у нас есть таблица движений (продажи и возвраты) и таблица корректировок к ним. Сложность заключается в том, что системе нужно «объяснить», какую именно строку из множества записей одного контрагента нужно откорректировать.
Когда мы просто пытаемся соединить таблицы по полям Контрагент и Статус, система находит все совпадения. Если у контрагента «К1» есть несколько записей по «продаже», а в таблице корректировок пришла одна сумма, стандартное соединение может привести к дублированию строк или некорректному суммированию. Нам необходимо принудительно «зацепиться» за конкретную строку, чтобы корректировка сработала точечно.
Самым надежным способом решения этой задачи является создание искусственного ключа с помощью встроенной функции АВТОНОМЕРЗАПИСИ(). Давайте разберем этот процесс по шагам.
АВТОНОМЕРЗАПИСИ присваиваем каждой строке уникальный номер.Контрагент + Статус), чтобы определить, к какой строке мы будем «привязывать» корректировку.Рассмотрим пример кода, который позволяет реализовать этот механизм:
// Шаг 1: Присваиваем каждой строке уникальный номер
ВЫБРАТЬ
Табличка1.Контрагент КАК Контрагент,
Табличка1.СтатусДокумента КАК СтатусДокумента,
Табличка1.Сумма КАК Сумма,
АВТОНОМЕРЗАПИСИ() КАК НомерСтроки
ПОМЕСТИТЬ ТабличкаСНомеромСтроки
ИЗ Табличка1 КАК Табличка1;
// Шаг 2: Определяем, какая строка будет главной для корректировки
ВЫБРАТЬ
ТабличкаСНомеромСтроки.Контрагент КАК Контрагент,
ТабличкаСНомеромСтроки.СтатусДокумента КАК СтатусДокумента,
МИНИМУМ(ТабличкаСНомеромСтроки.НомерСтроки) КАК НомерСтроки
ПОМЕСТИТЬ ТабличкаСНУжнымиНомерамиСтрок
ИЗ ТабличкаСНомеромСтроки КАК ТабличкаСНомеромСтроки
СГРУППИРОВАТЬ ПО ТабличкаСНомеромСтроки.Контрагент, ТабличкаСНомеромСтроки.СтатусДокумента;
После того как мы получили временную таблицу с «якорными» строками, мы можем легко присоединить к ним таблицу корректировок. Важно учитывать, что если корректировок нет, нам нужно получить 0, поэтому используем ЕСТЬNULL.
ВЫБРАТЬ
ТабличкаСНомеромСтроки.Контрагент,
ТабличкаСНомеромСтроки.СтатусДокумента,
ТабличкаСНомеромСтроки.Сумма,
ЕСТЬNULL(Результат.СуммаКорректировки, 0) КАК СуммаКорректировки
ИЗ ТабличкаСНомеромСтроки КАК ТабличкаСНомеромСтроки
ЛЕВОЕ СОЕДИНЕНИЕ Результат КАК Результат
ПО Результат.НомерСтроки = ТабличкаСНомеромСтроки.НомерСтроки
Этот подход решает проблему недетерминированности. Вместо того чтобы позволять системе выбирать строку для корректировки случайным образом, мы явно указываем ей: «применяй корректировку только к записи с таким-то уникальным номером».
Советы по оптимизации:
АВТОНОМЕРЗАПИСИ по каким-то причинам не подходит, можно создать отдельную таблицу чисел от 1 до N и использовать ее для перемножения исходных данных, но этот метод сложнее в поддержке.Используя предложенные методы, вы сможете легко справляться с задачами по перераспределению сумм и корректировке данных, делая свои отчеты точными и предсказуемыми.