Зачем нужны разрезы в виртуальных таблицах регистров расчета 1С и как с ними работать

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

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

В этой статье мы подробно разберем, что такое разрезы в регистрах расчета, для чего они используются, как правильно с ними работать и почему возникает популярная ошибка Поле не найдено '...Разрез' при тестировании запроса в консоли.

Назначение и принцип работы разрезов

Рассмотрим устройство механизма расчета базы. В 1С при обращении к виртуальной таблице База участвуют два понятия:

  1. Основной регистр — регистр, для записей которого мы производим расчет прямо сейчас.
  2. Базовый регистр — регистр, из записей которого мы извлекаем суммы и другие показатели для расчета базы (часто основной и базовый регистры совпадают).

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

Параметр Разрезы (3-й параметр виртуальной таблицы База) позволяет принудительно изменить уровень детализации и развернуть итоговые показатели по определенным полям базового регистра.

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

Структура параметров виртуальной таблицы База

Посмотрим на порядок передачи параметров в виртуальную таблицу базовых данных:


РегистрРасчета.Начисления.БазаОсновныеНачисления(
    &ИзмеренияОсновногоРегистра,
    &ИзмеренияБазовогоРегистра,
    &Разрезы,
    Регистратор = &СсылкаИДокумента
)

Разберем назначение каждого из них:

  1. Измерения основного регистра — список измерений, по которым выбираются записи текущего регистра.
  2. Измерения базового регистра — список измерений базового регистра, по которым происходит сопоставление (соединение) 1 к 1 с измерениями основного регистра.
  3. Разрезы — массив полей базового регистра, по которым требуется дополнительно сгруппировать получившийся результат.
  4. Условие — фильтр для отбора записей основного или базового регистра.

В результате передачи полей в параметр разрезов платформой динамически формируются виртуальные поля с суффиксом Разрез (например, СотрудникРазрез, ПодразделениеРазрез).

Почему возникает ошибка «Поле не найдено '...Разрез'» в Консоли запросов

Выясним причину распространенной ошибки, с которой сталкиваются программисты при отладке запросов в Консоли запросов.

Поля с суффиксом Разрез не существуют в постоянной метаструктуре базы данных. Они создаются платформой 1С на лету исключительно в момент выполнения запроса на основе состава массива, переданного в 3-й параметр. Если в параметрах виртуальной таблицы указана переменная (например, &Разрез), Конструктор запросов и обработка «Консоль запросов» на этапе синтаксической проверки не могут определить, какие именно поля появятся в результате. Из-за этого платформа выбивает ошибку о ненайденном поле СотрудникРазрез.

Чтобы протестировать запрос с разрезами в Консоли запросов без ошибок, наименования разрезов следует передать непосредственно в тексте запроса строковым литералом или жестко зафиксировать структуру параметров перед выполнением.

Практический пример использования разрезов

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

Для получения базовых сумм всех сотрудников подразделения с возможностью исключения самого руководителя в коде запроса можно применить массив разрезов:


Разрез = Новый Массив;
Разрез.Добавить("Сотрудник");

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

В данном запросе поле ДНБаза.Сотрудник содержит сотрудника из текущей записи расчета (руководителя), а поле ДНБаза.СотрудникРазрез — сотрудников, чьи начисления попали в базовый период. Условие в секции ГДЕ отсекает строки, где сотрудник базового регистра совпадает с руководителем.

Ограничения и влияние на производительность

Важно учитывать особенности работы СУБД при использовании механизма разрезов:

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

Оптимальные альтернативные решения

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

Вариант 1. Использование 4-го параметра (Условие)
Вместо разворачивания всей базы по сотрудникам с последующей фильтрацией через секцию ГДЕ, лучше заранее собрать массив или временную таблицу разрешенных сотрудников подчиненных и передать условие непосредственно в 4-й параметр виртуальной таблицы:


РегистрРасчета.ДополнительныеНачисления.БазаОсновныеНачисления(
    &Измерения,
    &Измерения,
    ,
    Регистратор = &Ссылка 
        И Сотрудник В (&МассивПодчиненных)
)

При таком подходе СУБД выполнит фильтрацию еще на этапе выборки и вернет уже свернутый готовый результат без лишних накладных расходов.

Вариант 2. Раздельный расчет и прямое обращение к регистру
Правильная архитектура расчетов подразумевает грамотную последовательность вычислений. Если сначала рассчитать и записать в регистр результаты подчиненных сотрудников, то при расчете премии руководителя можно обратиться к таблице базового регистра или физической таблице с прямым фильтром по подразделению и условием Сотрудник <> &Руководитель.

← На главную