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