Почему в отчете СКД в 1С:ERP не отображается Контрагент и как это исправить?

Программист 1С v8.3 (Управляемые формы) 1С:ERP Управление предприятием Управленческий учет
← На главную

При разработке отчетов на системе компоновки данных (СКД) в среде 1С:ERP Управление предприятием 2 программисты часто сталкиваются с ситуацией, когда данные в базе точно есть, запрос написан логично, но в результирующей таблице поле Контрагент остается пустым. Особенно часто это проявляется при попытке «дотянуться» до контрагента через документы расчетов или заказы. В этой статье мы подробно разберем, почему так происходит, и как правильно составить запрос, чтобы данные отображались корректно.

Проблема: Пустое поле Контрагент в отчете

Рассмотрим типичную ситуацию. Нам необходимо построить отчет по движению безналичных денежных средств в разрезе заказов и контрагентов. Мы используем регистр накопления ДенежныеСредстваБезналичные. Типичный запрос, который на первый взгляд кажется верным, выглядит следующим образом:


ВЫБРАТЬ
    ЕСТЬNULL(ДенежныеСредстваБезналичные.Заказ.Контрагент, ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)) КАК Контрагент,
    ДенежныеСредстваБезналичные.Период КАК Период,    
    ДенежныеСредстваБезналичные.БанковскийСчет КАК БанковскийСчет,
    ДенежныеСредстваБезналичные.Сумма КАК Сумма,     
    ДенежныеСредстваБезналичные.Заказ КАК Заказ
ИЗ
    РегистрНакопления.ДенежныеСредстваБезналичные КАК ДенежныеСредстваБезналичные
ГДЕ
    ДенежныеСредстваБезналичные.ХозяйственнаяОперация = &ХозяйственнаяОперация

Несмотря на использование ЕСТЬNULL и наличие данных в системе, в колонке «Контрагент» пользователь видит пустоту. Даже добавление левого соединения со справочником Контрагенты по прямой ссылке может не дать результата. Проанализируем причины этого поведения.

Причина 1: Влияние функциональных опций

В архитектуре 1С:ERP многие реквизиты объектов жестко связаны с функциональными опциями. Одной из ключевых является опция «Независимо вести партнеров и контрагентов». Если в настройках системы эта опция выключена, 1С предполагает, что партнер и контрагент — это одна и та же сущность (связь один-к-одному).

Важный нюанс работы СКД: Система компоновки данных анализирует метаданные. Если функциональная опция, управляющая видимостью реквизита, выключена, СКД может автоматически подставлять NULL при обращении к этому полю через точку (разыменование), даже если физически в таблице базы данных значение заполнено. Это механизм платформы по обеспечению целостности настроек интерфейса и логики программы.

Причина 2: Разыменование составных типов (две точки в запросе)

В регистре ДенежныеСредстваБезналичные измерение Заказ имеет составной тип данных. Оно может содержать ссылки на Заказ клиента, Заказ поставщику, Договор и другие документы. Когда мы пишем в запросе Заказ.Контрагент, система выполняет неявное левое соединение со всеми таблицами, входящими в этот составной тип.

Если хотя бы в одном из типов объектов, входящих в состав поля Заказ, отсутствует реквизит Контрагент, это может привести к некорректной работе оптимизатора запросов СКД. Кроме того, такое «разыменование» через точку является крайне непроизводительным для базы данных.

Решение 1: Использование прямого соединения со справочником

Проверенным способом обхода ограничений функциональных опций является явное левое соединение со справочником Контрагенты. При этом важно выбирать данные не из реквизита документа, а непосредственно из присоединенной таблицы справочника. Рассмотрим исправленный текст запроса:


ВЫБРАТЬ РАЗРЕШЕННЫЕ
    ДенежныеСредстваБезналичные.Период КАК Период,    
    ДенежныеСредстваБезналичные.БанковскийСчет КАК БанковскийСчет,
    ДенежныеСредстваБезналичные.Сумма КАК Сумма,     
    ДенежныеСредстваБезналичные.Заказ КАК Заказ,
    Контрагенты.Ссылка КАК Контрагент
ИЗ
    РегистрНакопления.ДенежныеСредстваБезналичные КАК ДенежныеСредстваБезналичные
    ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК Контрагенты
        ПО ДенежныеСредстваБезналичные.Заказ.Контрагент = Контрагенты.Ссылка
ГДЕ
    ДенежныеСредстваБезналичные.Период МЕЖДУ &НачалоПериода И &КонецПериода
    И ДенежныеСредстваБезналичные.ХозяйственнаяОперация = &ХозяйственнаяОперация

Почему это работает? Обращаясь к таблице Справочник.Контрагенты напрямую, мы указываем СКД, что нам нужна ссылка из самого справочника. В этом случае механизм контроля функциональных опций на уровне «разыменования поля через заказ» не срабатывает, и данные выводятся в отчет.

Решение 2: Приведение типов с помощью функции ВЫРАЗИТЬ

Профессиональным подходом к разработке в ERP считается использование конструкции ВЫРАЗИТЬ. Это позволяет системе точно знать, к какой таблице обращаться, и повышает производительность. Если мы знаем, что нас интересуют, например, только заказы клиентов, запрос следует переписать так:


ВЫБРАТЬ
    ВЫРАЗИТЬ(ДенежныеСредстваБезналичные.Заказ КАК Документ.ЗаказКлиента).Контрагент КАК Контрагент,
    ДенежныеСредстваБезналичные.Сумма КАК Сумма
ИЗ
    РегистрНакопления.ДенежныеСредстваБезналичные КАК ДенежныеСредстваБезналичные

Такой подход минимизирует количество неявных соединений и делает работу отчета более предсказуемой.

Решение 3: Использование специализированных регистров расчетов

Проанализируем структуру данных ERP глубже. Регистр ДенежныеСредстваБезналичные предназначен для учета остатков денег на счетах, и Контрагент там не является первичной аналитикой (он «спрятан» внутри объекта расчетов).

Для получения связки Платеж — Заказ — Контрагент гораздо эффективнее использовать регистры взаиморасчетов:

  1. РегистрНакопления.РасчетыСКлиентамиПоДокументам
  2. РегистрНакопления.РасчетыСПоставщикамиПоДокументам

В этих регистрах Контрагент является измерением. Если соединить данные о денежных средствах с данными из этих регистров по регистратору (документу оплаты), вы получите гарантированный доступ к контрагенту без каких-либо дополнительных ухищрений с разыменованием полей.

Дополнительные рекомендации

Разберем еще несколько моментов, которые могут влиять на результат:

  1. Права доступа (RLS): Даже если вы работаете под учетной записью администратора, наличие ключевого слова РАЗРЕШЕННЫЕ в запросе заставляет систему проверять ограничения. Убедитесь, что у пользователей (и у администратора, если RLS настроен жестко) есть права не только на чтение документа заказа, но и на просмотр реквизита Контрагент внутри него.
  2. Кэш пользовательских настроек: Часто бывает так, что программист исправил запрос, но в пользовательском режиме отчет все равно пустой. Это происходит из-за того, что 1С сохраняет настройки колонок и группировок. Выясним причину: если поле было добавлено или изменено, старый вариант отчета может его игнорировать. Всегда пробуйте нажать кнопку «Установить стандартные настройки» в меню «Прочее» (или «Еще») формы отчета.
  3. Партнеры vs Контрагенты: Помните, что в ERP управленческий учет ведется по Партнерам. Если отчет строится для целей управления, возможно, стоит выводить поле Заказ.Партнер. Если же нужна юридическая сущность — тогда используйте Контрагента через прямое соединение, как показано выше.

Подводя итог, можно сказать: наиболее стабильным решением для вывода контрагента в отчетах по денежным средствам в 1С:ERP является явное левое соединение со справочником Контрагенты или обращение к регистрам расчетов, где эта аналитика вынесена в измерения. Это гарантирует обход ограничений функциональных опций и обеспечивает высокую скорость работы отчета.

← На главную