Почему не совпадают результаты запроса в СКД и консоли запросов при работе с кадровой историей?

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

При разработке отчетов в системе 1С:Зарплата и управление персоналом 3.1 программисты часто сталкиваются с ситуацией, когда один и тот же запрос выдает разное количество записей в консоли запросов и при выполнении в теле схемы компоновки данных (СКД) или программно. Рассмотрим ситуацию на примере работы с виртуальной таблицей КадроваяИсторияСотрудников.СрезПоследних. Проанализируем основные причины возникновения таких расхождений и разберем способы их устранения.

Анализ исходного запроса

Рассмотрим типовой запрос, который часто используется для получения актуального списка сотрудников на определенную дату:


ВЫБРАТЬ РАЗРЕШЕННЫЕ РАЗЛИЧНЫЕ
    КадроваяИсторияСотрудниковСрезПоследних.Сотрудник КАК Сотрудник
ИЗ
    РегистрСведений.КадроваяИсторияСотрудников.СрезПоследних(&НаДату, ) КАК КадроваяИсторияСотрудниковСрезПоследних
ГДЕ
    КадроваяИсторияСотрудниковСрезПоследних.ВидСобытия <> ЗНАЧЕНИЕ(Перечисление.ВидыКадровыхСобытий.Увольнение)
    И КадроваяИсторияСотрудниковСрезПоследних.Подразделение В ИЕРАРХИИ(&Подразделение)

На первый взгляд запрос кажется корректным, однако при его выполнении может возникнуть разница (например, 5 записей в коде против 8 в консоли). Разберем пошагово, почему это происходит.

Причина 1: Подмена параметров системой компоновки данных

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

Важный момент: если тип параметра &НаДату — просто «Дата» (без указания времени), то запрос может брать начало дня, в то время как кадровые документы могли быть проведены в течение этого дня. В консоли запросов мы часто задаем дату вручную, и она может интерпретироваться как «конец дня» или «граница», что и дает разницу в результатах.

Рассмотрим, как правильно передавать параметры в виртуальную таблицу. Рекомендуется использовать встроенные механизмы СКД и всегда проверять, какое именно значение попадает в параметр &Период в момент исполнения запроса в отладчике.

Причина 2: Использование конструкции «В ИЕРАРХИИ»

Проанализируем ситуацию с иерархией подразделений, которая стала ключевой в данном случае. В 1С условие В ИЕРАРХИИ работает по-разному в зависимости от того, где оно расположено: в параметрах виртуальной таблицы или в секции ГДЕ.

  1. В секции ГДЕ: Система сначала выбирает все последние записи из регистра по всем сотрудникам на указанную дату, а затем из этого огромного массива «отсеивает» тех, кто не входит в иерархию подразделения.
  2. В параметрах виртуальной таблицы: Система на уровне базы данных сразу ограничивает выборку нужным подразделением и его дочерними элементами.

Посмотрим на пример правильного написания запроса для оптимизации и точности:


ВЫБРАТЬ РАЗРЕШЕННЫЕ
    Срез.Сотрудник
ИЗ
    РегистрСведений.КадроваяИсторияСотрудников.СрезПоследних(&Период, Подразделение В ИЕРАРХИИ(&Подразделение)) КАК Срез
ГДЕ
    Срез.ВидСобытия <> ЗНАЧЕНИЕ(Перечисление.ВидыКадровыхСобытий.Увольнение)

Почему же консоль может «обходить» проблемы иерархии, которые проявляются в коде? Это часто связано с временными таблицами. При выполнении запроса В ИЕРАРХИИ платформа 1С создает временную таблицу со всеми идентификаторами узлов иерархии. Если в справочнике «Подразделения» есть битые ссылки, зацикливания или помеченные на удаление родительские элементы, состав этой временной таблицы в разных контекстах выполнения может отличаться.

Причина 3: Ограничение прав доступа (RLS)

Разберем влияние слова РАЗРЕШЕННЫЕ. В ЗУП КОРП активно используются механизмы ограничения доступа на уровне записей (RLS). Если вы запускаете консоль запросов под пользователем с полными правами, а отчет — под кадровиком, результат обязательно будет разным. Система безопасности просто не отдаст те записи, по подразделениям которых у пользователя нет прав просмотра.

Для проверки этой гипотезы всегда стоит запустить консоль запросов именно под тем пользователем, у которого возникла проблема в отчете.

Методика поиска расхождений: пошаговый алгоритм

Если вы столкнулись с несовпадением данных, выполните следующие действия:

  1. Сравните итоговые тексты запросов. В СКД запрос, который вы написали, — это лишь «заготовка». Перед исполнением система модифицирует его. Чтобы увидеть реальный текст, используйте отладчик и получите свойство Запрос из макета компоновки данных.
  2. Проверьте типы параметров. Убедитесь, что в обоих случаях &Подразделение — это ссылка на справочник, а не массив или строка. Проверьте, что дата в обоих случаях совпадает до секунды.
  3. Вынесите условия в параметры виртуальной таблицы. Это исключит влияние «промежуточных» срезов и повысит производительность.
  4. Проанализируйте иерархию. Убедитесь, что выбранное подразделение само не является помеченным на удаление и что его «родители» в справочнике корректны. Проблема часто кроется в том, что консоль может использовать упрощенный механизм построения дерева иерархии, если она запущена в привилегированном режиме.

Особенности регистра «Кадровая история сотрудников»

Выясним специфику самого регистра в ЗУП 3.1. Он является периодическим и может содержать несколько записей по одному сотруднику на одну и ту же дату (например, если в один день были оформлены перевод и изменение графика).

При использовании СрезПоследних без уточнения момента времени, 1С может вернуть запись, которая была внесена в базу последней по времени регистрации, а не по логическому порядку документов. Консоль запросов иногда иначе обрабатывает «Момент времени», чем программный вызов Запрос.Выполнить(), особенно если используется внешний источник данных (ТЗ).

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

Заключение

Мы выяснили, что основные причины расхождений кроются в обработке иерархии подразделений и автоматической замене параметров системой СКД. Чтобы результаты всегда были идентичны, придерживайтесь правила: максимально переносить фильтры (Подразделение, Организация) непосредственно в параметры виртуальных таблиц и всегда проверять работу отчета под правами конечного пользователя.

← На главную