В процессе подготовки к экзамену пришлось перелопатить немало книг, кучу ресурсов Интернета, но нигде не нашел внятного объяснения что такое «Разрезы» и с чем его едят. О примерах использования вообще умолчу…
Если бы мне в свое время попалась на глаза подобная статья, экзамен на специалиста был бы сдан намного раньше 🙂
Надеюсь, кому-то данная информация будет полезной.
Итак, рассмотрим два варианта задачи (сама задача максимально упрощена, условие приводится только для иллюстрации работы с разрезами).
Условие задачи:
Сотрудники получают надбавку, которая рассчитывается как некая сумма умноженная на процент. Сумма и процент для расчета надбавки указываются пользователем в документе «Начисление зарплаты».
Дополнительно руководителям подразделений выплачивается премия, которая рассчитывается как:
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 |
Ну и осталось рассчитать результат, что теперь не составляет никаких трудностей.
Резюме.
Использование разрезов не так уж и сложно, если разобраться (как впрочем и все этом мире :).
Прилагаю выгрузку информационной базы, содержащую описанный здесь пример. В выгрузке выбор варианта получения базы реализован переключателем в документе «Начисление зарплаты».
Спасибо большое за статью. Теперь будет более понятно что это такое разрез и как им пользоваться.
Спасибо за публикацию. Статья очень помогла в подготовке к специалисту. Из задач которые я прорешивал, разрезы потребовались в задаче 3.49.
Здравствуйте.
Спасибо за подробную статью. У вас все написано понятно и по существу.
Возник следующий вопрос. Зачем в варианте 2 (расчет премии руководителю исходя из максимальной надбавки сотрудника) вы берете данные из реальной таблицы «Дополнительные начисления»?
Почему бы номер строки и процент не брать из вирт. таблицы «ДополнительныеНачисленияБазаДополнительныеНачисления»? В таком случае не было бы необходимости делать лишнее ЛЕВОЕ СОЕДИНЕНИЕ.
Статья отличная! Но я так и не могу допетрить, как из условия задачи понять, что нужны разрезы?
И если у меня в регистре расчета 2 измерения — сотрудник и подразделение, разве я не получу один и тот же результат, что при получении базы и указании параметра «Измерения», что при получении базы и указания параметра «Разрезы» ?!
Хорошо написано!
Про левое соединение правильное замечание.
А ещё, нужен разрез по должности сотрудника, особенно когда в один месяц перекидывают больше двух раз.
А зачем подтягивать основную таблицу? Номер строки и в доп. таблице такой же.
Показать