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