Разрезы в запросах к регистрам расчетов

При решении расчетных задач для подготовки к аттестации на специалиста по платформе 8.2 нередко приходится использовать разрезы при получении базы. Этот вопрос и постараюсь осветить.

В процессе подготовки к экзамену пришлось перелопатить немало книг, кучу ресурсов Интернета, но нигде не нашел внятного объяснения что такое «Разрезы» и с чем его едят. О примерах использования вообще умолчу…

Если бы мне в свое время попалась на глаза подобная статья, экзамен на специалиста был бы сдан намного раньше 🙂

Надеюсь, кому-то данная информация будет полезной.

Итак, рассмотрим два варианта задачи (сама задача максимально упрощена, условие приводится только для иллюстрации работы с разрезами).

Условие задачи:

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

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

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

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

Процент премии указывается пользователем в документе «Начисление зарплаты».

Решение

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

Вариант 1

Предположим, что на момент расчета премии у нас в регистре расчета существуют следующие записи (Иванов — руководитель подразделения): 

Номер строки Сотрудник Подразделение Вид расчета Результат База Процент
1 Иванов Отдел продаж Надбавка 200.00 1000.00 20
2 Петров Отдел продаж Надбавка 150.00 1000.00 15
3 Сидоров Отдел продаж  Надбавка 100.00 1000.00 10
4 Иванов Отдел продаж Премия     20

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

    Запрос = Новый Запрос;
   
Запрос.Текст =
       
«ВЫБРАТЬ
        |   ДополнительныеНачисления.НомерСтроки,
        |   ДополнительныеНачисленияБазаДополнительныеНачисления.СотрудникРазрез,
        |   ВЫБОР
        |       КОГДА ДополнительныеНачисленияБазаДополнительныеНачисления.Сотрудник = ДополнительныеНачисленияБазаДополнительныеНачисления.СотрудникРазрез
        |           ТОГДА 0
        |       ИНАЧЕ ЕСТЬNULL(ДополнительныеНачисленияБазаДополнительныеНачисления.РезультатБаза, 0)
        |   КОНЕЦ КАК База,
        |   ДополнительныеНачисления.Процент
        |ПОМЕСТИТЬ ВТРазрез
        |ИЗ
        |   РегистрРасчета.ДополнительныеНачисления КАК ДополнительныеНачисления
        |       ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисления.БазаДополнительныеНачисления(
        |               &Измерения,
        |               &Измерения,
        |               &Разрезы,
        |               Регистратор = &Регистратор
        |                   И ВидРасчета = &ВидРасчета) КАК ДополнительныеНачисленияБазаДополнительныеНачисления
        |       ПО ДополнительныеНачисления.НомерСтроки = ДополнительныеНачисленияБазаДополнительныеНачисления.НомерСтроки
        |ГДЕ
        |   ДополнительныеНачисления.Регистратор = &Регистратор
        |   И ДополнительныеНачисления.ВидРасчета = &ВидРасчета
        |   И ДополнительныеНачисления.Сотрудник.ЭтоРуководитель = ИСТИНА
        |;
        |
        |////////////////////////////////////////////////////////////////////////////////
        |ВЫБРАТЬ
        |   ВТРазрез.НомерСтроки,
        |   СУММА(ВТРазрез.База) КАК База,
        |   СУММА(ВТРазрез.База * ВТРазрез.Процент / 100) КАК Результат
        |ИЗ
        |   ВТРазрез КАК ВТРазрез
        |
        |СГРУППИРОВАТЬ ПО
        |   ВТРазрез.НомерСтроки»
;

    Измерения = Новый Массив(1);
   
Измерения[0] = «Подразделение»;

    Разрезы = Новый Массив(1);
   
Разрезы[0] = «Сотрудник»;

    Запрос.УстановитьПараметр(«Регистратор» ,Регистратор);
   
Запрос.УстановитьПараметр(«ВидРасчета»  ,ПланыВидовРасчета.ДополнительныеНачисления.Премия);
   
Запрос.УстановитьПараметр(«Измерения»   ,Измерения);
   
Запрос.УстановитьПараметр(«Разрезы»     ,Разрезы);

    Выборка = Запрос.Выполнить().Выбрать();
    Для Каждого
Запись Из НаборДвижений Цикл

        Отбор.НомерСтроки = Запись.НомерСтроки;
       
Выборка.Сбросить();
        Если
Выборка.НайтиСледующий(Отбор) Тогда

            Запись.База         = Выборка.База;
           
Запись.Результат    = Выборка.Результат;

        КонецЕсли;

    КонецЦикла;

Взглянем на временную таблицу «ВТРазрез»:

НомерСтроки СотрудникРазрез База Процент
4 Иванов 0.00 20
4 Петров 150.00 20
4 Сидоров 100.00 20

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

НомерСтроки База Процент
4 250.00 20

Вычислить результат, я думаю, теперь не составит труда.

 

Вариант 2

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

Пусть в регистре расчета на момент расчета премии существуют такие записи:

Номер строки Сотрудник Подразделение Вид расчета Результат База Процент
1 Иванов Отдел продаж Надбавка 100.00 1000.00 10
2 Петров Отдел продаж Надбавка 150.00 1000.00 15
3 Сидоров Отдел продаж Надбавка 200.00 1000.00 20
4 Иванов Отдел продаж Премия     20

Исходя из условия задачи, видим, что базой для расчета премии Иванова в данном случае должна стать сумма 200.00 — надбавка Сидорова.

Запрос тогда примет следующий вид: 

    Запрос = Новый Запрос;
   
Запрос.Текст =
       
«ВЫБРАТЬ
        |   ДополнительныеНачисления.НомерСтроки,
        |   ДополнительныеНачисленияБазаДополнительныеНачисления.СотрудникРазрез,
        |   ЕСТЬNULL(ДополнительныеНачисленияБазаДополнительныеНачисления.РезультатБаза, 0) КАК База,
        |   ДополнительныеНачисления.Процент
        |ПОМЕСТИТЬ ВТРазрез
        |ИЗ
        |   РегистрРасчета.ДополнительныеНачисления КАК ДополнительныеНачисления
        |       ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисления.БазаДополнительныеНачисления(
        |               &Измерения,
        |               &Измерения,
        |               &Разрезы,
        |               Регистратор = &Регистратор
        |                   И ВидРасчета = &ВидРасчета) КАК ДополнительныеНачисленияБазаДополнительныеНачисления
        |       ПО ДополнительныеНачисления.НомерСтроки = ДополнительныеНачисленияБазаДополнительныеНачисления.НомерСтроки
        |ГДЕ
        |   ДополнительныеНачисления.Регистратор = &Регистратор
        |   И ДополнительныеНачисления.ВидРасчета = &ВидРасчета
        |   И ДополнительныеНачисления.Сотрудник.ЭтоРуководитель = ИСТИНА
        |;
        |
        |////////////////////////////////////////////////////////////////////////////////
        |ВЫБРАТЬ
        |   ВТРазрез.НомерСтроки,
        |   МАКСИМУМ(ВТРазрез.База) КАК База,
        |   ВТРазрез.Процент
        |ПОМЕСТИТЬ ВТБаза
        |ИЗ
        |   ВТРазрез КАК ВТРазрез
        |
        |СГРУППИРОВАТЬ ПО
        |   ВТРазрез.НомерСтроки,
        |   ВТРазрез.Процент
        |;
        |
        |////////////////////////////////////////////////////////////////////////////////
        |ВЫБРАТЬ
        |   ВТБаза.НомерСтроки,
        |   ВТБаза.База,
        |   ВТБаза.База * ВТБаза.Процент / 100 КАК Результат
        |ИЗ
        |   ВТБаза КАК ВТБаза»
;

    Измерения = Новый Массив(1);
   
Измерения[0] = «Подразделение»;

    Разрезы = Новый Массив(1);
   
Разрезы[0] = «Сотрудник»;

    Запрос.УстановитьПараметр(«Регистратор» ,Регистратор);
   
Запрос.УстановитьПараметр(«ВидРасчета»  ,ПланыВидовРасчета.ДополнительныеНачисления.Премия);
   
Запрос.УстановитьПараметр(«Измерения»   ,Измерения);
   
Запрос.УстановитьПараметр(«Разрезы»     ,Разрезы);

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

Временная таблица «ВТРазрез» практически ничем не отличается от аналогичной в первом варианте:

НомерСтроки СотрудникРазрез База Процент
4 Иванов 100.00 20
4 Петров 150.00 20
4 Сидоров 200.00 20

Во временную таблицу «ВТБаза» мы помещаем только одну подходящую нам запись: по товарищу Сидорову, так как ему начислена максимальная надбавка:

НомерСтроки База Процент
4 200.00 20

Ну и осталось рассчитать результат, что теперь не составляет никаких трудностей.

 

Резюме.

Использование разрезов не так уж и сложно, если разобраться (как впрочем и все этом мире :).

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

6 Comments

  1. fr.myha

    Спасибо большое за статью. Теперь будет более понятно что это такое разрез и как им пользоваться.

    Reply
  2. Kryakovkin

    Спасибо за публикацию. Статья очень помогла в подготовке к специалисту. Из задач которые я прорешивал, разрезы потребовались в задаче 3.49.

    Reply
  3. BorisSpB

    Здравствуйте.

    Спасибо за подробную статью. У вас все написано понятно и по существу.

    Возник следующий вопрос. Зачем в варианте 2 (расчет премии руководителю исходя из максимальной надбавки сотрудника) вы берете данные из реальной таблицы «Дополнительные начисления»?

    Почему бы номер строки и процент не брать из вирт. таблицы «ДополнительныеНачисленияБазаДополнительныеНачисления»? В таком случае не было бы необходимости делать лишнее ЛЕВОЕ СОЕДИНЕНИЕ.

    Reply
  4. CeHbKA

    Статья отличная! Но я так и не могу допетрить, как из условия задачи понять, что нужны разрезы?

    И если у меня в регистре расчета 2 измерения — сотрудник и подразделение, разве я не получу один и тот же результат, что при получении базы и указании параметра «Измерения», что при получении базы и указания параметра «Разрезы» ?!

    Reply
  5. shoy

    Хорошо написано!

    Про левое соединение правильное замечание.

    А ещё, нужен разрез по должности сотрудника, особенно когда в один месяц перекидывают больше двух раз.

    Reply
  6. KonstIV

    А зачем подтягивать основную таблицу? Номер строки и в доп. таблице такой же.

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

    Показать

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *