Почему запрос СКД работает в консоли, но выдает неверные данные в отчете 1С:Предприятие

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

Разработчики 1С часто сталкиваются с ситуацией: сложный запрос, написанный и протестированный в консоли компоновки данных, работает идеально. Однако стоит перенести этот запрос в реальный отчет и запустить его в режиме 1С:Предприятие, как данные начинают «плыть», исчезать или заменяться неверными значениями. Особенно часто это проявляется при работе с кадровыми данными в конфигурации Зарплата и управление персоналом 3.1.

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

Причина №1: Оптимизация текста запроса в СКД

Главное отличие консоли запросов от реального отчета СКД заключается в том, что СКД — это не просто «исполнитель» текста запроса, а сложный генератор. Перед тем как отправить запрос в СУБД, система анализирует, какие поля выбрал пользователь на вкладке «Выбранные поля».

Проанализируем ситуацию: если в вашем запросе во временной таблице выбираются поля Подразделение и Должность, но в итоговом отчете пользователь вывел только ФизическоеЛицо, СКД может посчитать поля Подразделение и Должность лишними и просто вырезать их из текста запроса для «оптимизации». Это приводит к тому, что группировки и соединения начинают работать не так, как вы ожидали.

Как это исправить:

  1. Перейдите в конструктор схемы компоновки данных на вкладку «Наборы данных».
  2. В списке полей найдите те поля, которые критически важны для логики вашего запроса (например, ключевые поля во временных таблицах или поля, по которым идет соединение).
  3. В колонке «Роль» для этих полей установите флаг «Обязательное». Это гарантирует, что СКД включит их в итоговый SQL-запрос, даже если пользователь не выбрал их в настройках отчета.

Причина №2: Проблема использования «ВЫБРАТЬ ПЕРВЫЕ 1» во временных таблицах

Рассмотрим подробнее логическую ошибку, которая часто встречается в запросах к кадровым регистрам. Использование инструкции ВЫБРАТЬ ПЕРВЫЕ 1 вместе с УПОРЯДОЧИТЬ ПО во временной таблице — это «мина замедленного действия» для отчета, который должен выводить список данных.

Если вы пишете ВЫБРАТЬ ПЕРВЫЕ 1, запрос вернет ровно одну строку для всей таблицы. В консоли при тестировании на одном сотруднике это может сработать. Но когда вы строите отчет по всей организации, во временную таблицу попадет информация только по одному (чаще всего случайному) сотруднику, и все остальные строки в отчете будут пустыми или неверными.

Вместо ВЫБРАТЬ ПЕРВЫЕ 1 следует использовать классическую схему получения «среза последних» вручную:


ВЫБРАТЬ
    Реестр.ФизическоеЛицо,
    МАКСИМУМ(Реестр.ДатаПриказа) КАК МаксДата
ПОМЕСТИТЬ ВТ_МаксимальныеДаты
ИЗ
    РегистрСведений.РеестрКадровыхПриказов КАК Реестр
ГДЕ
    Реестр.ДатаПриказа < &ДатаОтчета
ГРУППИРОВАТЬ ПО
    Реестр.ФизическоеЛицо;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВТ_Макс.ФизическоеЛицо,
    Реестр.Должность,
    Реестр.Подразделение
ИЗ
    ВТ_МаксимальныеДаты КАК ВТ_Макс
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.РеестрКадровыхПриказов КАК Реестр
    ПО ВТ_Макс.ФизическоеЛицо = Реестр.ФизическоеЛицо
    И ВТ_Макс.МаксДата = Реестр.ДатаПриказа

Причина №3: Механизм автозаполнения СКД

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

Попробуйте отключить «Автозаполнение» для запроса и вручную прописать все доступные поля и параметры на соответствующих вкладках СКД. Это даст вам полный контроль над итоговым текстом запроса.

Причина №4: Специфика регистра «РеестрКадровыхПриказов» в ЗУП 3.1

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

Проанализируем профессиональный подход к решению этой задачи. В ЗУП 3.1 реализован мощный механизм программного получения кадровых данных. Вместо написания сложных запросов к реестру приказов, рекомендуется использовать функции общего модуля КадровыйУчет.

Если вы разрабатываете отчет не через схему запроса, а программно формируете данные для СКД, лучше воспользоваться методом:


// Пример использования программного интерфейса ЗУП 3.1
ПараметрыПолученияДанных = КадровыйУчет.ПараметрыПолученияКадровыхДанныхСотрудников();
ПараметрыПолученияДанных.ДатаПолученияДанных = ДатаОтчета;
ПараметрыПолученияДанных.Поля = "Должность, Подразделение";

КадровыеДанные = КадровыйУчет.КадровыеДанныеСотрудников(Истина, СписокСотрудников, ПараметрыПолученияДанных);

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

Итоги и рекомендации

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

  1. Проверяйте роли полей. Если поле используется для связи или в логике условий, всегда ставьте ему роль «Обязательное».
  2. Избегайте «ВЫБРАТЬ ПЕРВЫЕ» во временных таблицах внутри СКД, если запрос не предполагает выборку ровно одной записи на весь отчет. Используйте вложенные запросы с группировкой по МАКСИМУМ(Дата).
  3. Изучите типовые механизмы. В таких конфигурациях, как ЗУП 3.1 или ERP, кадровые данные лучше получать через специализированные виртуальные таблицы или программные модули, так как они учитывают историю перемещений, совмещения и исправления документов.
  4. Используйте консоль СКД с возможностью просмотра итогового запроса. Существуют продвинутые консоли, которые позволяют увидеть не тот запрос, который вы написали, а тот, который сгенерировала СКД для СУБД. Это поможет мгновенно увидеть, какое поле «вылетело» из-за оптимизации.

Следуя этим рекомендациям, мы сможем создавать отказоустойчивые отчеты, которые выдают стабильный и предсказуемый результат в любых условиях эксплуатации.

← На главную