Почему дублируются данные при выводе отчета в 1С и как это исправить?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке отчетов и печатных форм программисты 1С часто сталкиваются с ситуацией, когда в результирующей таблице строки начинают дублироваться. На первый взгляд код вывода кажется абсолютно корректным, а простое сообщение через Сообщить() может вводить в заблуждение, скрывая повторяющиеся записи. Рассмотрим подробнее, почему возникает такое поведение и как правильно локализовать и устранить проблему.

Причины дублирования строк

Проанализируем основные факторы, приводящие к появлению повторяющихся данных:

  1. Связь «один ко многим» в запросе. Это самая распространенная причина. Если при использовании конструкций ЛЕВОЕ СОЕДИНЕНИЕ или ПОЛНОЕ СОЕДИНЕНИЕ ключевому полю левой таблицы соответствует несколько записей в правой таблице, исходная строка размножается ровно столько раз, сколько совпадений найдено в подчиненном источнике.
  2. Неполные условия соединения. Пропуск ключевых полей в секции ПО (например, соединение справочников или документов без учета организации, подразделения или периода действия).
  3. Некорректная работа с периодическими регистрами сведений. Прямое обращение к физической таблице регистра вместо вызова виртуальной таблицы СрезПоследних() приводит к тому, что в выборку попадает вся история изменений по объекту.
  4. «Залипание» параметров области макета. Если область макета получена до цикла, а внутри итераций выполняется только вывод, значения параметров из предыдущих строк могут оставаться в ячейках, если для текущей строки новые значения не были переданы.

Способы исправления дублей в запросе

Разберем по шагам, как можно модифицировать текст запроса для исключения дублирования строк.

1. Использование ключевого слова РАЗЛИЧНЫЕ

Если дублирование вызвано соединением и все поля строки полностью идентичны, можно применить модификатор РАЗЛИЧНЫЕ:


ВЫБРАТЬ РАЗЛИЧНЫЕ
    Сотрудники.Код КАК Дкод,
    Сотрудники.Наименование КАК ФИО
ИЗ
    Справочник.Сотрудники КАК Сотрудники
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ДополнительныеДанные КАК ДопДанные
        ПО Сотрудники.Ссылка = ДопДанные.Сотрудник

2. Группировка данных

Когда требуется исключить дубли по ключевым полям и свернуть числовые показатели, используем конструкцию СГРУППИРОВАТЬ ПО с агрегатными функциями:


ВЫБРАТЬ
    Сотрудники.Код КАК Дкод,
    Сотрудники.Наименование КАК ФИО,
    МАКСИМУМ(ДопДанные.Значение) КАК ЗначениеПараметра
ИЗ
    Справочник.Сотрудники КАК Сотрудники
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ДополнительныеДанные КАК ДопДанные
        ПО Сотрудники.Ссылка = ДопДанные.Сотрудник
СГРУППИРОВАТЬ ПО
    Сотрудники.Код,
    Сотрудники.Наименование

3. Предварительная свертка во временных таблицах

Если подчиненная таблица содержит дублирующиеся ключи, правильным решением будет предварительно подготовить и сгруппировать данные во временной таблице до основного соединения:


ВЫБРАТЬ
    ДопДанные.Сотрудник КАК Сотрудник,
    МАКСИМУМ(ДопДанные.Период) КАК Период
ПОМЕСТИТЬ ВТ_АктуальныеДанные
ИЗ
    РегистрСведений.ДополнительныеДанные КАК ДопДанные
СГРУППИРОВАТЬ ПО
    ДопДанные.Сотрудник
;

ВЫБРАТЬ
    Сотрудники.Код КАК Дкод,
    Сотрудники.Наименование КАК ФИО
ИЗ
    Справочник.Сотрудники КАК Сотрудники
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_АктуальныеДанные КАК ВТ
        ПО Сотрудники.Ссылка = ВТ.Сотрудник

Корректная работа с макетом и табличным документом

Посмотрим на частую ошибку заполнения параметров области. Вместо универсальной процедуры ЗаполнитьЗначенияСвойств() для объектов табличного документа платформой предусмотрен оптимизированный метод Заполнить() у коллекции параметров.

Разберем правильный алгоритм вывода строк в цикле:


ТабДок = Новый ТабличныйДокумент;
Макет = ПолучитьМакет("Макет");
ОбластьСтрока = Макет.ПолучитьОбласть("Строка");

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл
    // Инициализируем область заново или заполняем параметры напрямую
    ОбластьСтрока.Параметры.Заполнить(Выборка);
    ТабДок.Вывести(ОбластьСтрока);
КонецЦикла;

Важные рекомендации:

  1. Для соединения таблиц в запросах всегда используйте ссылки (поле Ссылка), а не строковые или числовые коды (Код), так как коды могут дублироваться между разными группами или элементами.
  2. При возникновении дублирования обязательно проверяйте результат запроса в консоли запросов или через точку останова в отладчике, просматривая полную таблицу результата, а не отдельные поля через текстовые сообщения.
  3. Для сложных отчетов с множеством связей и иерархией рекомендуется использовать Систему компоновки данных (СКД), которая автоматически оптимизирует соединения и рассчитывает итоги без ручного обхода выборок.
← На главную