В процессе подготовки к экзамену пришлось перелопатить немало книг, кучу ресурсов Интернета, но нигде не нашел внятного объяснения что такое "Разрезы" и с чем его едят. О примерах использования вообще умолчу...
Если бы мне в свое время попалась на глаза подобная статья, экзамен на специалиста был бы сдан намного раньше :)
Надеюсь, кому-то данная информация будет полезной.
Итак, рассмотрим два варианта задачи (сама задача максимально упрощена, условие приводится только для иллюстрации работы с разрезами).
Условие задачи:
Сотрудники получают надбавку, которая рассчитывается как некая сумма умноженная на процент. Сумма и процент для расчета надбавки указываются пользователем в документе "Начисление зарплаты".
Дополнительно руководителям подразделений выплачивается премия, которая рассчитывается как:
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 |
Ну и осталось рассчитать результат, что теперь не составляет никаких трудностей.
Резюме.
Использование разрезов не так уж и сложно, если разобраться (как впрочем и все этом мире :).
Прилагаю выгрузку информационной базы, содержащую описанный здесь пример. В выгрузке выбор варианта получения базы реализован переключателем в документе "Начисление зарплаты".