Базовый курс. Занятие №15
Последнее занятие 4-го блока.
Необходимо изучить следующие главы.
Глава 13. Разработка отчетов.
Глава 14. Универсальные алгоритмы.
Глава 15. Сторнирование записей регистров расчета.
Также нужно выполнить домашнее задание, текст которого доступен на странице.
Задание необходимо выполнять в ИБ после предыдущего ДЗ.
В этой же теме необходимо написать отчет о выполнении задания.
ps. Участники курса без доступа в мастер-группу отчитываться по домашним заданиям не могут.
— залогиньтесь.
Если не активировали токен — посмотрите видео-инструкцию (видео N5)
Если вы залогинены, у Вас активирован токен доступа, но вы все равно видите эту запись —напишите нам на e-mail поддержки.
1.Программировать не надо. Можно настроить.
2. Новый ПВР зависимость по регистрации. Новый Регистр расчета.
расчитываю так же в отдельной проц.
3. Новое перечисление ПоДням
4. Новое перечисление Надбавка.
//{{КОНСТРУКТОР_ЗАПРОСА_С_ОБРАБОТКОЙ_РЕЗУЛЬТАТА
// Данный фрагмент построен конструктором.
// При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| ОсновныеНачисления.ВидРасчета.КатегорияРасчета КАК Категория,
| ОсновныеНачисления.ВидРасчета.СпособРасчета КАК Способ
|ИЗ
| РегистрРасчета.ОсновныеНачисления КАК ОсновныеНачисления
|ГДЕ
| ОсновныеНачисления.Регистратор = &Ссылка
|
|УПОРЯДОЧИТЬ ПО
| Категория
|ИТОГИ ПО
| Категория";
Запрос.УстановитьПараметр("Ссылка", Ссылка);
Запрос.Текст = СтрЗаменить(Запрос.Текст,"ОсновныеНачисления",ИмяРегистра);
Результат = Запрос.Выполнить();
ВыборкаКатегория = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока ВыборкаКатегория.Следующий() Цикл
// Вставить обработку выборки ВыборкаКатегория
ВыборкаДетальныеЗаписи = ВыборкаКатегория.Выбрать();
СпособыРасчета = Новый Массив;
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
// Вставить обработку выборки ВыборкаДетальныеЗаписи
СпособыРасчета.Добавить(ВыборкаДетальныеЗаписи.Способ);
Выполнить("Рассчитать"+ИмяРегистра+"(ВыборкаДетальныеЗаписи.Категория, СпособыРасчета, Отказ)");
КонецЦикла;
КонецЦикла;
//}}КОНСТРУКТОР_ЗАПРОСА_С_ОБРАБОТКОЙ_РЕЗУЛЬТАТА
КонецПроцедуры
Процедура РассчитатьОсновныеНачисления(Категория, СпособыРасчета, Отказ)
База=Ложь;
График = Ложь;
Надбавка = Ложь;
Для каждого Способ Из СпособыРасчета Цикл
Если Способ = Перечисления.СпособыРасчета.ПоВремени ИЛИ Способ = Перечисления.СпособыРасчета.ПоДням Тогда
График = Истина;
ИначеЕсли Способ = Перечисления.СпособыРасчета.ПоСреднему ИЛИ Способ = Перечисления.СпособыРасчета.Процентом Тогда
База = Истина
КонецЕсли;
КонецЦикла;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ОсновныеНачисления.НомерСтроки,
| ОсновныеНачисления.Размер";
Если График Тогда
Запрос.Текст = Запрос.Текст +"
| ,ЕСТЬNULL(ОсновныеНачисленияДанныеГрафика.ЗначениеФактическийПериодДействия, 0) КАК ФактДней,
| ЕСТЬNULL(ОсновныеНачисленияДанныеГрафика.ЗначениеБазовыйПериод, 0) КАК БазаДней,
| ЕСТЬNULL(ОсновныеНачисленияДанныеГрафика.ЗначениеПериодДействия, 0) КАК ПланДней";
КонецЕсли;
Если База Тогда
Запрос.Текст = Запрос.Текст +"
| ,ЕСТЬNULL(ОсновныеНачисленияБазаДополнительныеНачисления.РезультатБаза, 0) + ЕСТЬNULL(ОсновныеНачисленияБазаОсновныеНачисления.РезультатБаза, 0) КАК База";
КонецЕсли;
Запрос.Текст = Запрос.Текст +"
|ИЗ
| РегистрРасчета.ОсновныеНачисления КАК ОсновныеНачисления";
Если База Тогда
Запрос.Текст = Запрос.Текст +"
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ОсновныеНачисления.БазаОсновныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &Категория) КАК ОсновныеНачисленияБазаОсновныеНачисления
| ПО ОсновныеНачисления.НомерСтроки = ОсновныеНачисленияБазаОсновныеНачисления.НомерСтроки
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ОсновныеНачисления.БазаДополнительныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &Категория) КАК ОсновныеНачисленияБазаДополнительныеНачисления
| ПО ОсновныеНачисления.НомерСтроки = ОсновныеНачисленияБазаДополнительныеНачисления.НомерСтроки";
КонецЕсли;
Если График Тогда
Запрос.Текст = Запрос.Текст +"
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ОсновныеНачисления.ДанныеГрафика(
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &Категория) КАК ОсновныеНачисленияДанныеГрафика
| ПО ОсновныеНачисления.НомерСтроки = ОсновныеНачисленияДанныеГрафика.НомерСтроки";
КонецЕсли;
Запрос.Текст = Запрос.Текст +"
|ГДЕ
| ОсновныеНачисления.Регистратор = &Ссылка
| И ОсновныеНачисления.ВидРасчета.КатегорияРасчета = &Категория";
Измерения = Новый Массив;
Измерения.Добавить("Сотрудник");
Измерения.Добавить("Подразделение");
Запрос.УстановитьПараметр("Движения", Измерения);
Запрос.УстановитьПараметр("Ссылка", Ссылка);
Запрос.УстановитьПараметр("Категория", Категория);
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
НомерСтроки = Новый Структура("НомерСтроки");
Для каждого Запись Из Движения.ОсновныеНачисления Цикл
НомерСтроки.НомерСтроки = Запись.НомерСтроки;
Выборка.Сбросить();
Если НЕ Выборка.НайтиСледующий(НомерСтроки) Тогда
Продолжить;
КонецЕсли;
СпособРасчета = Запись.ВидРасчета.СпособРасчета;
Если СпособРасчета = Перечисления.СпособыРасчета.ПоВремени Тогда
Если Выборка.ПланДней=0 Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Не заполнен график - "+Запись.ТипГрафика;
Сообщение.Сообщить();
Отказ = Истина;
Продолжить;
Иначе
Результат = Запись.Размер*Выборка.ФактДней/Выборка.ПланДней;
КонецЕсли;
ИначеЕсли СпособРасчета = Перечисления.СпособыРасчета.ПоДням Тогда
Результат = Выборка.ФактДней * Запись.Размер;
ИначеЕсли СпособРасчета = Перечисления.СпособыРасчета.ПоСреднему Тогда
Если Выборка.БазаДней=0 Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Не заполнен график - "+Запись.ТипГрафика;
Сообщение.Сообщить();
Отказ = Истина;
Продолжить;
Иначе
Результат = Выборка.ФактДней * Выборка.База/Выборка.БазаДней;
КонецЕсли;
ИначеЕсли СпособРасчета = Перечисления.СпособыРасчета.БезОплаты Тогда
Результат = 0;
Иначе
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Алгоритм для вида расчета "+СпособРасчета+" не определен";
Сообщение.Сообщить();
Отказ = Истина;
Продолжить;
КонецЕсли;
Запись.Результат = Результат * ?(Запись.Сторно, -1, 1);
КонецЦикла;
Движения.ОсновныеНачисления.Записать(,Истина);
КонецПроцедуры
Процедура РассчитатьДополнительныеНачисления(Категория, СпособыРасчета, Отказ)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ЕСТЬNULL(ДополнительныеНачисленияБазаДополнительныеНачисления.НомерСтроки, ДополнительныеНачисленияБазаОсновныеНачисления.НомерСтроки) КАК НомерСтроки,
| ЕСТЬNULL(ДополнительныеНачисленияБазаОсновныеНачисления.РезультатБаза, 0) + ЕСТЬNULL(ДополнительныеНачисленияБазаДополнительныеНачисления.РезультатБаза, 0) КАК База
|ИЗ
| РегистрРасчета.ДополнительныеНачисления.БазаДополнительныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &Категория) КАК ДополнительныеНачисленияБазаДополнительныеНачисления
| ПОЛНОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисления.БазаОсновныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &Категория) КАК ДополнительныеНачисленияБазаОсновныеНачисления
| ПО ДополнительныеНачисленияБазаДополнительныеНачисления.НомерСтроки = ДополнительныеНачисленияБазаОсновныеНачисления.НомерСтроки";
Измерения = Новый Массив;
Измерения.Добавить("Сотрудник");
Измерения.Добавить("Подразделение");
Запрос.УстановитьПараметр("Измерения", Измерения);
Запрос.УстановитьПараметр("Ссылка", Ссылка);
Запрос.УстановитьПараметр("Категория", Категория);
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Выборка = Результат.Выбрать();
НомерСтроки = Новый Структура("НомерСтроки");
Для каждого Запись Из Движения.ДополнительныеНачисления Цикл
НомерСтроки.НомерСтроки = Запись.НомерСтроки;
Выборка.Сбросить();
Если НЕ Выборка.НайтиСледующий(НомерСтроки) Тогда
Продолжить;
КонецЕсли;
СпособРасчета = Запись.ВидРасчета.СпособРасчета;
Если СпособРасчета = Перечисления.СпособыРасчета.Процентом Тогда
Результат = Выборка.База*Запись.Размер/100;
Иначе
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Алгоритм для вида расчета "+СпособРасчета+" не определен";
Сообщение.Сообщить();
Отказ = Истина;
КонецЕсли;
Запись.Результат = Результат * ?(Запись.Сторно, -1, 1);
КонецЦикла;
Движения.ДополнительныеНачисления.Записать(,Истина);
КонецПроцедуры
Процедура РассчитатьДополнительныеНачисленияПоРегистрации(Категория, СпособыРасчета, Отказ)
Надбавка = Ложь;
Для каждого Способ Из СпособыРасчета Цикл
Если Способ = Перечисления.СпособыРасчета.Надбавка Тогда
Надбавка = Истина;
КонецЕсли;
КонецЦикла;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ДополнительныеНачисленияПоРегистрации.НомерСтроки КАК НомерСтроки,
| ЕСТЬNULL(ДополнительныеНачисленияПоРегистрацииБазаОсновныеНачисления.РезультатБаза, 0) + ЕСТЬNULL(ДополнительныеНачисленияПоРегистрацииБазаДополнительныеНачисления.РезультатБаза, 0) КАК База,
| ДополнительныеНачисленияПоРегистрацииБазаДополнительныеНачисленияПоРегистрации.РезультатБаза КАК База1
|ИЗ
| РегистрРасчета.ДополнительныеНачисленияПоРегистрации КАК ДополнительныеНачисленияПоРегистрации
| ПОЛНОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисленияПоРегистрации.БазаОсновныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &Категория) КАК ДополнительныеНачисленияПоРегистрацииБазаОсновныеНачисления
| ПО ДополнительныеНачисленияПоРегистрации.НомерСтроки = ДополнительныеНачисленияПоРегистрацииБазаОсновныеНачисления.НомерСтроки
| ПОЛНОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисленияПоРегистрации.БазаДополнительныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &Категория) КАК ДополнительныеНачисленияПоРегистрацииБазаДополнительныеНачисления
| ПО ДополнительныеНачисленияПоРегистрации.НомерСтроки = ДополнительныеНачисленияПоРегистрацииБазаДополнительныеНачисления.НомерСтроки
| ПОЛНОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисленияПоРегистрации.БазаДополнительныеНачисленияПоРегистрации(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &Категория) КАК ДополнительныеНачисленияПоРегистрацииБазаДополнительныеНачисленияПоРегистрации
| ПО ДополнительныеНачисленияПоРегистрации.НомерСтроки = ДополнительныеНачисленияПоРегистрацииБазаДополнительныеНачисленияПоРегистрации.НомерСтроки
|ГДЕ
| ДополнительныеНачисленияПоРегистрации.Регистратор = &Ссылка
| И ДополнительныеНачисленияПоРегистрации.ВидРасчета.КатегорияРасчета = &Категория";
Измерения = Новый Массив;
Измерения.Добавить("Подразделение");
Если Не Надбавка Тогда
Измерения.Добавить("Сотрудник");
КонецЕсли;
Запрос.УстановитьПараметр("Измерения", Измерения);
Запрос.УстановитьПараметр("Ссылка", Ссылка);
Запрос.УстановитьПараметр("Категория", Категория);
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Выборка = Результат.Выбрать();
НомерСтроки = Новый Структура("НомерСтроки");
Для каждого Запись Из Движения.ДополнительныеНачисленияПоРегистрации Цикл
НомерСтроки.НомерСтроки = Запись.НомерСтроки;
Выборка.Сбросить();
Если НЕ Выборка.НайтиСледующий(НомерСтроки) Тогда
Продолжить;
КонецЕсли;
СпособРасчета = Запись.ВидРасчета.СпособРасчета;
Если СпособРасчета = Перечисления.СпособыРасчета.Процентом Тогда
Результат = Выборка.База*Запись.Размер/100;
ИначеЕсли СпособРасчета = Перечисления.СпособыРасчета.Надбавка Тогда
Результат = Выборка.База1*Запись.Размер/100;
Иначе
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Алгоритм для способа расчета "+СпособРасчета+" не определен";
Сообщение.Сообщить();
Отказ = Истина;
КонецЕсли;
Запись.Результат = Результат * ?(Запись.Сторно, -1, 1);
КонецЦикла;
Движения.ДополнительныеНачисленияПоРегистрации.Записать(,Истина);
КонецПроцедуры
Наверное можно было обойтись 2-мя пройедурами (РасчитатьОснНачисления и РасчитатьДопНачисления), но мало времени.
Отчет – СКД на запросе к РР ОсновныеНачисления. Таблица. Строки: Сотр, Подр, колонки: Период, Вид расчета
Arbat, отчет принят.
Очень поздно, но все же…
Выполнено. Повозился со второй частью задания. Долго мучился.
<code>
Процедура ОбработкаПроведения(Отказ, Режим)
Для Каждого ТекСтрокаНачисления Из Начисления Цикл
Если ТипЗнч(ТекСтрокаНачисления.ВидРасчета) = Тип(“ПланВидовРасчетаСсылка.ОсновныеНачисления”) Тогда
Движение = Движения.ОсновныеНачисления.Добавить();
Если ТекСтрокаНачисления.ВидРасчета = ПланыВидовРасчета.ОсновныеНачисления.Отпуск Тогда
Движение.ТипГрафика = Константы.Шестидневка.Получить();
Иначе
Движение.ТипГрафика = ТекСтрокаНачисления.ТипГрафика;
КонецЕсли;
Движение.ПериодДействияНачало = ТекСтрокаНачисления.ДатаНачала;
Движение.ПериодДействияКонец = ТекСтрокаНачисления.ДатаОкончания;
ИначеЕсли ТипЗнч(ТекСтрокаНачисления.ВидРасчета) = Тип(“ПланВидовРасчетаСсылка.ДополнительныеНачисления”) Тогда
Движение = Движения.ДополнительныеНачисления.Добавить();
ИначеЕсли ТипЗнч(ТекСтрокаНачисления.ВидРасчета) = Тип(“ПланВидовРасчетаСсылка.ДополнительныеНачисленияПериодРегистрации”) Тогда
Движение = Движения.ДополнительныеНачисленияПериодРегистрации.Добавить();
Иначе
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = “Алгоритм вида расчета “+ТекСтрокаНачисления.ВидРасчета+” не поддреживается”;
Сообщение.Сообщить();
Отказ = Истина;
Продолжить;
КонецЕсли;
Движение.ВидРасчета = ТекСтрокаНачисления.ВидРасчета;
Движение.ПериодРегистрации = ПериодРегистрации;
Движение.БазовыйПериодНачало = ТекСтрокаНачисления.БазовыйПериодНачало;
Движение.БазовыйПериодКонец = ТекСтрокаНачисления.БазовыйПериодКонец;
Движение.Сотрудник = ТекСтрокаНачисления.Сотрудник;
Движение.Подразделение = ТекСтрокаНачисления.Подразделение;
Движение.Размер = ТекСтрокаНачисления.Размер;
КонецЦикла;
Если НЕ Отказ Тогда
//Движения.Записать();
Движения.ОсновныеНачисления.Записать();
Движения.ДополнительныеНачисления.Записать();
Движения.ДополнительныеНачисленияПериодРегистрации.Записать();
РасчетНачислений(Отказ, “ОсновныеНачисления”);
РасчетНачислений(Отказ, “ДополнительныеНачисления”);
РасчетНачислений(Отказ, “ДополнительныеНачисленияПериодРегистрации”);
КонецЕсли;
КонецПроцедуры
Процедура РасчетНачислений(Отказ, ИмяРегистра)
//{{КОНСТРУКТОР_ЗАПРОСА_С_ОБРАБОТКОЙ_РЕЗУЛЬТАТА
// Данный фрагмент построен конструктором.
// При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!
Запрос = Новый Запрос;
Запрос.Текст =
“ВЫБРАТЬ
| ОсновныеНачисления.ВидРасчета.КатегорияРасчета КАК КатегорияРасчета,
| ОсновныеНачисления.ВидРасчета.СпособРасчета КАК СпособРасчета
|ИЗ
| РегистрРасчета.ОсновныеНачисления КАК ОсновныеНачисления
|ГДЕ
| ОсновныеНачисления.Регистратор = &Ссылка
|
|УПОРЯДОЧИТЬ ПО
| КатегорияРасчета
|ИТОГИ ПО
| КатегорияРасчета”;
Если ИмяРегистра<>”ОсновныеНачисления” Тогда
Запрос.Текст = СтрЗаменить(Запрос.Текст, “ОсновныеНачисления”, ИмяРегистра);
КонецЕсли;
Запрос.УстановитьПараметр(“Ссылка”, Ссылка);
Результат = Запрос.Выполнить();
ВыборкаВидРасчетаКатегорияРасчета = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока ВыборкаВидРасчетаКатегорияРасчета.Следующий() Цикл
// Вставить обработку выборки ВыборкаВидРасчетаКатегорияРасчета
ВыборкаДетальныеЗаписи = ВыборкаВидРасчетаКатегорияРасчета.Выбрать();
Способы = Новый Массив;
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
Способы.Добавить(ВыборкаДетальныеЗаписи.СпособРасчета);
КонецЦикла;
Если ИмяРегистра=”ОсновныеНачисления” Тогда
РасчетОсновныхНачислений(Отказ, ВыборкаВидРасчетаКатегорияРасчета.КатегорияРасчета, Способы);
ИначеЕсли ИмяРегистра=”ДополнительныеНачисления”
ИЛИ ИмяРегистра=”ДополнительныеНачисленияПериодРегистрации” Тогда
РасчетДополнительныхНачислений(Отказ, ВыборкаВидРасчетаКатегорияРасчета.КатегорияРасчета, Способы, ИмяРегистра);
КонецЕсли;
КонецЦикла;
//}}КОНСТРУКТОР_ЗАПРОСА_С_ОБРАБОТКОЙ_РЕЗУЛЬТАТА
КонецПроцедуры
Процедура РасчетОсновныхНачислений(Отказ, Категория=0, Способы)
НужнаБаза = Ложь;
НуженГрафик = Ложь;
Для Каждого Способ Из Способы Цикл
Если Способ = Перечисления.СпособыРасчета.ПоВремени Тогда
НуженГрафик = Истина;
ИначеЕсли Способ = Перечисления.СпособыРасчета.ПоСреднему Тогда
НужнаБаза = Истина;
НуженГрафик = Истина;
ИначеЕсли Способ = Перечисления.СпособыРасчета.ПоТарифу Тогда
НуженГрафик = Истина;
КонецЕсли;
КонецЦикла;
Запрос = Новый Запрос;
Запрос.Текст =
“ВЫБРАТЬ
| ОсновныеНачисления.НомерСтроки КАК НомерСтроки,
| ОсновныеНачисления.Размер КАК Размер”;
Если НуженГрафик Тогда
Запрос.Текст = Запрос.Текст + “,
| ЕСТЬNULL(ОсновныеНачисленияДанныеГрафика.ЗначениеФактическийПериодДействия, 0) КАК ФактДней,
| ЕСТЬNULL(ОсновныеНачисленияДанныеГрафика.ЗначениеБазовыйПериод, 0) КАК БазаДней,
| ЕСТЬNULL(ОсновныеНачисленияДанныеГрафика.ЗначениеПериодДействия, 0) КАК ПланДней”;
КонецЕсли;
Если НужнаБаза Тогда
Запрос.Текст = Запрос.Текст + “,
| ЕСТЬNULL(ОсновныеНачисленияБазаДополнительныеНачисления.РезультатБаза, 0) + ЕСТЬNULL(ОсновныеНачисленияБазаОсновныеНачисления.РезультатБаза, 0) КАК База”;
КонецЕсли;
Запрос.Текст = Запрос.Текст + ”
|ИЗ
| РегистрРасчета.ОсновныеНачисления КАК ОсновныеНачисления”;
Если НуженГрафик Тогда
Запрос.Текст = Запрос.Текст + ”
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ОсновныеНачисления.ДанныеГрафика(
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &Категория) КАК ОсновныеНачисленияДанныеГрафика
| ПО ОсновныеНачисления.НомерСтроки = ОсновныеНачисленияДанныеГрафика.НомерСтроки”;
КонецЕсли;
Если НужнаБаза Тогда
Запрос.Текст = Запрос.Текст + “,
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ОсновныеНачисления.БазаДополнительныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &Категория) КАК ОсновныеНачисленияБазаДополнительныеНачисления
| ПО ОсновныеНачисления.НомерСтроки = ОсновныеНачисленияБазаДополнительныеНачисления.НомерСтроки
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ОсновныеНачисления.БазаОсновныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &Категория) КАК ОсновныеНачисленияБазаОсновныеНачисления
| ПО ОсновныеНачисления.НомерСтроки = ОсновныеНачисленияБазаОсновныеНачисления.НомерСтроки”;
КонецЕсли;
Запрос.Текст = Запрос.Текст + ” ГДЕ ОсновныеНачисления.Регистратор = &Ссылка И ОсновныеНачисления.ВидРасчета.КатегорияРасчета = &Категория”;
Измерения = Новый Массив;
Измерения.Добавить(“Сотрудник”);
Измерения.Добавить(“Подразделение”);
Запрос.УстановитьПараметр(“Движения”, Измерения);
Запрос.УстановитьПараметр(“Ссылка”, Ссылка);
Запрос.УстановитьПараметр(“Категория”, Категория);
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
НомерСтроки = Новый Структура(“НомерСтроки”);
Для каждого Запись Из Движения.ОсновныеНачисления Цикл
НомерСтроки.НомерСтроки = Запись.НомерСтроки;
Выборка.Сбросить();
Если НЕ Выборка.НайтиСледующий(НомерСтроки) Тогда
Продолжить;
КонецЕсли;
Способ = Запись.ВидРасчета.СпособРасчета;
Если Способ = Перечисления.СпособыРасчета.ПоВремени Тогда
Если Выборка.ПланДней=0 Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = “Не заполнен график – “+Запись.ТипГрафика;
Сообщение.Сообщить();
Отказ = Истина;
Иначе
Результат = Запись.Размер*Выборка.ФактДней/Выборка.ПланДней;
КонецЕсли;
ИначеЕсли Способ = Перечисления.СпособыРасчета.ПоСреднему Тогда
Если Выборка.БазаДней=0 Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = “Не заполнен график – “+Запись.ТипГрафика;
Сообщение.Сообщить();
Отказ = Истина;
Иначе
Результат = Выборка.ФактДней * Выборка.База/Выборка.БазаДней;
КонецЕсли;
ИначеЕсли Способ = Перечисления.СпособыРасчета.БезОплаты Тогда
Результат = 0;
ИначеЕсли Способ = Перечисления.СпособыРасчета.ПоТарифу Тогда
Результат = Запись.Размер*Выборка.ФактДней;
Иначе
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = “Алгоритм для способа расчета “+Способ+” не определен”;
Сообщение.Сообщить();
Отказ = Истина;
КонецЕсли;
Запись.Результат = Результат * ?(Запись.Сторно, -1, 1);
КонецЦикла;
Движения.ОсновныеНачисления.Записать(,Истина);
КонецПроцедуры
Процедура РасчетДополнительныхНачислений(Отказ, Категория=0, Способы, ИмяРегистра)
НужнаБаза = Ложь;
НужнаБазаРуководителю = Ложь;
Для Каждого Способ Из Способы Цикл
Если Способ = Перечисления.СпособыРасчета.Процентом Тогда
НужнаБаза = Истина;
ИначеЕсли Способ = Перечисления.СпособыРасчета.НадбавкаРуководителю Тогда
НужнаБазаРуководителю = Истина;
КонецЕсли;
КонецЦикла;
Запрос = Новый Запрос;
Запрос.Текст =
“ВЫБРАТЬ
| ДополнительныеНачисления.НомерСтроки КАК НомерСтроки,
| ДополнительныеНачисления.Размер”;
Если НужнаБаза Тогда
Запрос.Текст = Запрос.Текст + “,
| ЕСТЬNULL(ДополнительныеНачисленияБазаОсновныеНачисления.РезультатБаза, 0) + ЕСТЬNULL(ДополнительныеНачисленияБазаДополнительныеНачисления.РезультатБаза, 0) КАК База”;
КонецЕсли;
Если НужнаБазаРуководителю Тогда
Запрос.Текст = Запрос.Текст + “,
| ЕСТЬNULL(ДополнительныеНачисленияБазаДополнительныеНачисленияПериодРегистрации.РезультатБаза, 0) КАК БазаРук”;
КонецЕсли;
Запрос.Текст = Запрос.Текст + ”
|ИЗ
| РегистрРасчета.ДополнительныеНачисления КАК ДополнительныеНачисления”;
Если НужнаБаза Тогда
Запрос.Текст = Запрос.Текст + ”
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисления.БазаДополнительныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &Категория) КАК ДополнительныеНачисленияБазаДополнительныеНачисления
| ПО ДополнительныеНачисления.НомерСтроки = ДополнительныеНачисленияБазаДополнительныеНачисления.НомерСтроки
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисления.БазаОсновныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &Категория) КАК ДополнительныеНачисленияБазаОсновныеНачисления
| ПО ДополнительныеНачисления.НомерСтроки = ДополнительныеНачисленияБазаОсновныеНачисления.НомерСтроки”;
КонецЕсли;
Если НужнаБазаРуководителю Тогда
Запрос.Текст = Запрос.Текст + ”
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисления.БазаДополнительныеНачисленияПериодРегистрации(
| &ИзмеренияРук,
| &ИзмеренияРук,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &Категория) КАК ДополнительныеНачисленияБазаДополнительныеНачисленияПериодРегистрации
| ПО ДополнительныеНачисления.НомерСтроки = ДополнительныеНачисленияБазаДополнительныеНачисленияПериодРегистрации.НомерСтроки”;
КонецЕсли;
Запрос.Текст = Запрос.Текст + ”
|ГДЕ
| ДополнительныеНачисления.Регистратор = &Ссылка
| И ДополнительныеНачисления.ВидРасчета.КатегорияРасчета = &Категория”;
Если ИмяРегистра=”ДополнительныеНачисленияПериодРегистрации” Тогда
Запрос.Текст = СтрЗаменить(Запрос.Текст, “РегистрРасчета.ДополнительныеНачисления”, “РегистрРасчета.ДополнительныеНачисленияПериодРегистрации”);
КонецЕсли;
Измерения = Новый Массив;
Измерения.Добавить(“Сотрудник”);
Измерения.Добавить(“Подразделение”);
Запрос.УстановитьПараметр(“Измерения”, Измерения);
Запрос.УстановитьПараметр(“Ссылка”, Ссылка);
Запрос.УстановитьПараметр(“Категория”, Категория);
ИзмеренияРук = Новый Массив;
ИзмеренияРук.Добавить(“Подразделение”);
Запрос.УстановитьПараметр(“ИзмеренияРук”, ИзмеренияРук);
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Выборка = Результат.Выбрать();
НомерСтроки = Новый Структура(“НомерСтроки”);
Для каждого Запись Из Движения[ИмяРегистра] Цикл
НомерСтроки.НомерСтроки = Запись.НомерСтроки;
Выборка.Сбросить();
Если НЕ Выборка.НайтиСледующий(НомерСтроки) Тогда
Продолжить;
КонецЕсли;
Способ = Запись.ВидРасчета.СпособРасчета;
Если Способ = Перечисления.СпособыРасчета.Процентом Тогда
Результат = Выборка.База*Запись.Размер/100;
ИначеЕсли Способ = Перечисления.СпособыРасчета.НадбавкаРуководителю Тогда
Результат = Выборка.БазаРук*Запись.Размер/100;
Иначе
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = “Алгоритм для способа расчета “+Способ+” не определен”;
Сообщение.Сообщить();
Отказ = Истина;
КонецЕсли;
Запись.Результат = Результат * ?(Запись.Сторно, -1, 1);
КонецЦикла;
Движения[ИмяРегистра].Записать(,Истина);
КонецПроцедуры</code>
Каюсь, без решения не разобрался бы как надбавку руководителю отдела реализовать. Самая интересная домашняя работа для меня!
Больше всего понравилась последняя часть базового курса, т.к. с регистрами расчета не сталкивался ни разу.
P.S. Я сейчас оплачу продление мастер-группы базового курса и финальное задание могу выполнить с 5-ым потоком, правильно понимаю?
Да, правильно, сможете зафиналится с 5-м потоком.
Последним, но все же добежал!
Задание, фактически выполняется на основании только что просмотренных видеоуроков и, если дельта между просмотром и выполнение маленькая, то затруднений почти нет. Вот как у меня.
Переработал имеющийся функционал в универсальную схему. Первые три расчета без затруднений, а вот с надбавкой руководителю не удалось справиться напролом поздно вечером, поэтому делал уже сегодня утром, причем лень было уже мучаться придумывать как вычитать премию руководителя из всех остальных премий, и сделал отдельно виды расчетов премий для рядовых сотрудников и для руководителя. Как оказалось – угадал решение. Отчет сделал без затруднений.
Обратная связь. Блок расчетов для меня совершенно новый и незнакомый, смотрел медленно. Тема по жизни суховатая и даже кажется обманчиво простой, но все равно было любопытно, и оказалось не все так легко. Изложено понятно, ничего сверх того что показано, наверное не нужно, и так полная голова информации. Для закрепления знаний планирую просмотреть бонусные видео по решению аттестационной задачи по расчету и порешать задачки по платформе.
Ок :)
ДЗ выполнил добавив категории и способы расчета, а также в осн. виды расчетов добавил дополнительный крыжик “компенсация”, в доп. виды расчетов добавил дополнительные реквизиты галку-премия и количество месяцев премии. В зависимости от кол-ва месяцев премии берется база. Все расчеты вывел в отдельный модуль. Он мало чем отличается от модуля по теории :)
<code>
Процедура Расчитать(Набор, Отказ)Экспорт
Ссылка = Набор.Отбор.Регистратор.Значение;
ИмяРегистра = Набор.Метаданные().Имя;
Запрос = Новый Запрос;
Запрос.Текст =
“ВЫБРАТЬ РАЗЛИЧНЫЕ
| ОсновныеНачисления.ВидРасчета.КатегорияРасчета КАК Категория,
| ОсновныеНачисления.ВидРасчета.СпособРасчета КАК Способ
|ИЗ
| РегистрРасчета.ОсновныеНачисления КАК ОсновныеНачисления
|ГДЕ
| ОсновныеНачисления.Регистратор = &Ссылка
|
|УПОРЯДОЧИТЬ ПО
| Категория
|ИТОГИ ПО
| Категория”;
Запрос.Текст = СтрЗаменить(Запрос.Текст, “ОсновныеНачисления”, ИмяРегистра);
Запрос.УстановитьПараметр(“Ссылка”, Ссылка);
Результат = Запрос.Выполнить();
ВыборкаКатегории = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока ВыборкаКатегории.Следующий() Цикл
ВыборкаСпособы = ВыборкаКатегории.Выбрать();
Параметры = ПолучитьСтруктуруНеобходимыхДанных(ВыборкаСпособы);
Результат = ПолучитьДанныеДляРасчета(Параметры, ИмяРегистра, Ссылка, ВыборкаКатегории.Категория);
Выборка = Результат.Выбрать();
РассчитатьЗаписиРегистраРасчета(Выборка, Набор, Отказ);
Набор.Записать(,Истина);
КонецЦикла;
КонецПроцедуры
Функция ПолучитьСтруктуруНеобходимыхДанных(Выборка)
Параметры = Новый Структура;
Параметры.Вставить(“ДанныеГрафика”, Ложь);
Параметры.Вставить(“База”, Ложь);
Пока Выборка.Следующий() Цикл
Если Выборка.Способ = Перечисления.СпособыРасчета.ПоОтработанномуВремени Тогда
Параметры.ДанныеГрафика = Истина;
ИначеЕсли Выборка.Способ = Перечисления.СпособыРасчета.Процентом или Выборка.Способ = Перечисления.СпособыРасчета.ПоСреднему Тогда
Параметры.База = Истина;
КонецЕсли;
КонецЦикла;
Возврат Параметры;
КонецФункции
Функция ПолучитьДанныеДляРасчета(Параметры, ИмяРегистра, Ссылка, КатегорияРасчета)
Запрос = Новый Запрос;
Запрос.УстановитьПараметр(“Ссылка”, Ссылка);
Измерения = Новый Массив;
Измерения.Добавить(“Сотрудник”);
Измерения.Добавить(“Подразделение”);
Запрос.УстановитьПараметр(“Измерения”, Измерения);
Запрос.УстановитьПараметр(“КатегорияРасчета”, КатегорияРасчета);
Если ИмяРегистра = “ОсновныеНачисления” Тогда
Запрос.Текст = “ВЫБРАТЬ
| ОсновныеНачисления.НомерСтроки,
| ОсновныеНачисления.ВидРасчета.СпособРасчета Способ,
| ОсновныеНачисления.Размер”;
Если Параметры.ДанныеГрафика Тогда
Запрос.Текст = Запрос.Текст + ”
| ,ЕСТЬNULL(ОсновныеНачисленияДанныеГрафика.ЗначениеПериодДействия, 0) КАК План,
| ЕСТЬNULL(ОсновныеНачисленияДанныеГрафика.ЗначениеФактическийПериодДействия, 0) КАК Факт”;
КонецЕсли;
Если Параметры.База Тогда
Запрос.Текст = Запрос.Текст + ”
| ,ЕСТЬNULL(ОсновныеНачисленияБазаОсновныеНачисления.РезультатБаза, 0) + ЕСТЬNULL(ОсновныеНачисленияБазаДополнительныеНачисления.РезультатБаза, 0) КАК База”;
КонецЕсли;
Запрос.Текст = Запрос.Текст + ”
|ИЗ
| РегистрРасчета.ОсновныеНачисления КАК ОсновныеНачисления”;
Если Параметры.ДанныеГрафика Тогда
Запрос.Текст = Запрос.Текст + ”
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ОсновныеНачисления.ДанныеГрафика(
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК ОсновныеНачисленияДанныеГрафика
| ПО ОсновныеНачисления.НомерСтроки = ОсновныеНачисленияДанныеГрафика.НомерСтроки”;
КонецЕсли;
Если Параметры.База Тогда
Запрос.Текст = Запрос.Текст + ”
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ОсновныеНачисления.БазаОсновныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК ОсновныеНачисленияБазаОсновныеНачисления
| ПО ОсновныеНачисления.НомерСтроки = ОсновныеНачисленияБазаОсновныеНачисления.НомерСтроки
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ОсновныеНачисления.БазаДополнительныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК ОсновныеНачисленияБазаДополнительныеНачисления
| ПО ОсновныеНачисления.НомерСтроки = ОсновныеНачисленияБазаДополнительныеНачисления.НомерСтроки”;
КонецЕсли;
Запрос.Текст = Запрос.Текст + ”
|ГДЕ
| ОсновныеНачисления.Регистратор = &Ссылка
| И ОсновныеНачисления.ВидРасчета.КатегорияРасчета = &КатегорияРасчета”;
ИначеЕсли ИмяРегистра = “ДополнительныеНачисления” Тогда
Запрос.Текст = “ВЫБРАТЬ
| ДополнительныеНачисления.НомерСтроки,
| ДополнительныеНачисления.ВидРасчета.СпособРасчета КАК Способ,
| ДополнительныеНачисления.ВидРасчета.ФлагПремии КАК ФлагПремии,
| ДополнительныеНачисления.Размер”;
Если Параметры.База Тогда
Запрос.Текст = Запрос.Текст + ”
| ,ЕСТЬNULL(ДополнительныеНачисленияБазаДополнительныеНачисления.РезультатБаза, 0) + ЕСТЬNULL(ДополнительныеНачисленияБазаОсновныеНачисления.РезультатБаза, 0) КАК База”;
КонецЕсли;
Запрос.Текст = Запрос.Текст + ”
|ИЗ
| РегистрРасчета.ДополнительныеНачисления КАК ДополнительныеНачисления”;
Если Параметры.База Тогда
Запрос.Текст = Запрос.Текст + ”
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисления.БазаДополнительныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК ДополнительныеНачисленияБазаДополнительныеНачисления
| ПО ДополнительныеНачисления.НомерСтроки = ДополнительныеНачисленияБазаДополнительныеНачисления.НомерСтроки
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисления.БазаОсновныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК ДополнительныеНачисленияБазаОсновныеНачисления
| ПО ДополнительныеНачисления.НомерСтроки = ДополнительныеНачисленияБазаОсновныеНачисления.НомерСтроки”;
КонецЕсли;
Запрос.Текст = Запрос.Текст + ”
|ГДЕ
| ДополнительныеНачисления.Регистратор = &Ссылка
| И ДополнительныеНачисления.ВидРасчета.КатегорияРасчета = &КатегорияРасчета”;
КонецЕсли;
Возврат Запрос.Выполнить();
КонецФункции // ПолучитьДанныеДляРасчета(Параметры)()
Процедура РассчитатьЗаписиРегистраРасчета(Выборка, Набор, Отказ)
Поиск = Новый Структура(“НомерСтроки”);
Для каждого Запись Из Набор Цикл
Поиск.НомерСтроки = Запись.НомерСтроки;
Выборка.Сбросить();
Если Выборка.НайтиСледующий(Поиск) Тогда
Если Выборка.Способ = Перечисления.СпособыРасчета.ПоОтработанномуВремени Тогда
Если Выборка.План=0 Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = “Нет данных графика”;
Сообщение.Сообщить();
Отказ = Истина;
Иначе
Если Запись.ВидРасчета.Компенсация Тогда
Результат = Выборка.Факт*Выборка.Размер;
Иначе
Результат = Выборка.Факт*Выборка.Размер/Выборка.План;
КонецЕсли;
КонецЕсли;
ИначеЕсли Выборка.Способ = Перечисления.СпособыРасчета.ФиксированнойСуммой Тогда
Результат = Выборка.Размер;
ИначеЕсли Выборка.Способ = Перечисления.СпособыРасчета.Процентом Тогда
Результат = Выборка.Размер*Выборка.База/100;
ИначеЕсли Выборка.Способ = Перечисления.СпособыРасчета.ПоСреднему Тогда
Результат = Выборка.База*ОпределитьКоличествоДнейОтпуска(Запись.ПериодДействияНачало,Запись.ПериодДействияКонец)/ЗначенияГрафика(Запись)*?(Запись.Сторно, -1, 1)
КонецЕсли;
Запись.Результат = Результат*?(Запись.Сторно, -1, 1);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция ЗначенияГрафика(Запись)
Запрос = Новый Запрос;
Запрос.Текст =
“ВЫБРАТЬ
| СУММА(ГрафикиРабот.Значение) КАК РабочиеДни
|ИЗ
| РегистрСведений.ГрафикиРабот КАК ГрафикиРабот
|ГДЕ
| ГрафикиРабот.ТипГрафика = &ТипГрафика
| И ГрафикиРабот.Дата МЕЖДУ &ДатаНач И &ДатаКон”;
Запрос.УстановитьПараметр(“ДатаКон”, Запись.БазовыйПериодКонец);
Запрос.УстановитьПараметр(“ДатаНач”, Запись.БазовыйПериодНачало);
Запрос.УстановитьПараметр(“ТипГрафика”, Запись.ТипГрафика);
Результат = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = Результат.Выбрать();
ВыборкаДетальныеЗаписи.Следующий();
Возврат ВыборкаДетальныеЗаписи.РабочиеДни;
КонецФункции
Функция ОпределитьКоличествоДнейОтпуска(ПериодДействияНачало,ПериодДействияКонец)
Количество = 0;
Счетчик = 24*3600;
НачалоПериода = ПериодДействияНачало;
КонецПериода = ПериодДействияКонец;
Пока НачалоПериода < КонецПериода Цикл
НачалоПериода = НачалоПериода + Счетчик;
Количество = Количество +1;
КонецЦикла;
Возврат Количество-1;
КонецФункции
Процедура Расчитать(Набор, Отказ)Экспорт Ссылка = Набор.Отбор.Регистратор.Значение; ИмяРегистра = Набор.Метаданные().Имя; Запрос = Новый Запрос; Запрос.Текст = “ВЫБРАТЬ РАЗЛИЧНЫЕ | ОсновныеНачисления.ВидРасчета.КатегорияРасчета КАК Категория, | ОсновныеНачисления.ВидРасчета.СпособРасчета КАК Способ |ИЗ | РегистрРасчета.ОсновныеНачисления КАК ОсновныеНачисления |ГДЕ | ОсновныеНачисления.Регистратор = &Ссылка | |УПОРЯДОЧИТЬ ПО | Категория |ИТОГИ ПО | Категория”; Запрос.Текст = СтрЗаменить(Запрос.Текст, “ОсновныеНачисления”, ИмяРегистра); Запрос.УстановитьПараметр(“Ссылка”, Ссылка); Результат = Запрос.Выполнить(); ВыборкаКатегории = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам); Пока ВыборкаКатегории.Следующий() Цикл ВыборкаСпособы = ВыборкаКатегории.Выбрать(); Параметры = ПолучитьСтруктуруНеобходимыхДанных(ВыборкаСпособы); Результат = ПолучитьДанныеДляРасчета(Параметры, ИмяРегистра, Ссылка, ВыборкаКатегории.Категория); Выборка = Результат.Выбрать(); РассчитатьЗаписиРегистраРасчета(Выборка, Набор, Отказ); Набор.Записать(,Истина); КонецЦикла;КонецПроцедуры Функция ПолучитьСтруктуруНеобходимыхДанных(Выборка) Параметры = Новый Структура; Параметры.Вставить(“ДанныеГрафика”, Ложь); Параметры.Вставить(“База”, Ложь); Пока Выборка.Следующий() Цикл Если Выборка.Способ = Перечисления.СпособыРасчета.ПоОтработанномуВремени Тогда Параметры.ДанныеГрафика = Истина; ИначеЕсли Выборка.Способ = Перечисления.СпособыРасчета.Процентом или Выборка.Способ = Перечисления.СпособыРасчета.ПоСреднему Тогда Параметры.База = Истина; КонецЕсли; КонецЦикла; Возврат Параметры; КонецФункции
Функция ПолучитьДанныеДляРасчета(Параметры, ИмяРегистра, Ссылка, КатегорияРасчета) Запрос = Новый Запрос; Запрос.УстановитьПараметр(“Ссылка”, Ссылка); Измерения = Новый Массив; Измерения.Добавить(“Сотрудник”); Измерения.Добавить(“Подразделение”); Запрос.УстановитьПараметр(“Измерения”, Измерения); Запрос.УстановитьПараметр(“КатегорияРасчета”, КатегорияРасчета); Если ИмяРегистра = “ОсновныеНачисления” Тогда Запрос.Текст = “ВЫБРАТЬ | ОсновныеНачисления.НомерСтроки, | ОсновныеНачисления.ВидРасчета.СпособРасчета Способ, | ОсновныеНачисления.Размер”; Если Параметры.ДанныеГрафика Тогда Запрос.Текст = Запрос.Текст + ” | ,ЕСТЬNULL(ОсновныеНачисленияДанныеГрафика.ЗначениеПериодДействия, 0) КАК План, | ЕСТЬNULL(ОсновныеНачисленияДанныеГрафика.ЗначениеФактическийПериодДействия, 0) КАК Факт”; КонецЕсли; Если Параметры.База Тогда Запрос.Текст = Запрос.Текст + ” | ,ЕСТЬNULL(ОсновныеНачисленияБазаОсновныеНачисления.РезультатБаза, 0) + ЕСТЬNULL(ОсновныеНачисленияБазаДополнительныеНачисления.РезультатБаза, 0) КАК База”; КонецЕсли; Запрос.Текст = Запрос.Текст + ” |ИЗ | РегистрРасчета.ОсновныеНачисления КАК ОсновныеНачисления”; Если Параметры.ДанныеГрафика Тогда Запрос.Текст = Запрос.Текст + ” | ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ОсновныеНачисления.ДанныеГрафика( | Регистратор = &Ссылка | И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК ОсновныеНачисленияДанныеГрафика | ПО ОсновныеНачисления.НомерСтроки = ОсновныеНачисленияДанныеГрафика.НомерСтроки”; КонецЕсли; Если Параметры.База Тогда Запрос.Текст = Запрос.Текст + ” | ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ОсновныеНачисления.БазаОсновныеНачисления( | &Измерения, | &Измерения, | , | Регистратор = &Ссылка | И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК ОсновныеНачисленияБазаОсновныеНачисления | ПО ОсновныеНачисления.НомерСтроки = ОсновныеНачисленияБазаОсновныеНачисления.НомерСтроки | ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ОсновныеНачисления.БазаДополнительныеНачисления( | &Измерения, | &Измерения, | , | Регистратор = &Ссылка | И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК ОсновныеНачисленияБазаДополнительныеНачисления | ПО ОсновныеНачисления.НомерСтроки = ОсновныеНачисленияБазаДополнительныеНачисления.НомерСтроки”; КонецЕсли; Запрос.Текст = Запрос.Текст + ” |ГДЕ | ОсновныеНачисления.Регистратор = &Ссылка | И ОсновныеНачисления.ВидРасчета.КатегорияРасчета = &КатегорияРасчета”; ИначеЕсли ИмяРегистра = “ДополнительныеНачисления” Тогда Запрос.Текст = “ВЫБРАТЬ | ДополнительныеНачисления.НомерСтроки, | ДополнительныеНачисления.ВидРасчета.СпособРасчета КАК Способ, | ДополнительныеНачисления.ВидРасчета.ФлагПремии КАК ФлагПремии, | ДополнительныеНачисления.Размер”; Если Параметры.База Тогда Запрос.Текст = Запрос.Текст + ” | ,ЕСТЬNULL(ДополнительныеНачисленияБазаДополнительныеНачисления.РезультатБаза, 0) + ЕСТЬNULL(ДополнительныеНачисленияБазаОсновныеНачисления.РезультатБаза, 0) КАК База”; КонецЕсли; Запрос.Текст = Запрос.Текст + ” |ИЗ | РегистрРасчета.ДополнительныеНачисления КАК ДополнительныеНачисления”; Если Параметры.База Тогда Запрос.Текст = Запрос.Текст + ” | ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисления.БазаДополнительныеНачисления( | &Измерения, | &Измерения, | , | Регистратор = &Ссылка | И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК ДополнительныеНачисленияБазаДополнительныеНачисления | ПО ДополнительныеНачисления.НомерСтроки = ДополнительныеНачисленияБазаДополнительныеНачисления.НомерСтроки | ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисления.БазаОсновныеНачисления( | &Измерения, | &Измерения, | , | Регистратор = &Ссылка | И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК ДополнительныеНачисленияБазаОсновныеНачисления | ПО ДополнительныеНачисления.НомерСтроки = ДополнительныеНачисленияБазаОсновныеНачисления.НомерСтроки”; КонецЕсли; Запрос.Текст = Запрос.Текст + ” |ГДЕ | ДополнительныеНачисления.Регистратор = &Ссылка | И ДополнительныеНачисления.ВидРасчета.КатегорияРасчета = &КатегорияРасчета”; КонецЕсли; Возврат Запрос.Выполнить(); КонецФункции // ПолучитьДанныеДляРасчета(Параметры)()
Процедура РассчитатьЗаписиРегистраРасчета(Выборка, Набор, Отказ)
Поиск = Новый Структура(“НомерСтроки”); Для каждого Запись Из Набор Цикл Поиск.НомерСтроки = Запись.НомерСтроки; Выборка.Сбросить(); Если Выборка.НайтиСледующий(Поиск) Тогда Если Выборка.Способ = Перечисления.СпособыРасчета.ПоОтработанномуВремени Тогда Если Выборка.План=0 Тогда Сообщение = Новый СообщениеПользователю; Сообщение.Текст = “Нет данных графика”; Сообщение.Сообщить(); Отказ = Истина; Иначе Если Запись.ВидРасчета.Компенсация Тогда Результат = Выборка.Факт*Выборка.Размер; Иначе Результат = Выборка.Факт*Выборка.Размер/Выборка.План; КонецЕсли; КонецЕсли; ИначеЕсли Выборка.Способ = Перечисления.СпособыРасчета.ФиксированнойСуммой Тогда Результат = Выборка.Размер; ИначеЕсли Выборка.Способ = Перечисления.СпособыРасчета.Процентом Тогда Результат = Выборка.Размер*Выборка.База/100; ИначеЕсли Выборка.Способ = Перечисления.СпособыРасчета.ПоСреднему Тогда Результат = Выборка.База*ОпределитьКоличествоДнейОтпуска(Запись.ПериодДействияНачало,Запись.ПериодДействияКонец)/ЗначенияГрафика(Запись)*?(Запись.Сторно, -1, 1) КонецЕсли; Запись.Результат = Результат*?(Запись.Сторно, -1, 1); КонецЕсли; КонецЦикла; КонецПроцедуры
Функция ЗначенияГрафика(Запись) Запрос = Новый Запрос; Запрос.Текст = “ВЫБРАТЬ | СУММА(ГрафикиРабот.Значение) КАК РабочиеДни |ИЗ | РегистрСведений.ГрафикиРабот КАК ГрафикиРабот |ГДЕ | ГрафикиРабот.ТипГрафика = &ТипГрафика | И ГрафикиРабот.Дата МЕЖДУ &ДатаНач И &ДатаКон”; Запрос.УстановитьПараметр(“ДатаКон”, Запись.БазовыйПериодКонец); Запрос.УстановитьПараметр(“ДатаНач”, Запись.БазовыйПериодНачало); Запрос.УстановитьПараметр(“ТипГрафика”, Запись.ТипГрафика); Результат = Запрос.Выполнить(); ВыборкаДетальныеЗаписи = Результат.Выбрать(); ВыборкаДетальныеЗаписи.Следующий(); Возврат ВыборкаДетальныеЗаписи.РабочиеДни;КонецФункции
Функция ОпределитьКоличествоДнейОтпуска(ПериодДействияНачало,ПериодДействияКонец) Количество = 0; Счетчик = 24*3600; НачалоПериода = ПериодДействияНачало; КонецПериода = ПериодДействияКонец; Пока НачалоПериода < КонецПериода Цикл НачалоПериода = НачалоПериода + Счетчик; Количество = Количество +1; КонецЦикла; Возврат Количество-1;КонецФункции</code>
Запрос по отчету:
<code>ВЫБРАТЬ
ОсновныеНачисления.ПериодРегистрации КАК Период,
ОсновныеНачисления.Сотрудник,
ОсновныеНачисления.Подразделение,
ОсновныеНачисления.Результат КАК Начислено,
ОсновныеНачисления.ВидРасчета
ИЗ
РегистрРасчета.ОсновныеНачисления КАК ОсновныеНачисления
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
ДополнительныеНачисления.ПериодРегистрации,
ДополнительныеНачисления.Сотрудник,
ДополнительныеНачисления.Подразделение,
ДополнительныеНачисления.Результат,
ДополнительныеНачисления.ВидРасчета
ИЗ
РегистрРасчета.ДополнительныеНачисления КАК ДополнительныеНачисления</code>
Спасибо за интересные ДЗ. Встретимся снова уже с 4 июля в продвинутом курсе! :)
Хорошо :)
Отчет по блоку:
1) Ранее не сталкивавшись с расчетом пришлось
усваивать материал с нуля и выполнять задания со значительным
усилием.
2) Материал подан корректно, хорошо организованной структурой
Задание выполнено со значительными затруднениями, но балгодаря
хорошо проработанной структуре подачи информации уроков
всё получается.
Введены способы(перечисления) и
категории расчета(просто реквизит число).
После модификации алгоритма начисления результирующие данные
не изменились, введена обработка способа расчета и категории расчета.
способ расчета непостредственно влияет на структура начисления,
а категория на включение этих структур в текущий документ
начисления.
На основании способов и категорий расчетов реализовал – премию по итогам года
, премию ежемесячную, компенсацию за обеды, надбавку руководителя отдела
Составление отчета на СКД не составил трудностей.
Выргузка ИБ
Задание выполнено
http://www.imagepost.ru/?v=dz15_screen.png
Задание выполнила наконец. Привожу существенные блоки кода из общего модуля, где реализован расчет:
<code> Процедура РассчитатьНачисление(НаборЗаписей,Отказ) Экспорт
ИмяНабора = НаборЗаписей.Метаданные().Имя;
Регистратор = НаборЗаписей.Отбор.Регистратор.Значение;
Запрос = Новый Запрос;
Запрос.Текст =
“ВЫБРАТЬ
| ОсновныеНачисления.ВидРасчета.СпособРасчета КАК Способ,
| ОсновныеНачисления.ВидРасчета.КатегорияРасчета КАК Категория
|ИЗ
| РегистрРасчета.ОсновныеНачисления КАК ОсновныеНачисления
|ГДЕ
| ОсновныеНачисления.Регистратор = &Регистратор
|ИТОГИ ПО
| Категория”;
Запрос.УстановитьПараметр(“Регистратор”, Регистратор);
Запрос.Текст = СтрЗаменить(Запрос.Текст,”ОсновныеНачисления”,ИмяНабора);
Результат = Запрос.Выполнить();
ВыборкаКатегория = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока ВыборкаКатегория.Следующий() Цикл
ВыборкаСпособ = ВыборкаКатегория.Выбрать();
Пока ВыборкаСпособ.Следующий() Цикл
СтруктураПараметров = ПолучитьСтруктуруПараметров(ВыборкаСпособ);
ДанныеДляРасчета = ПолучитьДанныеДляРасчета(СтруктураПараметров,ИмяНабора,Регистратор,ВыборкаСпособ.Категория);
Выборка = ДанныеДляРасчета.Выбрать();
РассчитатьЗаписи(Выборка,НаборЗаписей,Отказ);
НаборЗаписей.Записать(,Истина);
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Процедура РассчитатьЗаписи(Выборка,НаборЗаписей,Отказ)
Для каждого СтрокаНабора Из НаборЗаписей Цикл
СтруктураПоиск = Новый Структура;
СтруктураПоиск.Вставить(“НомерСтроки”,СтрокаНабора.НомерСтроки);
Выборка.Сбросить();
Если Выборка.НайтиСледующий(СтруктураПоиск) Тогда
Если Выборка.Способ = Перечисления.СпособРасчета.ПоОтработанномуВремени Тогда
Если Не ЗначениеЗаполнено(Выборка.План) Тогда
Сообщить(“Ошибка в графике расчета”);
Отказ = Истина;
КонецЕсли;
СтрокаНабора.Результат = Выборка.Факт*СтрокаНабора.Размер/Выборка.План;
ИначеЕсли Выборка.Способ = Перечисления.СпособРасчета.ПоОтработанномуВремениЗаДень Тогда
Если Не ЗначениеЗаполнено(Выборка.План) Тогда
Сообщить(“Ошибка в графике расчета”);
Отказ = Истина;
КонецЕсли;
СтрокаНабора.Результат = Выборка.Факт*СтрокаНабора.Размер;
ИначеЕсли Выборка.Способ = Перечисления.СпособРасчета.ФиксированнойСуммой Тогда
СтрокаНабора.Результат = СтрокаНабора.Размер;
ИначеЕсли Выборка.Способ = Перечисления.СпособРасчета.ПоСредней Тогда
СтрокаНабора.Результат = Выборка.План*Выборка.База/Выборка.ПериодБаза;
ИначеЕсли Выборка.Способ = Перечисления.СпособРасчета.Процентом Тогда
СтрокаНабора.Результат = Выборка.База*СтрокаНабора.Размер/100;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция ПолучитьСтруктуруПараметров(Выборка)
СтруктураПараметров = Новый Структура;
СтруктураПараметров.Вставить(“База”,Ложь);
СтруктураПараметров.Вставить(“График”,Ложь);
Если Выборка.Способ = Перечисления.СпособРасчета.ПоОтработанномуВремени или Выборка.Способ = Перечисления.СпособРасчета.ВынужденныйПростой
или Выборка.Способ = Перечисления.СпособРасчета.УдержаниеЗаНевыход Тогда
СтруктураПараметров.График = Истина;
ИначеЕсли Выборка.Способ = Перечисления.СпособРасчета.Процентом Тогда
СтруктураПараметров.База = Истина;
ИначеЕсли Выборка.Способ = Перечисления.СпособРасчета.ПоСредней Тогда
СтруктураПараметров.База = Истина;
СтруктураПараметров.График = Истина;
ИначеЕсли Выборка.Способ = Перечисления.СпособРасчета.ПоОтработанномуВремениЗаДень Тогда
СтруктураПараметров.База = Ложь;
СтруктураПараметров.График = Истина;
КонецЕсли;
Возврат СтруктураПараметров;
КонецФункции // ПолучитьСтруктуруПараметров()
Функция ПолучитьДанныеДляРасчета(Параметры,ИмяНабора,Регистратор,КатегорияРасчета)
Запрос = Новый Запрос;
Запрос.УстановитьПараметр(“Регистратор”,Регистратор);
Измерения = Новый Массив;
Измерения.Добавить(“Сотрудник”);
Измерения.Добавить(“Подразделение”);
Запрос.УстановитьПараметр(“Измерения”,Измерения);
Запрос.УстановитьПараметр(“Категория”,КатегорияРасчета);
Если ИмяНабора = “ОсновныеНачисления” Тогда
Запрос.Текст = “ВЫБРАТЬ
| ОсновныеНачисления.НомерСтроки,
| ОсновныеНачисления.ВидРасчета.СпособРасчета как Способ,
| ОсновныеНачисления.Размер”;
Если Параметры.График Тогда
Запрос.Текст = Запрос.Текст + “,
| ЕСТЬNULL(ОсновныеНачисленияДанныеГрафика.ЗначениеФактическийПериодДействия, 0) КАК Факт,
| ЕСТЬNULL(ОсновныеНачисленияДанныеГрафика.ЗначениеПериодДействия, 0) КАК План”;
КонецЕсли;
Если Параметры.График и Параметры.База Тогда
Запрос.Текст = Запрос.Текст + “,
| ЕСТЬNULL(ОсновныеНачисленияДанныеГрафика.ЗначениеБазовыйПериод, 0) КАК ПериодБаза”;
КонецЕсли;
Если Параметры.База Тогда
Запрос.Текст = Запрос.Текст + “,
| ЕСТЬNULL(ОсновныеНачисленияБазаОсновныеНачисления.РезультатБаза, 0) + ЕСТЬNULL(ОсновныеНачисленияБазаДополнительныеНачисления.РезультатБаза, 0) КАК База”;
КонецЕсли;
Запрос.Текст = Запрос.Текст + ”
|ИЗ
| РегистрРасчета.ОсновныеНачисления КАК ОсновныеНачисления”;
Если Параметры.База Тогда
Запрос.Текст = Запрос.Текст + ”
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ОсновныеНачисления.БазаОсновныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Регистратор
| И ВидРасчета.КатегорияРасчета = &Категория) КАК ОсновныеНачисленияБазаОсновныеНачисления
| ПО ОсновныеНачисления.НомерСтроки = ОсновныеНачисленияБазаОсновныеНачисления.НомерСтроки
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ОсновныеНачисления.БазаДополнительныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Регистратор
| И ВидРасчета.КатегорияРасчета = &Категория) КАК ОсновныеНачисленияБазаДополнительныеНачисления
| ПО ОсновныеНачисления.НомерСтроки = ОсновныеНачисленияБазаДополнительныеНачисления.НомерСтроки”;
КонецЕсли;
Если Параметры.График Тогда
Запрос.Текст = Запрос.Текст + ”
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ОсновныеНачисления.ДанныеГрафика(
| Регистратор = &Регистратор
| И ВидРасчета.КатегорияРасчета = &Категория) КАК ОсновныеНачисленияДанныеГрафика
| ПО ОсновныеНачисления.НомерСтроки = ОсновныеНачисленияДанныеГрафика.НомерСтроки”;
КонецЕсли;
Запрос.Текст = Запрос.Текст + ”
|ГДЕ
| ОсновныеНачисления.Регистратор = &Регистратор
| И ОсновныеНачисления.ВидРасчета.КатегорияРасчета = &Категория”;
ИначеЕсли ИмяНабора = “ДополнительныеНачисления” Тогда
Запрос.Текст = “ВЫБРАТЬ
| ДополнительныеНачисления.НомерСтроки,
| ДополнительныеНачисления.ВидРасчета.СпособРасчета как Способ,
| ДополнительныеНачисления.Размер”;
Если Параметры.База Тогда
Запрос.Текст = Запрос.Текст + “,
| ЕСТЬNULL(ДополнительныеНачисленияБазаОсновныеНачисления.РезультатБаза, 0) + ЕСТЬNULL(ДополнительныеНачисленияБазаДополнительныеНачисления.РезультатБаза, 0) КАК База”;
КонецЕсли;
Запрос.Текст = Запрос.Текст + ”
|ИЗ
| РегистрРасчета.ДополнительныеНачисления КАК ДополнительныеНачисления”;
Если Параметры.База Тогда
Запрос.Текст = Запрос.Текст + ”
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисления.БазаОсновныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Регистратор
| И ВидРасчета.КатегорияРасчета = &Категория) КАК ДополнительныеНачисленияБазаОсновныеНачисления
| ПО ДополнительныеНачисления.НомерСтроки = ДополнительныеНачисленияБазаОсновныеНачисления.НомерСтроки
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисления.БазаДополнительныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Регистратор
| И ВидРасчета.КатегорияРасчета = &Категория) КАК ДополнительныеНачисленияБазаДополнительныеНачисления
| ПО ДополнительныеНачисления.НомерСтроки = ДополнительныеНачисленияБазаДополнительныеНачисления.НомерСтроки”;
КонецЕсли;
Запрос.Текст = Запрос.Текст + ”
|ГДЕ
| ДополнительныеНачисления.Регистратор = &Регистратор
| И ДополнительныеНачисления.ВидРасчета.КатегорияРасчета = &Категория”;
КонецЕсли;
Возврат Запрос.Выполнить();
КонецФункции // ПолучитьДанныеДляРасчета
</code>
С отчетом проблем не возникло.
Обратная связь:
В данной теме все было ново, на практике с расчетом не работаю вообще. Основные затруднения вызвал принцип создания видов расчета, а именно назначения ведущих и вытесняющих видов расчетов. Пришлось не один раз пересмотреть видео по данной теме. Вроде бы разобралась.
1) Первая часть все как по урокам, чуть модернезирована, и оптимальность не доделана. Расчет показал неизменность результата, значит все сделано правильно.
2) Премия по итогам года — добавил новый СпособРасчета.
3) Премия ещемесячная. В условии задачи есть слова «сделанным в текущем месяце». Значит новый вид начисления в ПВР «ДополнительныеНачисления» с расчетом по базе по периоду регистрации.
4) Оплата Обедов — добавил новый СпособРасчета.
5)Надбавка руководителю. Добавил константу КатегорияРасчетаДляНадбавкиРуководителю. И расчет для этой категории будет идти по другому Измерению(без сотрудника). Добавил копированием допначисление МесячнаяПремияРуководителю с категорией КатегорияРасчетаДляНадбавкиРуководителю+1. При расчете НадбавкиРуководителю МесячнаяПремия всех кроме него будет расчитана, потом расчет надбавки, и потом премия месячная руководителю посчитается.(…все хорошо только табличную часть у ДопНачилений не нарисовал) 6)Отчет как в уроке.
Связь обратная – 1) Расчет Зарплаты и объекты по этому блоку. 2) В Самом понимании механизма расчета. Помогла практическая работа по ДЗ. 3) Про тему уже времени не остается.
Общий модуль расчетЗП
<code>
Процедура РасчитатьРегистрРасчета(Набор, Отказ) Экспорт
Ссылка = Набор.Отбор.Регистратор.Значение;
ИмяРегистра = Набор.Метаданные().Имя;
Запрос = Новый Запрос;
Запрос.Текст =
“ВЫБРАТЬ РАЗЛИЧНЫЕ
| ОсновныеНачисления.ВидРасчета.СпособРасчета КАК Способ,
| ОсновныеНачисления.ВидРасчета.КатегорияРасчета КАК Категория
|ИЗ
| РегистрРасчета.ОсновныеНачисления КАК ОсновныеНачисления
|ГДЕ
| ОсновныеНачисления.Регистратор = &Ссылка
|
|УПОРЯДОЧИТЬ ПО
| Категория
|ИТОГИ ПО
| Категория”;
Запрос.Текст = СтрЗаменить(Запрос.Текст, “ОсновныеНачисления”, ИмяРегистра);
Запрос.УстановитьПараметр(“Ссылка”, Ссылка);
Результат = Запрос.Выполнить();
ВыборкаКатегория = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока ВыборкаКатегория.Следующий() Цикл
ВыборкаСпособы = ВыборкаКатегория.Выбрать();
Параметры = ПолучитьСтруктуруНеобходимыхДанных(ВыборкаСпособы);
Результат = ПолучитьДанныеДляРасчетов(Параметры, ИмяРегистра, Ссылка, ВыборкаКатегория.Категория);
Выборка = Результат.Выбрать();
РассчитатьЗаписиРегистраРасчета(Выборка, Набор, Отказ);
Набор.Записать(,Истина);
КонецЦикла;
КонецПроцедуры
Процедура РассчитатьЗаписиРегистраРасчета(Выборка, Набор, Отказ)
Поиск = Новый Структура(“НомерСтроки”);
Для каждого Запись Из Набор Цикл
Поиск.НомерСтроки = Запись.НомерСтроки;
Выборка.Сбросить();
Если Выборка.НайтиСледующий(Поиск) Тогда
Если Выборка.СпособРасчета = Перечисления.СпособРасчета.ОплатаЗаДни Тогда
Результат = Выборка.Факт*Выборка.Размер;
ИначеЕсли Выборка.СпособРасчета = Перечисления.СпособРасчета.ПоОтработанномуВремени Тогда
Если НЕ ЗначениеЗаполнено(Выборка.План) ИЛИ Выборка.План=0 Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = “Нет плана по графику “+Запись.Сотрудник+” “+Запись.ВидРасчета;
Сообщение.Сообщить();
Отказ = Истина;
Иначе
Результат = Выборка.Факт*Выборка.Размер/Выборка.План;
КонецЕсли;
ИначеЕсли Выборка.СпособРасчета = Перечисления.СпособРасчета.УдержаниеЗаПрогул Тогда
//прогул не оплачивается
Результат = 0;
ИначеЕсли Выборка.СпособРасчета = Перечисления.СпособРасчета.ПоЗП Тогда
//проверка базы
Если Выборка.База = 0 Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = “Нет базы для расчета “+Запись.ВидРасчета;;
Сообщение.Сообщить();
Отказ = Истина;
КонецЕсли;
Если Выборка.БазаПлан = 0 Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = “Нет плана по графику “+Запись.Сотрудник+” “+Запись.ВидРасчета;
Сообщение.Сообщить();
Отказ = Истина;
Иначе
Результат = Выборка.База*Выборка.Факт/Выборка.БазаПлан;
КонецЕсли;
ИначеЕсли Выборка.СпособРасчета = Перечисления.СпособРасчета.Процент
ИЛИ Выборка.СпособРасчета = Перечисления.СпособРасчета.ПроцентЗаПрошлыйГод
ИЛИ Выборка.СпособРасчета = Перечисления.СпособРасчета.ПроцентПоРегистрации Тогда
Результат = Выборка.База*Выборка.Размер/100;
ИначеЕсли Выборка.СпособРасчета = Перечисления.СпособРасчета.Сумма Тогда
Результат = Выборка.База*Выборка.Размер/Выборка.План;
Иначе
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = “Вид расчета “+Запись.ВидРасчета+” без алгоритма расчета”;
Сообщение.Сообщить();
Отказ = Истина;
КонецЕсли;
Если НЕ Отказ Тогда
Запись.Результат = Результат*?(Запись.Сторно,-1,1);
КонецЕсли;
Иначе
//будем обходить все категории по очереди, и не всегда все они есть в Выборке = Отказ = Истина;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция ПолучитьСтруктуруНеобходимыхДанных(Выборка)
Параметры = Новый Структура;
Параметры.Вставить(“ДанныеГрафика”, Ложь);
Параметры.Вставить(“База”, Ложь);
Пока Выборка.Следующий() Цикл
Если Выборка.Способ = Перечисления.СпособРасчета.ПоОтработанномуВремени
ИЛИ Выборка.Способ = Перечисления.СпособРасчета.ПоЗП
ИЛИ Выборка.Способ = Перечисления.СпособРасчета.Процент Тогда
Параметры.ДанныеГрафика = Истина;
КонецЕсли;
Если Выборка.Способ = Перечисления.СпособРасчета.ПоЗП
ИЛИ Выборка.Способ = Перечисления.СпособРасчета.Процент Тогда
Параметры.База = Истина;
КонецЕсли;
КонецЦикла;
КонецФункции
Функция ЗаполнитьНачКонПериод(НачКонПериода, СпособРасчета) Экспорт
Если СпособРасчета = Перечисления.СпособРасчета.ПоОтработанномуВремени Тогда
НачКонПериода.БПН = НачалоДня(НачалоМесяца(ДобавитьМесяц(НачалоМесяца(НачКонПериода.БПН), -13)));
НачКонПериода.БПК = КонецДня(КонецМесяца(ДобавитьМесяц(НачалоМесяца(НачКонПериода.БПК), -1)));
Возврат Ложь;
ИначеЕсли СпособРасчета = Перечисления.СпособРасчета.УдержаниеЗаПрогул
ИЛИ СпособРасчета = Перечисления.СпособРасчета.ОплатаЗаДни Тогда
НачКонПериода.БПН = НачалоДня(НачКонПериода.БПН);
НачКонПериода.БПК = КонецДня(НачКонПериода.БПК);
Возврат Ложь;
ИначеЕсли СпособРасчета = Перечисления.СпособРасчета.поЗП Тогда
НачКонПериода.БПН = НачалоДня(НачалоМесяца(ДобавитьМесяц(НачалоМесяца(НачКонПериода.БПН), -13)));
НачКонПериода.БПК = КонецДня(КонецМесяца(ДобавитьМесяц(НачалоМесяца(НачКонПериода.БПК), -1)));
Возврат Ложь;
ИначеЕсли СпособРасчета = Перечисления.СпособРасчета.ПроцентПоРегистрации Тогда
НачКонПериода.БПН = НачалоДня(НачКонПериода.БПН);
НачКонПериода.БПК = Конецдня(КонецМесяца(НачКонПериода.БПН));
Возврат Ложь;
ИначеЕсли СпособРасчета = Перечисления.СпособРасчета.Процент Тогда
//квартал предыдущий считаем
КварталTmp = Месяц(НачКонПериода.БПН);
Если 1<=КварталTmp И КварталTmp<=3 Тогда
КварталН = 1;
ИначеЕсли 4<=КварталTmp И КварталTmp<=6 Тогда
КварталН = 4;
ИначеЕсли 7<=КварталTmp И КварталTmp<=9 Тогда
КварталН = 7;
Иначе
КварталН = 10;
КонецЕсли;
Год = Год(НачКонПериода.БПН);
НачКонПериода.БПН = ДобавитьМесяц(НачалоДня(Дата(Год, КварталН, 1)),-3);
НачКонПериода.БПК = Конецдня(КонецМесяца(ДобавитьМесяц(НачКонПериода.БПН,2)));
Возврат Ложь;
ИначеЕсли СпособРасчета = Перечисления.СпособРасчета.ПроцентЗаПрошлыйГод Тогда
НачКонПериода.БПК = КонецДня(КонецМесяца(НачалоГода(НачКонПериода.БПН)-1));
НачКонПериода.БПН = НачалоДня(НачалоМесяца(ДобавитьМесяц(НачалоГода(НачКонПериода.БПН), -12)));
Возврат Ложь;
Иначе
Возврат Истина;
КонецЕсли;
КонецФункции
Функция ПолучитьДанныеДляРасчетов(Параметры, ИмяРегистра, Ссылка, КатегорияРасчета)
Запрос = Новый Запрос;
Запрос.УстановитьПараметр(“Ссылка”, Ссылка);
Запрос.УстановитьПараметр(“КатегорияРасчета”, КатегорияРасчета);
Измерения = Новый Массив;
спецкат = Константы.КатегорияРасчетаДляНадбавкиРуководителю.Получить();
Если КатегорияРасчета<>Константы.КатегорияРасчетаДляНадбавкиРуководителю.Получить() Тогда
Измерения.Добавить(“Сотрудник”);
КонецЕсли;
Измерения.Добавить(“Подразделение”);
Запрос.УстановитьПараметр(“Измерения”, Измерения);
Если ИмяРегистра=”ОсновныеНачисления” Тогда
Запрос.Текст =
“ВЫБРАТЬ
| ОсновныеНачисления.НомерСтроки,
| ОсновныеНачисления.ВидРасчета.СпособРасчета КАК СпособРасчета,
| ЕСТЬNULL(ОсновныеНачисления.Размер, 0) КАК Размер,
| ЕСТЬNULL(ОсновныеНачисленияДанныеГрафика.РаботатьИлиНетПериодДействия, 0) КАК План,
| ЕСТЬNULL(ОсновныеНачисленияДанныеГрафика.РаботатьИлиНетФактическийПериодДействия, 0) КАК Факт,
| ЕСТЬNULL(ОсновныеНачисленияБазаДополнительныеНачисления.РезультатБаза, 0) + ЕСТЬNULL(ОсновныеНачисленияБазаОсновныеНачисления.РезультатБаза, 0) КАК База,
| ЕСТЬNULL(ОсновныеНачисленияДанныеГрафика.РаботатьИлиНетБазовыйПериод, 0) КАК БазаПлан
|ИЗ
| РегистрРасчета.ОсновныеНачисления КАК ОсновныеНачисления
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ОсновныеНачисления.БазаОсновныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК ОсновныеНачисленияБазаОсновныеНачисления
| ПО ОсновныеНачисления.НомерСтроки = ОсновныеНачисленияБазаОсновныеНачисления.НомерСтроки
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ОсновныеНачисления.БазаДополнительныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК ОсновныеНачисленияБазаДополнительныеНачисления
| ПО ОсновныеНачисления.НомерСтроки = ОсновныеНачисленияБазаДополнительныеНачисления.НомерСтроки
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ОсновныеНачисления.ДанныеГрафика(
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК ОсновныеНачисленияДанныеГрафика
| ПО ОсновныеНачисления.НомерСтроки = ОсновныеНачисленияДанныеГрафика.НомерСтроки
|ГДЕ
| ОсновныеНачисления.Регистратор = &Ссылка
| И ОсновныеНачисления.ВидРасчета.КатегорияРасчета = &КатегорияРасчета”
ИначеЕсли ИмяРегистра=”ДополнительныеНачисления” Тогда
Запрос.Текст =
“ВЫБРАТЬ
| ДополнительныеНачисления.НомерСтроки,
| ЕСТЬNULL(ДополнительныеНачисления.Размер, 0) КАК Размер,
| ДополнительныеНачисления.ВидРасчета.СпособРасчета КАК СпособРасчета,
| ЕСТЬNULL(ДополнительныеНачисленияБазаДополнительныеНачисления.РезультатБаза, 0) + ЕСТЬNULL(ДополнительныеНачисленияБазаОсновныеНачисления.РезультатБаза, 0) КАК База
|ИЗ
| РегистрРасчета.ДополнительныеНачисления КАК ДополнительныеНачисления
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисления.БазаОсновныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК ДополнительныеНачисленияБазаОсновныеНачисления
| ПО ДополнительныеНачисления.НомерСтроки = ДополнительныеНачисленияБазаОсновныеНачисления.НомерСтроки
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисления.БазаДополнительныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК ДополнительныеНачисленияБазаДополнительныеНачисления
| ПО ДополнительныеНачисления.НомерСтроки = ДополнительныеНачисленияБазаДополнительныеНачисления.НомерСтроки
|ГДЕ
| ДополнительныеНачисления.Регистратор = &Ссылка
| И ДополнительныеНачисления.ВидРасчета.КатегорияРасчета = &КатегорияРасчета”
Иначе
//Удержания
Запрос.Текст =
“ВЫБРАТЬ
| Удержания.НомерСтроки,
| Удержания.ВидРасчета.СпособРасчета,
| ЕСТЬNULL(Удержания.Размер, 0) КАК Размер,
| ЕСТЬNULL(УдержанияБазаДополнительныеНачисления.РезультатБаза, 0) + ЕСТЬNULL(УдержанияБазаОсновныеНачисления.РезультатБаза, 0) КАК База
|ИЗ
| РегистрРасчета.Удержания КАК Удержания
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.Удержания.БазаОсновныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК УдержанияБазаОсновныеНачисления
| ПО Удержания.НомерСтроки = УдержанияБазаОсновныеНачисления.НомерСтроки
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.Удержания.БазаДополнительныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК УдержанияБазаДополнительныеНачисления
| ПО Удержания.НомерСтроки = УдержанияБазаДополнительныеНачисления.НомерСтроки
|ГДЕ
| Удержания.Регистратор = &Ссылка
| И Удержания.ВидРасчета.КатегорияРасчета = &КатегорияРасчета”
КонецЕсли;
Возврат Запрос.Выполнить();
КонецФункции
</code>
Документ НачислениеЗП МО
<code>
Процедура ОбработкаПроведения(Отказ, Режим)
// регистр ОсновныеНачисления
Для Каждого ТекСтрокаНачисления Из Начисления Цикл
Движение = Движения.ОсновныеНачисления.Добавить();
Движение.Сторно = ТекСтрокаНачисления.Сторно;
Движение.ВидРасчета = ТекСтрокаНачисления.ВидРасчета;
Движение.Сотрудник = ТекСтрокаНачисления.Сотрудник;
Движение.Подразделение = ТекСтрокаНачисления.Подразделение;
Движение.ТипГрафика = ТекСтрокаНачисления.ТипГрафика;
Движение.ПериодРегистрации = ПериодРегистрации;
НачКонПериода = Новый Структура;
НачКонПериода.Вставить(“БПН”, ТекСтрокаНачисления.ДатаНачала);
НачКонПериода.Вставить(“БПК”, ТекСтрокаНачисления.ДатаОкончания);
Отказ = РасчетЗП.ЗаполнитьНачКонПериод(НачКонПериода, ТекСтрокаНачисления.ВидРасчета.СпособРасчета);
Если Отказ Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = “Неизвестный вид расчета “+ТекСтрокаНачисления.ВидРасчета;
Сообщение.Сообщить();
Иначе
Движение.БазовыйПериодНачало = НачКонПериода.БПН;
Движение.БазовыйПериодКонец = НачКонПериода.БПК;
КонецЕсли;
Движение.Размер = ТекСтрокаНачисления.Размер;
Движение.ПериодДействияНачало = ТекСтрокаНачисления.ДатаНачала;
Движение.ПериодДействияКонец = КонецДня(ТекСтрокаНачисления.ДатаОкончания);
КонецЦикла;
Если НЕ Отказ Тогда
// регистр Удержания
Для Каждого ТекСтрокаУдержания Из Удержания Цикл
Движение = Движения.Удержания.Добавить();
Движение.Сторно = ТекСтрокаУдержания.Сторно;
Движение.ВидРасчета = ТекСтрокаУдержания.ВидРасчета;
Движение.БазовыйПериодНачало = НачалоМесяца(ПериодРегистрации);
Движение.БазовыйПериодКонец = КонецМесяца(ПериодРегистрации);
Движение.Сотрудник = ТекСтрокаУдержания.Сотрудник;
Движение.Подразделение = ТекСтрокаУдержания.Подразделение;
Движение.Размер = ТекСтрокаУдержания.Размер;
КонецЦикла;
КонецЕсли;
Если НЕ Отказ Тогда
Движения.ОсновныеНачисления.Записать();
Движения.Удержания.Записать();
РасчетЗП.РасчитатьРегистрРасчета(Движения.ОсновныеНачисления, Отказ);
РасчетЗП.РасчитатьРегистрРасчета(Движения.Удержания, Отказ);
//РасчитатьНачисления(Отказ);
//РасчитатьУдержания(Отказ);
КонецЕсли;
КонецПроцедуры
</code>
<code>
</code>
<code>
</code>
Задание выполнил. Сделал универсальную обработку, как в уроках. Сложности были с надбавкой руководителю, пока не сообразил создать новый план видов расчета с зависимостью по периоду регистрации. В остальном проблем не было. При расчете базы для начисления руководителю получаю базу по всему отделу и вычитаю базу по самому сотруднику. Отчет на СКД тоже без затруднений.
По 4 блоку:
C расчетными задачами на практике сталкивался редко, поэтому с некоторым трудом давалась общая идеология. Но все разжевано максимально понятно просто требуется некоторая практика.
В качестве темы для мастер-группы можно было бы предложить еще какое-нибудь приложение расчетных механизмов кроме зарплаты (аренда, амортизация ОС …). Это позволило бы взглянуть на механизм с другой стороны.
Задание выполнил.
Наибольшие трудности возникли с распределением видов расчета по планам видов расчета. Также при обновлении базы долго боролся с неочень понятными сообщениями системы о неправильном наборе ведущих видов расчета.
Для премии ежемесячной создал отдельный план видов расчета “ДополнительныеНачисленияПоПериодуРегистрации”, с зависимостью по базе по периоду регистрации, а также отдельный регистр расчета.
Для премии ежемесячной присвоил категорию расчет – 1, для надбавки руководителю – 2
Модифицировал обработку проведения документа Начисление. Все делал по урокам.
//Общий модуль “РассчетНачислений”
<code>
Процедура РассчитатьРегистрРасчета(Набор, Отказ) Экспорт
Регистратор = Набор.Отбор.Регистратор.Значение;
ИмяРегистра = Набор.Метаданные().Имя;
Запрос = Новый Запрос;
Запрос.Текст =
“ВЫБРАТЬ
| ТекРегистрРасчета.ВидРасчета.КатегорияРасчета КАК КатегорияРасчета,
| ТекРегистрРасчета.ВидРасчета.СпособРасчета КАК СпособРасчета
|ИЗ
| РегистрРасчета.” + ИмяРегистра + ” КАК ТекРегистрРасчета
|ГДЕ
| ТекРегистрРасчета.Регистратор = &Регистратор
|УПОРЯДОЧИТЬ ПО
| ТекРегистрРасчета.Видрасчета.КатегорияРасчета
|ИТОГИ ПО
| ТекРегистрРасчета.ВидРасчета.КатегорияРасчета
|”;
Запрос.УстановитьПараметр(“Регистратор”, Регистратор);
Результат = Запрос.Выполнить();
ВыборкаКатегории = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока ВыборкаКатегории.Следующий() Цикл
ВыборкаСпособы = ВыборкаКатегории.Выбрать();
Параметры = ПолучитьСтруктуруНеобходимыхДанных(ВыборкаСпособы);
Результат = ПолучитьДанныеДляРасчета(Параметры, ИмяРегистра, Регистратор, ВыборкаКатегории.КатегорияРасчета);
ТаблицаДанныхДляРасчета = Результат.Выгрузить();
РассчитатьЗаписиРегистраРасчета(ТаблицаДанныхДляРасчета, Набор, Отказ);
Набор.Записать(, Истина);
КонецЦикла;
КонецПроцедуры
Функция ПолучитьСтруктуруНеобходимыхДанных(ВыборкаСпособы)
Параметры = Новый Структура();
Параметры.Вставить(“ДанныеГрафика”, Ложь);
Параметры.Вставить(“База”, Ложь);
Параметры.Вставить(“БазаПоПодразделению”, Ложь);
Пока ВыборкаСпособы.Следующий() Цикл
Если ВыборкаСпособы.СпособРасчета = Перечисления.СпособыРасчета.ПоОтработанномуВремени
ИЛИ ВыборкаСпособы.СпособРасчета = Перечисления.СпособыРасчета.ПроцентомПоСреднемуЗаработку
ИЛИ ВыборкаСпособы.СпособРасчета = Перечисления.СпособыРасчета.ФиксированнойСуммой Тогда
Параметры.ДанныеГрафика = Истина;
КонецЕсли;
Если ВыборкаСпособы.СпособРасчета = Перечисления.СпособыРасчета.ПроцентомПоСреднемуЗаработку
ИЛИ ВыборкаСпособы.СпособРасчета = Перечисления.СпособыРасчета.Процентом
ИЛИ ВыборкаСпособы.СпособРасчета = Перечисления.СпособыРасчета.ПроцентомПоЕжемесячнымПремиям Тогда
Параметры.База = Истина;
КонецЕсли;
Если ВыборкаСпособы.СпособРасчета = Перечисления.СпособыРасчета.ПроцентомПоЕжемесячнымПремиям Тогда
Параметры.БазаПоПодразделению = Истина;
КонецЕсли;
КонецЦикла;
Возврат Параметры;
КонецФункции
Функция ПолучитьДанныеДляРасчета(Параметры, ИмяРегистра, Регистратор, КатегорияРасчета)
Запрос = Новый Запрос;
Запрос.УстановитьПараметр(“Регистратор”, Регистратор);
МассивИзмерений = Новый Массив;
МассивИзмерений.Добавить(“Сотрудник”);
МассивИзмерений.Добавить(“Подразделение”);
Запрос.УстановитьПараметр(“Измерения”, МассивИзмерений);
Запрос.УстановитьПараметр(“КатегорияРасчета”, КатегорияРасчета);
Если ИмяРегистра = “ОсновныеНачисления” Тогда
Запрос.Текст =
“ВЫБРАТЬ
| ОсновныеНачисления.НомерСтроки,
| ОсновныеНачисления.ВидРасчета.СпособРасчета КАК СпособРасчета,
| ОсновныеНачисления.ПлановыйРазмер КАК ПлановыйРазмер”;
Если Параметры.ДанныеГрафика Тогда
Запрос.Текст = Запрос.Текст + ”
| ,ЕСТЬNULL(ОсновныеНачисленияДанныеГрафика.ЗначениеПериодДействия, 0) КАК ПланДней,
| ЕСТЬNULL(ОсновныеНачисленияДанныеГрафика.ЗначениеФактическийПериодДействия, 0) КАК ФактДней,
| ЕСТЬNULL(ОсновныеНачисленияДанныеГрафика.ЗначениеБазовыйПериод, 0) КАК БазаДней”;
КонецЕсли;
Если Параметры.База Тогда
Запрос.Текст = Запрос.Текст + ”
| ,ЕСТЬNULL(БазаОсновныеНачисления.РезультатБаза, 0) + ЕСТЬNULL(БазаДополнительныеНачисления.РезультатБаза, 0) КАК База”;
КонецЕсли;
Запрос.Текст = Запрос.Текст + ”
|ИЗ
| РегистрРасчета.ОсновныеНачисления КАК ОсновныеНачисления”;
Если Параметры.ДанныеГрафика Тогда
Запрос.Текст = Запрос.Текст + ”
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ОсновныеНачисления.ДанныеГрафика(Регистратор = &Регистратор И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК ОсновныеНачисленияДанныеГрафика
| ПО ОсновныеНачисления.НомерСтроки = ОсновныеНачисленияДанныеГрафика.НомерСтроки”;
КонецЕсли;
Если Параметры.База Тогда
Запрос.Текст = Запрос.Текст + ”
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ОсновныеНачисления.БазаОсновныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Регистратор
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК БазаОсновныеНачисления
| ПО ОсновныеНачисленияДанныеГрафика.НомерСтроки = БазаОсновныеНачисления.НомерСтроки
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ОсновныеНачисления.БазаДополнительныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Регистратор
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК БазаДополнительныеНачисления
| ПО ОсновныеНачисленияДанныеГрафика.НомерСтроки = БазаДополнительныеНачисления.НомерСтроки”;
КонецЕсли;
Запрос.Текст = Запрос.Текст + ”
|ГДЕ
| ОсновныеНачисления.Регистратор = &Регистратор
| И ОсновныеНачисления.ВидРасчета.КатегорияРасчета = &КатегорияРасчета
|”;
ИначеЕсли ИмяРегистра = “ДополнительныеНачисления” Тогда
Запрос.Текст =
“ВЫБРАТЬ
| ДополнительныеНачисления.НомерСтроки,
| ДополнительныеНачисления.ВидРасчета.СпособРасчета КАК СпособРасчета,
| ДополнительныеНачисления.ПлановыйРазмер”;
Если Параметры.База Тогда
Запрос.Текст = Запрос.Текст + ”
| ,ЕСТЬNULL(БазаОсновныеНачисления.РезультатБаза, 0) + ЕСТЬNULL(БазаДополнительныеНачисления.РезультатБаза, 0) + ЕСТЬNULL(БазаДополнительныеНачисленияПоПериодуРегистрации.РезультатБаза, 0) КАК База”;
КонецЕсли;
Если Параметры.БазаПоПодразделению Тогда
Запрос.Текст = Запрос.Текст + ”
| ,ЕСТЬNULL(БазаДополнительныеНачисленияПоПериодуРегистрацииПоПодразделению.РезультатБаза, 0) КАК БазаПоПодразделению”;
КонецЕсли;
Запрос.Текст = Запрос.Текст + ”
|ИЗ
| РегистрРасчета.ДополнительныеНачисления КАК ДополнительныеНачисления”;
Если Параметры.База Тогда
Запрос.Текст = Запрос.Текст + ”
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисления.БазаОсновныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Регистратор
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК БазаОсновныеНачисления
| ПО ДополнительныеНачисления.НомерСтроки = БазаОсновныеНачисления.НомерСтроки
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисления.БазаДополнительныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Регистратор
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК БазаДополнительныеНачисления
| ПО ДополнительныеНачисления.НомерСтроки = БазаДополнительныеНачисления.НомерСтроки
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисления.БазаДополнительныеНачисленияПоПериодуРегистрации(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Регистратор
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК БазаДополнительныеНачисленияПоПериодуРегистрации
| ПО ДополнительныеНачисления.НомерСтроки = БазаДополнительныеНачисленияПоПериодуРегистрации.НомерСтроки”;
КонецЕсли;
Если Параметры.БазаПоПодразделению Тогда
Запрос.Текст = Запрос.Текст + ”
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисления.БазаДополнительныеНачисленияПоПериодуРегистрации(
| “”Подразделение””,
| “”Подразделение””,
| ,
| Регистратор = &Регистратор
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК БазаДополнительныеНачисленияПоПериодуРегистрацииПоПодразделению
| ПО ДополнительныеНачисления.НомерСтроки = БазаДополнительныеНачисленияПоПериодуРегистрацииПоПодразделению.НомерСтроки”;
КонецЕсли;
Запрос.Текст = Запрос.Текст + ”
|ГДЕ
| ДополнительныеНачисления.Регистратор = &Регистратор
| И ДополнительныеНачисления.ВидРасчета.КатегорияРасчета = &КатегорияРасчета
|”;
ИначеЕсли ИмяРегистра = “ДополнительныеНачисленияПоПериодуРегистрации” Тогда
Запрос.Текст =
“ВЫБРАТЬ
| ДополнительныеНачисленияПоПериодуРегистрации.НомерСтроки,
| ДополнительныеНачисленияПоПериодуРегистрации.Видрасчета.СпособРасчета КАК Способрасчета,
| ДополнительныеНачисленияПоПериодуРегистрации.ПлановыйРазмер”;
Если Параметры.База Тогда
Запрос.Текст = Запрос.Текст + ”
| ,ЕСТЬNULL(БазаОсновныеНачисления.РезультатБаза, 0) + ЕСТЬNULL(БазаДополнительныеНачисления.РезультатБаза, 0) + ЕСТЬNULL(БазаДополнительныеНачисленияПоПериодуРегистрации.РезультатБаза, 0) КАК База”;
КонецЕсли;
Запрос.Текст = Запрос.Текст + ”
|ИЗ
| РегистрРасчета.ДополнительныеНачисленияПоПериодуРегистрации КАК ДополнительныеНачисленияПоПериодуРегистрации”;
Если Параметры.База Тогда
Запрос.Текст = Запрос.Текст + ”
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисленияПоПериодуРегистрации.БазаОсновныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Регистратор
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК БазаОсновныеНачисления
| ПО ДополнительныеНачисленияПоПериодуРегистрации.НомерСтроки = БазаОсновныеНачисления.НомерСтроки
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисленияПоПериодуРегистрации.БазаДополнительныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Регистратор
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК БазаДополнительныеНачисления
| ПО ДополнительныеНачисленияПоПериодуРегистрации.НомерСтроки = БазаДополнительныеНачисления.НомерСтроки
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисленияПоПериодуРегистрации.БазаДополнительныеНачисленияПоПериодуРегистрации(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Регистратор
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК БазаДополнительныеНачисленияПоПериодуРегистрации
| ПО ДополнительныеНачисленияПоПериодуРегистрации.НомерСтроки = БазаДополнительныеНачисленияПоПериодуРегистрации.НомерСтроки”;
КонецЕсли;
Запрос.Текст = Запрос.Текст + ”
|ГДЕ
| ДополнительныеНачисленияПоПериодуРегистрации.Регистратор = &Регистратор
| И ДополнительныеНачисленияПоПериодуРегистрации.ВидРасчета.КатегорияРасчета = &КатегорияРасчета
|”;
КонецЕсли;
Возврат Запрос.Выполнить();
КонецФункции
Процедура РассчитатьЗаписиРегистраРасчета(ТаблицаДанныхДляРасчета, Набор, Отказ)
Для Каждого Запись Из Набор Цикл
НайденнаяСтрока = ТаблицаДанныхДляРасчета.Найти(Запись.НомерСтроки, “НомерСтроки”);
Если НЕ ЗначениеЗаполнено(НайденнаяСтрока) тогда
Продолжить;
КонецЕсли;
Если НайденнаяСтрока.СпособРасчета = Перечисления.СпособыРасчета.ПоОтработанномуВремени Тогда
Если НайденнаяСтрока.ПланДней = 0 Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = “Не заполнен график.”;
Сообщение.Сообщить();
Отказ = Истина;
Иначе
Запись.Результат = НайденнаяСтрока.ФактДней*Запись.ПлановыйРазмер/НайденнаяСтрока.ПланДней;
КонецЕсли;
ИначеЕсли НайденнаяСтрока.СпособРасчета = Перечисления.СпособыРасчета.ФиксированнойСуммой Тогда
Запись.Результат = Запись.ПлановыйРазмер*НайденнаяСтрока.ФактДней;
ИначеЕсли НайденнаяСтрока.СпособРасчета = Перечисления.СпособыРасчета.ПроцентомПоСреднемуЗаработку Тогда
Если НайденнаяСтрока.БазаДней = 0 Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = “Не заполнен график за предыдущие 12 месяцев.”;
Сообщение.Сообщить();
Отказ = Истина;
Иначе
Запись.Результат = НайденнаяСтрока.ФактДней*НайденнаяСтрока.База/НайденнаяСтрока.БазаДней;
КонецЕсли;
ИначеЕсли НайденнаяСтрока.СпособРасчета = Перечисления.СпособыРасчета.Процентом Тогда
Запись.Результат = Запись.ПлановыйРазмер*НайденнаяСтрока.База/100;
ИначеЕсли НайденнаяСтрока.СпособРасчета = Перечисления.СпособыРасчета.ПроцентомПоЕжемесячнымПремиям Тогда
Запись.Результат = Запись.ПлановыйРазмер*(НайденнаяСтрока.БазаПоПодразделению-НайденнаяСтрока.База)/100;
Иначе
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = “Неизветный способ расчета – ” + Строка(Запись.СпособРасчета);
Сообщение.Сообщить();
Отказ = Истина;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
</code>
Отчет без затруднений.
//Текст запроса для отчета
<code>
ВЫБРАТЬ
ОсновныеНачисления.Сотрудник,
ОсновныеНачисления.Подразделение,
ОсновныеНачисления.ВидРасчета,
ОсновныеНачисления.Результат КАК Результат,
ОсновныеНачисления.ПериодДействия КАК Период
ИЗ
РегистрРасчета.ОсновныеНачисления КАК ОсновныеНачисления
ГДЕ
ОсновныеНачисления.ПериодДействия МЕЖДУ &ПериодНач И &ПериодКон
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
ДополнительныеНачисления.Сотрудник,
ДополнительныеНачисления.Подразделение,
ДополнительныеНачисления.ВидРасчета,
ДополнительныеНачисления.Результат,
ДополнительныеНачисления.ПериодРегистрации
ИЗ
РегистрРасчета.ДополнительныеНачисления КАК ДополнительныеНачисления
ГДЕ
ДополнительныеНачисления.ПериодРегистрации МЕЖДУ &ПериодНач И &ПериодКон
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
ДополнительныеНачисленияПоПериодуРегистрации.Сотрудник,
ДополнительныеНачисленияПоПериодуРегистрации.Подразделение,
ДополнительныеНачисленияПоПериодуРегистрации.ВидРасчета,
ДополнительныеНачисленияПоПериодуРегистрации.Результат,
ДополнительныеНачисленияПоПериодуРегистрации.ПериодРегистрации
ИЗ
РегистрРасчета.ДополнительныеНачисленияПоПериодуРегистрации КАК ДополнительныеНачисленияПоПериодуРегистрации
ГДЕ
ДополнительныеНачисленияПоПериодуРегистрации.ПериодРегистрации МЕЖДУ &ПериодНач И &ПериодКон
</code>
Обратная связь.
Про расчеты не знал абсолютно ничего. Поэтому все новое, все интересное, но несколько трудновато.
Хотелось бы увидеть несколько более подробное объяснение распределения видов расчета по планам видов расчета. Рассмотреть какие-нибудь сложные ситуации.
А также настройку ведущих видов расчета, т.к. система выдает не всегда понятные подсказки по этому поводу. В таких случаях приходится действовать “методом тыка”.
Да, забыл спросить.
Прошу прощения за оффтоп, но мои комментарии к обсуждению финального задания не добавляются. :(
К финальному заданию будут допущены все участники или вы огласите список?
Когда можно будет узнать о том, кого вы допустили а кого нет?
К финальному заданию допущены все участники.
Это странно, что не добавляется комментарий. Попробуйте добавить сейчас, возможно был временный сбой на сайте.
Если не получится – пишите на ящик мастер-группы подробное описание и скрин-шоты, будем разбираться.
Добрый день!
Даю обратную связь по блоку.
Нового узнал много. Самое важное – то, что уже знал, вплелось в то, что стало понятным впервые после прослушивания блока. Ну, или наоборот. :)
Чтобы вы ни говорили в начале изучения данного блока, Расчет – один из самых сложных кусков (модулей?) платформы. И спасибо вам за то, что помогли с ним разобраться.
Второе домашнее задание писал с большим скрипом, не раз возвращаясь к урокам, и даже (позор мне, позор) – подглядывал иногда в ваше решение (единственный случай за весь курс).
После такого мучительного выполнения второго домашнего задания третье, на удивление, решилось гораздо легче.
Отлично! :)
Задание выполнил. Прошу прощение за опоздание. Уезжал отдыхать :) Сделал без подглядывания в решение. Так увлекся заданием, что совсем забыл про время :)
Решение:
Определил способы расчета как перечисления, добавил туда следующие значения:
– ПоОтработанномуВремени (для оклада по дням);
– Невыход (для прогула);
– ОплатаПоСреднемуЗаработку (для отпуска);
– Процентом (для премии ежемесячной и по итогам года);
– ПроцентомОтДополнительныхНачислений (для надбавки для руководителя);
– СуммаОтВремени (для компенсации за обеды).
Сам алгоритм расчета сделал через динамический запрос, как было представлено в главе 14, через серверный привилегированный модуль. Есть только один нюанс :) Когда рассчитываем надбавку руководителя отдела, она рассчитывается в первую очередь, потому что для неё задана категория расчета 0, а для ежемесячной премии установлена категория 1, поэтому премия самого руководителя не попадает в расчет. А вот премии других сотрудников попадают, так как я оставил только одно измерение “Подразделение” И сам запрос:
<code>
Запрос.Текст=”ВЫБРАТЬ
| ДополнительныеНачисленияБазаДополнительныеНачисления.Сотрудник,
| ДополнительныеНачисленияБазаДополнительныеНачисления.Подразделение,
| ДополнительныеНачисленияБазаДополнительныеНачисления.РезультатБаза КАК База,
| ДополнительныеНачисленияБазаДополнительныеНачисления.НомерСтроки,
| ДополнительныеНачисленияБазаДополнительныеНачисления.Размер
|ИЗ
| РегистрРасчета.ДополнительныеНачисления.БазаДополнительныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &Категория) КАК ДополнительныеНачисленияБазаДополнительныеНачисления”;
Измерения.Очистить();
Измерения.Добавить(“Подразделение”);
Запрос.УстановитьПараметр(“Измерения”, Измерения);
</code>
А отчет сделал буквально за одну минуту;)
Ну и самое главное, обратная связь;)
1) Я узнал много нового, так как до этого вообще не работал с регистрами расчета. Материал составлен очень классно, что даже несмотря что я ничего не знал про РР, очень быстро в этой теме освоился:)
2) На мой взгляд материал составлен корректно, всё понятно изложено.
3) На мой взгляд в данной теме все вопросы раскрыты в рамках базового курса;)
Задание выполнила.
Создан новый ПВР “ДопНачисленияПоРегистрации” для расчетов “Премия ежемесячная” и “Надбавка руководителя отдела” с зависимостью по базе – по периоду регистрации. В качестве базовых ПВР выбраны Основные, Дополнительные и ДопНачисления.
Введен новый регистр расчета “ДопНачисленияПоРегистрации” с ПВР -“ДопНачисленияПоРегистрации”, V – базовый период, измерения Сотрудник и Подразделение, ресурсы – Результат, реквизиты – Размер.
Во все ПВР добавлен реквизит “СпособРасчета” (перечисление СпособыРасчета) и “Категория” (число).
В ПВР Основные и Дополнительные – новый ПВР добавлен в базовые.
В пользовательском режиме у существующих расчетов проставлено:
Оклад – способ – ПоОтработанномуВремени, категория 0.
Отпуск – способ – ПоСреднему, категория 0.
Прогул – способ – Прогул, категория 0.
Премия квартальная – способ – Процентом, категория 0.
Созданы новые виды расчета:
Премия по итогам года – дополнит начисление, способ расчета – Процентом, категория 0.
Компенсация за обеды – основное начисление, способ – ПоОтработанномуВремениПоТарифу, категория 0.
Премия ежемесячная – дополнит по регистрации, способ – Процентом, категория 1.
Надбавка руководителю отдела – дополнит по регистрации, способ – ПроцентомПоПодразделению, категория 2.
Внесены изменения в модуль документа “Начисление зарплаты”
————————————-
Процедура ОбработкаПроведения(Отказ, Режим)
Для Каждого ТекСтрокаНачисления Из Начисления Цикл
Если ТипЗнч(ТекСтрокаНачисления.ВидРасчета) = Тип(“ПланВидовРасчетаСсылка.ОсновныеНачисления”) Тогда
Движение = Движения.ОсновныеНачисления.Добавить();
Если ТекСтрокаНачисления.ВидРасчета.СпособРасчета = Перечисления.СпособыРасчета.ПоСреднему Тогда
Движение.ТипГрафика = Константы.Шестидневка.Получить();
Иначе
Движение.ТипГрафика = ТекСтрокаНачисления.ТипГрафика;
КонецЕсли;
Движение.ПериодДействияНачало = ТекСтрокаНачисления.ДатаНачала;
Движение.ПериодДействияКонец = КонецДня(ТекСтрокаНачисления.ДатаОкончания);
ИначеЕсли ТипЗнч(ТекСтрокаНачисления.ВидРасчета) = Тип(“ПланВидовРасчетаСсылка.ДополнительныеНачисления”) Тогда
Движение = Движения.ДополнительныеНачисления.Добавить();
ИначеЕсли ТипЗнч(ТекСтрокаНачисления.ВидРасчета) = Тип(“ПланВидовРасчетаСсылка.ДопНачисленияПоРегистрации”) Тогда
Движение = Движения.ДопНачисленияПоРегистрации.Добавить();
Иначе
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = “Алгоритм вида расчета “+ТекСтрокаНачисления.ВидРасчета+” не поддерживается”;
Сообщение.Сообщить();
Отказ = Истина;
Продолжить;
КонецЕсли;
Движение.ВидРасчета = ТекСтрокаНачисления.ВидРасчета;
Движение.ПериодРегистрации = ПериодРегистрации;
Движение.БазовыйПериодНачало = ТекСтрокаНачисления.БазовыйПериодНачало;
Движение.БазовыйПериодКонец = ТекСтрокаНачисления.БазовыйПериодКонец;
Движение.Сотрудник = ТекСтрокаНачисления.Сотрудник;
Движение.Подразделение = ТекСтрокаНачисления.Подразделение;
Движение.Размер = ТекСтрокаНачисления.Размер;
КонецЦикла;
Если НЕ Отказ Тогда
Движения.ОсновныеНачисления.Записать();
Движения.ДополнительныеНачисления.Записать();
Движения.ДопНачисленияПоРегистрации.Записать();
РасчетЗП.РассчитатьРегистрРасчета(Движения.ОсновныеНачисления, Отказ);
РасчетЗП.РассчитатьРегистрРасчета(Движения.ДополнительныеНачисления, Отказ);
РасчетЗП.РассчитатьРегистрРасчета(Движения.ДопНачисленияПоРегистрации, Отказ);
КонецЕсли;
КонецПроцедуры
====================================================================================
Общий модуль “РасчетЗП” согласно видео-урокам:
Измененные процедуры ниже
Процедура РассчитатьЗаписиРегистраРасчета(Выборка, Набор, Отказ)
Поиск = Новый Структура(“НомерСтроки”);
Для каждого Запись Из Набор Цикл
Поиск.НомерСтроки = Запись.НомерСтроки;
Выборка.Сбросить();
Если Выборка.НайтиСледующий(Поиск) Тогда
Если Выборка.Способ = Перечисления.СпособыРасчета.ПоОтработанномуВремени Тогда
Если Выборка.План=0 Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = “Нет данных графика”;
Сообщение.Сообщить();
Отказ = Истина;
КонецЕсли;
Результат = Выборка.Размер*Выборка.Факт/Выборка.План;
ИначеЕсли Выборка.Способ = Перечисления.СпособыРасчета.Прогул Тогда
Результат = 0;
ИначеЕсли Выборка.Способ = Перечисления.СпособыРасчета.ФиксированнойСуммой Тогда
Результат = Выборка.Размер;
ИначеЕсли Выборка.Способ = Перечисления.СпособыРасчета.Процентом Тогда
Результат = Выборка.Размер*Выборка.База/100;
ИначеЕсли Выборка.Способ = Перечисления.СпособыРасчета.ПроцентомПоПодразделению Тогда
Результат = Выборка.Размер*(Выборка.БазаПодразделение – Выборка.База)/100;
ИначеЕсли Выборка.Способ = Перечисления.СпособыРасчета.ПоСреднему Тогда
Если Выборка.БазаДней=0 Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = “Не заполнен график – “+Запись.ТипГрафика;
Сообщение.Сообщить();
Отказ = Истина;
КонецЕсли;
Результат = Выборка.База*Выборка.Факт/Выборка.БазаДней;
ИначеЕсли Выборка.Способ = Перечисления.СпособыРасчета.ПоОтработанномуВремениПоТарифу Тогда
Результат = Выборка.Размер*Выборка.Факт;
КонецЕсли;
Запись.Результат = Результат*?(Запись.Сторно, -1, 1);
КонецЕсли;
КонецЦикла;
КонецПроцедуры //РассчитатьЗаписиРегистраРасчета(Выборка, Набор, Отказ)
=============================================================
Функция ПолучитьСтруктуруНеобходимыхДанных(Выборка)
Параметры = Новый Структура;
Параметры.Вставить(“ДанныеГрафика”, Ложь);
Параметры.Вставить(“База”, Ложь);
Параметры.Вставить(“БазаПодразделения”, Ложь);
Пока Выборка.Следующий() Цикл
Если Выборка.Способ = Перечисления.СпособыРасчета.ПоОтработанномуВремени
ИЛИ Выборка.Способ = Перечисления.СпособыРасчета.Прогул
ИЛИ Выборка.Способ = Перечисления.СпособыРасчета.ПоОтработанномуВремениПоТарифу Тогда
Параметры.ДанныеГрафика = Истина;
ИначеЕсли Выборка.Способ = Перечисления.СпособыРасчета.Процентом Тогда
Параметры.База = Истина;
ИначеЕсли Выборка.Способ = Перечисления.СпособыРасчета.ПоСреднему Тогда
Параметры.ДанныеГрафика = Истина;
Параметры.База = Истина;
ИначеЕсли Выборка.Способ = Перечисления.СпособыРасчета.ПроцентомПоПодразделению Тогда
Параметры.БазаПодразделения = Истина;
Параметры.База = Истина;
КонецЕсли;
КонецЦикла;
Возврат Параметры;
КонецФункции // ПолучитьСтруктуруНеобходимыхДанных(Выборка)
=============================================================
Функция ПолучитьДанныеДляРасчета(Параметры, ИмяРегистра, Ссылка, КатегорияРасчета)
Запрос = Новый Запрос;
Запрос.УстановитьПараметр(“Ссылка”, Ссылка);
Измерения = Новый Массив;
Измерения.Добавить(“Подразделение”);
Измерения.Добавить(“Сотрудник”);
Запрос.УстановитьПараметр(“Измерения”, Измерения);
Если Параметры.БазаПодразделения = Истина тогда
ИзмеренияПодразделения = Новый Массив;
ИзмеренияПодразделения.Добавить(“Подразделение”);
Запрос.УстановитьПараметр(“ИзмеренияПодразделения”,ИзмеренияПодразделения);
КонецЕсли;
Запрос.УстановитьПараметр(“КатегорияРасчета”, КатегорияРасчета);
Если ИмяРегистра = “ОсновныеНачисления” Тогда …(как в видео-уроке)
ИначеЕсли ИмяРегистра = “ДополнительныеНачисления” Тогда …(как в видео-уроке)
ИначеЕсли ИмяРегистра = “ДопНачисленияПоРегистрации” Тогда
Запрос.Текст = “ВЫБРАТЬ
| ДопНачисленияПоРег.НомерСтроки КАК НомерСтроки,
| ДопНачисленияПоРег.Размер КАК Размер,
| ДопНачисленияПоРег.ВидРасчета.СпособРасчета КАК Способ”;
Если Параметры.База Тогда
Запрос.Текст = Запрос.Текст + ”
|,ЕСТЬNULL(БазаДопНачисленияПоРег.РезультатБаза, 0) + ЕСТЬNULL(БазаДополнительныеНачисленияПоРег.РезультатБаза, 0) + ЕСТЬNULL(БазаОсновныеНачисленияПоРег.РезультатБаза, 0) КАК База”;
КонецЕсли;
Если Параметры.БазаПодразделения Тогда
Запрос.Текст = Запрос.Текст + ”
|,ЕСТЬNULL(БазаДополнительныеНачисленияПоРегПодразделение.РезультатБаза, 0) + ЕСТЬNULL(БазаОсновныеНачисленияПоРегПодразделение.РезультатБаза, 0) + ЕСТЬNULL(БазаДопНачисленияПоРегПодразделение.РезультатБаза, 0) КАК БазаПодразделение”;
КонецЕсли;
Запрос.Текст = Запрос.Текст + ”
|ИЗ
| РегистрРасчета.ДопНачисленияПоРегистрации КАК ДопНачисленияПоРег”;
Если Параметры.База Тогда
Запрос.Текст = Запрос.Текст + ”
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДопНачисленияПоРегистрации.БазаДополнительныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК БазаДополнительныеНачисленияПоРег
| ПО ДопНачисленияПоРег.НомерСтроки = БазаДополнительныеНачисленияПоРег.НомерСтроки
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДопНачисленияПоРегистрации.БазаОсновныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК БазаОсновныеНачисленияПоРег
| ПО ДопНачисленияПоРег.НомерСтроки = БазаОсновныеНачисленияПоРег.НомерСтроки
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДопНачисленияПоРегистрации.БазаДопНачисленияПоРегистрации(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК БазаДопНачисленияПоРег
| ПО ДопНачисленияПоРег.НомерСтроки = БазаДопНачисленияПоРег.НомерСтроки”;
КонецЕсли;
Если Параметры.БазаПодразделения Тогда
Запрос.Текст = Запрос.Текст + ”
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДопНачисленияПоРегистрации.БазаДополнительныеНачисления(
| &ИзмеренияПодразделения,
| &ИзмеренияПодразделения,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК БазаДополнительныеНачисленияПоРегПодразделение
| ПО ДопНачисленияПоРег.НомерСтроки = БазаДополнительныеНачисленияПоРегПодразделение.НомерСтроки
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДопНачисленияПоРегистрации.БазаОсновныеНачисления(
| &ИзмеренияПодразделения,
| &ИзмеренияПодразделения,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК БазаОсновныеНачисленияПоРегПодразделение
| ПО ДопНачисленияПоРег.НомерСтроки = БазаОсновныеНачисленияПоРегПодразделение.НомерСтроки
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДопНачисленияПоРегистрации.БазаДопНачисленияПоРегистрации(
| &ИзмеренияПодразделения,
| &ИзмеренияПодразделения,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК БазаДопНачисленияПоРегПодразделение
| ПО ДопНачисленияПоРег.НомерСтроки = БазаДопНачисленияПоРегПодразделение.НомерСтроки”;
КонецЕсли;
Запрос.Текст = Запрос.Текст + ”
|ГДЕ
| ДопНачисленияПоРег.Регистратор = &Ссылка
| И ДопНачисленияПоРег.ВидРасчета.КатегорияРасчета = &КатегорияРасчета”;
КонецЕсли;
Возврат Запрос.Выполнить();
КонецФункции // ПолучитьДанныеДляРасчета(Параметры)
===========================================================================================
Отчет по начислениям не вызвал затруднений.
Обратная связь:
1.В 1с7 есть опыт работы с конфигурированием в расчете, но он был основан на самообразовании. Т.е. можно сказать был больше опыт расчетчика ЗП, чем программиста, знала что и куда. Здесь же получила именно теорию как организовать весь процесс с нуля.
2.Затруднения возникали только когда решались практические задания, а именно при построении запроса к определению Базы расчета.
Задание выполнил. Добавил категории и способы расчета в планы видов расчета. Реализовал универсальные алгоритмы, как в видео-уроках. Премию по итогам года и Компенсацию за обеды сделал. По двум другим видам расчета есть затруднения. Для надбавки руководителю не придумал как в универсальных алгоритмах обеспечить исключение своего начисления. Отчет создал.
Задание выполнил.
Добавил перечисление СпособыРасчета. В планах видов расчета добавил реквизиты КатегорияРасчета и СпособРасчета.
Создал общий модуль РасчетЗП. Скопировал код всех процедур и функций этого модуля.
Заполнил свойства видов расчета:
“Вид расчета” “Способ расчета” “Категория расчета”
“ОкладПоДням” “ПоОтработанномуВремени” “0”
“ПремияКвартальная” “Процентом” “1”
“Прогул” “НеОплачивается” “0”
“Отпуск” “ПоСреднеДневному” “0”
После немногочисленных правок все заработало кроме этого для способа “ПоСреднеДневному” пришлось добавить следующую строку в запрос в функцию ПолучитьДанныеДляРасчета
<code>
| ЕСТЬNULL(ОсновныеНачисленияДанныеГрафика.ЗначениеБазовыйПериод, 0) КАК БазаДней,
</code>
Добавил виды расчета:
“Вид расчета” “Способ расчета” “Категория расчета”
“ПремияПоИтогамГода” “Процентом” “2”
“ПремияЕжемесячная” “Процентом” “0”
“КомпенсацияЗаОбеды” “Компенсация” “0”
“НадбавкаРуководителю” “Надбавка” “99”
В “Надбавка” установил категорию расчета “99” и для этой категории
исключаем Измерения.Добавить(“Сотрудник”), добавляем оганичение в параметры виртуальных таблиц
<code>
| И Сотрудник <> &Сотрудник
</code>
и добавляем оганичение в условие физической таблицы
<code>
ДополнительныеНачисления.Сотрудник <> &Сотрудник
</code>
Сформировал отчет.
Раздел по расчету ЗП для меня новый. Евгений, спасибо за интересный и познавательный материал.
1. Задание выполнено, обработка проведения теперь универсальна, сложностей не было – так как делала по аналогии с описанием в 14 главе теории.
2. Добавлены новые способы расчета в соотв с заданием и формулы для них. По п 1-3 сложностей не было, по 4 – для расчета надбавки – добавлен еще один вид параметра запроса БазаПоПодразделению и дорабатывала текст универсального запроса для получения второго значения базы, но до конца отладить работоспособность не удалось, база все время возвращается нулевая, при этом заметила что БазовыйПериодНачало и Конец не заполнены для вирт таблицы ДополнительныеНачисленияБазаДополнительныеНачисления, Разобраться не смогла, буду ждать решения .
С отчетом сложностей не было.
ОбратнаяСвязь: ранее с понятием расчета не сталкивалась даже будучи пользователем – поэтому все абсолютно новое, тема показалась наиболее сложной.
Наибольшая сложность – невозможность пользоваться консолью для просмотра содержимого вирттаблиц для получения Базы
Задание выполнил. Добавил необходимые реквизиты в планы счетов и соответственно настроил виды расчетов. Сам расчет записей регистра расчетов выполнил немного по другому- без вложенного обхода способов расчета:
Процедура РассчитатьЗаписьРегистраРасчета(Запись,ДанныеДляРасчета)
СпособРасчета = Запись.ВидРасчета.СпособРасчета;
Результат = 0;
Факт = 0;
Если СпособРасчета = Перечисления.СпособыРасчета.Процентом ИЛИ СпособРасчета = Перечисления.СпособыРасчета.НадбавкаяРуководителюОтдела Тогда
Результат = ДанныеДляРасчета.База * Запись.Размер/100;
ИначеЕсли СпособРасчета = Перечисления.СпособыРасчета.ПоМесячнойТарифнойСтавкеПоДням Тогда
Норма = ДанныеДляРасчета.Норма;
Факт = ДанныеДляРасчета.Факт;
Если Норма > 0 Тогда
Результат = Запись.Размер * Факт /Норма;
КонецЕсли;
ИначеЕсли СпособРасчета = Перечисления.СпособыРасчета.ПоСреднемуЗаработку Тогда
Норма = ДанныеДляРасчета.Норма;
Если Норма > 0 Тогда
Результат = ДанныеДляРасчета.База * (((Запись.ПериодДействияКонец +1) – Запись.ПериодДействияНачало) /(24*60*60)) / Норма ;
КонецЕсли;
ИначеЕсли СпособРасчета = Перечисления.СпособыРасчета.ПоНулевойСумме Тогда
Результат = 0;
ИначеЕсли СпособРасчета = Перечисления.СпособыРасчета.СуммойЗаОтработанноеВремя Тогда
Результат = ДанныеДляРасчета.Факт * Запись.Размер;
КонецЕсли;
Запись.Результат = Результат;
КонецПроцедуры
Функция ПолучитьДанныеДляРасчета(ИмяРегистра,Запись)
СтруктураДанных = Новый Структура;
СпособРасчета = Запись.ВидРасчета.СпособРасчета;
Запрос = Новый Запрос;
Запрос.УстановитьПараметр(“Регистратор”,Запись.Регистратор);
Запрос.УстановитьПараметр(“НомерСтроки”,Запись.НомерСтроки);
ИзмеренияМассив = Новый Массив;
ИзмеренияМассив.Добавить(“Сотрудник”);
ИзмеренияМассив.Добавить(“Подразделение”);
Запрос.УстановитьПараметр(“Измерения”,ИзмеренияМассив);
Если ИмяРегистра = “ОсновныеНачисления” Тогда
// По месячной тарифной ставке по дням
Если СпособРасчета = Перечисления.СпособыРасчета.ПоМесячнойТарифнойСтавкеПоДням ИЛИ СпособРасчета = Перечисления.СпособыРасчета.СуммойЗаОтработанноеВремя Тогда
ТекстЗапроса =
“ВЫБРАТЬ
| ОсновныеНачисленияДанныеГрафика.ЗначениеПериодДействия КАК Норма,
| ОсновныеНачисленияДанныеГрафика.ЗначениеФактическийПериодДействия КАК Факт
|ИЗ
| РегистрРасчета.ОсновныеНачисления.ДанныеГрафика(
| Регистратор = &Регистратор
| И НомерСтроки = &НомерСтроки) КАК ОсновныеНачисленияДанныеГрафика”
;
Запрос.Текст = ТекстЗапроса;
ВыборкаЗапроса = Запрос.Выполнить().Выбрать();
Если ВыборкаЗапроса.Следующий() Тогда
СтруктураДанных.Вставить(“Норма”,ВыборкаЗапроса.Норма);
СтруктураДанных.Вставить(“Факт”,ВыборкаЗапроса.Факт);
Иначе
СтруктураДанных.Вставить(“Норма”,0);
СтруктураДанных.Вставить(“Факт”,0);
КонецЕсли;
// По среднему заработку
ИначеЕсли СпособРасчета = Перечисления.СпособыРасчета.ПоСреднемуЗаработку Тогда
ТекстЗапроса =
“ВЫБРАТЬ
| ЕСТЬNULL(ОсновныеНачисленияДанныеГрафика.ЗначениеБазовыйПериод, 0) КАК Норма,
| ЕСТЬNULL(ОсновныеНачисленияБазаОсновныеНачисления.РезультатБаза, 0) + ЕСТЬNULL(ОсновныеНачисленияБазаДополнительныеНачисления.РезультатБаза, 0) КАК База
|ИЗ
| РегистрРасчета.ОсновныеНачисления.ДанныеГрафика(
| Регистратор = &Регистратор
| И НомерСтроки = &НомерСтроки) КАК ОсновныеНачисленияДанныеГрафика
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ОсновныеНачисления.БазаОсновныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Регистратор
| И НомерСтроки = &НомерСтроки) КАК ОсновныеНачисленияБазаОсновныеНачисления
| ПО ОсновныеНачисленияДанныеГрафика.НомерСтроки = ОсновныеНачисленияБазаОсновныеНачисления.НомерСтроки
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ОсновныеНачисления.БазаДополнительныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Регистратор
| И НомерСтроки = &НомерСтроки) КАК ОсновныеНачисленияБазаДополнительныеНачисления
| ПО ОсновныеНачисленияДанныеГрафика.НомерСтроки = ОсновныеНачисленияБазаДополнительныеНачисления.НомерСтроки”
;
Запрос.Текст = ТекстЗапроса;
ВыборкаЗапроса = Запрос.Выполнить().Выбрать();
Если ВыборкаЗапроса.Следующий() Тогда
СтруктураДанных.Вставить(“Норма”,ВыборкаЗапроса.Норма);
СтруктураДанных.Вставить(“База”,ВыборкаЗапроса.База);
Иначе
СтруктураДанных.Вставить(“Норма”,0);
СтруктураДанных.Вставить(“База”,0);
КонецЕсли;
Иначе
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = “Неизвестный способ расчета”;
Сообщение.Сообщить();
КонецЕсли;
// Дополнительные начисления
ИначеЕсли ИмяРегистра = “ДополнительныеНачисления” Тогда
// Процентом от базы
Если СпособРасчета = Перечисления.СпособыРасчета.Процентом Тогда
ТекстЗапроса =
“ВЫБРАТЬ
| ЕСТЬNULL(ДополнительныеНачисленияБазаДополнительныеНачисления.РезультатБаза, 0) + ЕСТЬNULL(ДополнительныеНачисленияБазаОсновныеНачисления.РезультатБаза, 0) КАК База
|ИЗ
| РегистрРасчета.ДополнительныеНачисления.БазаДополнительныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = Регистратор
| И НомерСтроки = &НомерСтроки) КАК ДополнительныеНачисленияБазаДополнительныеНачисления
| ПОЛНОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисления.БазаОсновныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = Регистратор
| И НомерСтроки = &НомерСтроки) КАК ДополнительныеНачисленияБазаОсновныеНачисления
| ПО (ДополнительныеНачисленияБазаОсновныеНачисления.НомерСтроки = ДополнительныеНачисленияБазаДополнительныеНачисления.НомерСтроки)”
;
Запрос.Текст = ТекстЗапроса;
ВыборкаЗапроса = Запрос.Выполнить().Выбрать();
Если ВыборкаЗапроса.Следующий() Тогда
СтруктураДанных.Вставить(“База”,ВыборкаЗапроса.База);
Иначе
СтруктураДанных.Вставить(“База”,0);
КонецЕсли;
ИначеЕсли СпособРасчета = Перечисления.СпособыРасчета.НадбавкаяРуководителюОтдела Тогда
ТекстЗапроса =
“ВЫБРАТЬ
| ДополнительныеНачисленияБазаДополнительныеНачисления.РезультатБаза – ПремияЕжемесячная.Премия КАК База
|ИЗ
| РегистрРасчета.ДополнительныеНачисления.БазаДополнительныеНачисления(
| &ИзмПодразделение,
| &ИзмПодразделение,
| ,
| Регистратор = &Регистратор
| И НомерСтроки = &НомерСтроки
| И Подразделение = &Подразделение) КАК ДополнительныеНачисленияБазаДополнительныеНачисления
| ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
| ДополнительныеНачисления.Сотрудник КАК Сотрудник,
| ДополнительныеНачисления.Подразделение КАК Подразделение,
| ЕСТЬNULL(ДополнительныеНачисления.Результат, 0) КАК Премия
| ИЗ
| РегистрРасчета.ДополнительныеНачисления КАК ДополнительныеНачисления
| ГДЕ
| ДополнительныеНачисления.ВидРасчета = &ВидРасчета
| И ДополнительныеНачисления.ПериодРегистрации = &ПериодРегистрации
| И ДополнительныеНачисления.Сотрудник = &Сотрудник
| И ДополнительныеНачисления.Подразделение = &Подразделение) КАК ПремияЕжемесячная
| ПО ДополнительныеНачисленияБазаДополнительныеНачисления.Сотрудник = ПремияЕжемесячная.Сотрудник
| И ДополнительныеНачисленияБазаДополнительныеНачисления.Подразделение = ПремияЕжемесячная.Подразделение”;
Запрос.Текст = ТекстЗапроса;
ИзмПодразделение = Новый Массив;
ИзмПодразделение.Добавить(“Подразделение”);
Запрос.УстановитьПараметр(“ИзмПодразделение”,ИзмПодразделение);
Запрос.УстановитьПараметр(“Сотрудник”,Запись.Сотрудник);
Запрос.УстановитьПараметр(“Подразделение”,Запись.Подразделение);
Запрос.УстановитьПараметр(“ПериодРегистрации”,Запись.ПериодРегистрации);
Запрос.УстановитьПараметр(“ВидРасчета”,ПланыВидовРасчета.ДополнительныеНачисления.ПремияЕжемесячная);
ВыборкаЗапроса = Запрос.Выполнить().Выбрать();
Если ВыборкаЗапроса.Следующий() Тогда
СтруктураДанных.Вставить(“База”,ВыборкаЗапроса.База);
Иначе
СтруктураДанных.Вставить(“База”,0);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат СтруктураДанных;
КонецФункции
Процедура РассчитатьЗаписиНабора(НаборЗаписейРегистра,КатегорияРасчета,ТабЧастьДокумента);
ИмяРегистра = НаборЗаписейРегистра.Метаданные().Имя;
Для каждого Запись Из НаборЗаписейРегистра Цикл
Если Запись.ВидРасчета.КатегорияРасчета = КатегорияРасчета Тогда
ДанныеДляРасчета = ПолучитьДанныеДляРасчета(ИмяРегистра,Запись);
РассчитатьЗаписьРегистраРасчета(Запись,ДанныеДляРасчета);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
// Алгоритм обработки данных в цикле по категориям расчета
Процедура РассчитатьЗаписиРегистраРасчета(ИмяРегистра,НаборЗаписейРегистра,ТабЧастьДокумента)Экспорт
Если НаборЗаписейРегистра.Количество() = 0 Тогда Возврат КонецЕсли;
// Первоначальная запись набора с формированием фактического периода
НаборЗаписейРегистра.Записать(Истина,Ложь);
Регистратор = НаборЗаписейРегистра.Отбор.Регистратор.Значение;
ИмяПВР = Метаданные.РегистрыРасчета[ИмяРегистра].ПланВидовРасчета.Имя;
//1. Получить массив видов расчета из набора записей
ВидыРасчетаТабЗнач = НаборЗаписейРегистра.Выгрузить();
ВидыРасчетаТабЗнач.Свернуть(“ВидРасчета”);
ВидыРасчетаМассив = ВидыРасчетаТабЗнач.ВыгрузитьКолонку(“ВидРасчета”);
Запрос = Новый Запрос;
Запрос.Текст =
“ВЫБРАТЬ
| ПВР.КатегорияРасчета КАК КатегорияРасчета
|ИЗ
| ПланВидовРасчета.” + ИмяПВР + ” КАК ПВР
|ГДЕ
| ПВР.Ссылка В (&МассивВидовРасчета)
|
|УПОРЯДОЧИТЬ ПО
| ПВР.КатегорияРасчета.Порядок
|ИТОГИ ПО
| КатегорияРасчета”
;
Запрос.УстановитьПараметр(“МассивВидовРасчета”,ВидыРасчетаМассив);
ВыборкаКатегорий = Запрос.Выполнить().Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
//2.Обойти категории
Пока ВыборкаКатегорий.Следующий() Цикл
//ВыборкаСпособовРасчета = ВыборкаКатегорий.Выбрать();
//3.Расчить набор записей
РассчитатьЗаписиНабора(НаборЗаписейРегистра,ВыборкаКатегорий.КатегорияРасчета,ТабЧастьДокумента);
НаборЗаписейРегистра.Записать(,Истина);
КонецЦикла;
КонецПроцедуры
Создание отчета вопросов не вызвал.
Задание выполнил.
Привел аллгоритмы к универсальному виду с использованием динамического запроса.
Ежемесячную премию сделал через план видов расчета с зависимостью от базы по периоду регистрации, т.к. в задании написано “в текущем месяце”, долго мучился с запросом, он почему-то не хотел выбирать из таблицы с базой всех сотрудников, выбирал только тех, кто был указан в документе, но удалось обойти это. Получившийся запрос:
ВЫБРАТЬ
РегистрДополнительныхНачислений.НомерСтроки,
РегистрДополнительныхНачислений.ПлановыйРазмер,
РегистрДополнительныхНачислений.ВидРасчета.КатегорияРасчета,
РегистрДополнительныхНачислений.ВидРасчета.СпособРасчета
,(ЕСТЬNULL(РегистрДополнительныхНачисленийБазаРегистрДополнительныхНачислений.РезультатБаза, 0) + ЕСТЬNULL(РегистрДополнительныхНачисленийБазаРегистрОсновныхНачислений.РезультатБаза, 0) + ЕСТЬNULL(РегистрДополнительныхНачисленийБазаРегистрНачисленийПоРегистрации.РезультатБаза, 0)) КАК База,
(ЕСТЬNULL(ДополнительныеНачисленияПоПодразделению.РезультатБаза, 0)) КАК БазаПодразделения
ИЗ
РегистрРасчета.РегистрДополнительныхНачислений КАК РегистрДополнительныхНачислений
ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.РегистрДополнительныхНачислений.БазаРегистрДополнительныхНачислений(
&Измерения,
&Измерения,
,
Регистратор = &Ссылка) КАК РегистрДополнительныхНачисленийБазаРегистрДополнительныхНачислений
ПО РегистрДополнительныхНачислений.НомерСтроки = РегистрДополнительныхНачисленийБазаРегистрДополнительныхНачислений.НомерСтроки
ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.РегистрДополнительныхНачислений.БазаРегистрНачисленийПоРегистрации(
&Измерения,
&Измерения,
,
Регистратор = &Ссылка) КАК РегистрДополнительныхНачисленийБазаРегистрНачисленийПоРегистрации
ПО РегистрДополнительныхНачислений.НомерСтроки = РегистрДополнительныхНачисленийБазаРегистрНачисленийПоРегистрации.НомерСтроки
ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.РегистрДополнительныхНачислений.БазаРегистрОсновныхНачислений(
&Измерения,
&Измерения,
,
Регистратор = &Ссылка) КАК РегистрДополнительныхНачисленийБазаРегистрОсновныхНачислений
ПО РегистрДополнительныхНачислений.НомерСтроки = РегистрДополнительныхНачисленийБазаРегистрОсновныхНачислений.НомерСтроки
ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
СУММА(ЕСТЬNULL(вложенныйзапрос.РезультатБаза, 0)) КАК РезультатБаза,
Подразделения.Ссылка как Подразделение
ИЗ
Справочник.Подразделения КАК Подразделения
ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.РегистрДополнительныхНачислений.БазаРегистрНачисленийПоРегистрации(&Измерения, &Измерения, , ) КАК вложенныйзапрос
ПО (вложенныйзапрос.Подразделение = Подразделения.Ссылка)
СГРУППИРОВАТЬ ПО
Подразделения.Ссылка) КАК ДополнительныеНачисленияПоПодразделению
ПО РегистрДополнительныхНачислений.Подразделение = ДополнительныеНачисленияПоПодразделению.Подразделение
ГДЕ
РегистрДополнительныхНачислений.ВидРасчета.КатегорияРасчета = &КатегорияРасчета И
РегистрДополнительныхНачислений.Регистратор = &Ссылка
До этого очень мало сталкивался с расчетами, поэтому эта тема далась намного труднее предыдущих…
Задание выполнил.
Создано перечисление «СпособыРасчетаЗП». Значения перечисления – исходя из ДЗ № 14 и ДЗ № 15:
– ПоОтработанномуВремениДни;
– ПоСреднемуЗаработкуДляОтпуска;
– НулеваяСумма;
– ФиксированнойСуммой;
– Процентом.
Создан справочник «КатегорииРасчетов».
В справочник введены 2 предопределенных элемента:
– Первичное (код = «00000»);
– ЗависимоеПервогоУровня (код «00001»).
В планы видов расчета добавлены реквизиты:
– СпособРасчета;
– КатегорияРасчета.
В режиме 1С-Предприятия в планах видов расчета заполнены реквизиты «СпособРасчета» и «КатегорияРасчета».
При этом, согласно заданию, введены недостающие виды расчета.
Для оптимизации алгоритмов расчета регистров расчета – создан ряд функций и процедур, которые вынес в общий модуль «РасчетЗП»: http://paste.org.ru/?fdxckz
Создал отчет «ОтчетПоНачислениям».
Задание выполнила. Сделала универсальные алгоритмы как показано в видео уроках. Создала перечисление Способы Расчета и Категории Расчетов. Заполнила в пользовательском режиме. У надбавки руководителю категория расчета 2. настроила зависимости по базе согласно заданию. В структуре необходимых данных создала 3 параметра ДанныеГрафика,База,ОбщаяБаза. В зависимости от параметров строится динамический запрос. В дополнительных начисления таблицы по базе выбираются 2 раза в одном случае с параметрами измерения в другом подразделения, а также в одном случае выходное поле сумма баз по измерениям,а в другом сумма баз по подразделениям за минусом баз по измерениям. С отчетом проблем не возникло.
Задание выполнено.
Код сделан универсальным аналогично лекциям.
2 вида премий удалось сделать не меняя кода, с уже существующими видами расчета.
Компенсация за обед потребовала ввода дополнительного перечисления и незначительной корректировки кода.
С Надбавкой за руководство пришлось повозиться. Но результат по Базе у меня все равно выходит 0. Не найду в чем ошибка. Добавила новое перечисление и новый вид расчета, в Дополнительные начисления. Для него баз.вид расчета – ежемесячная премия. Категория его 1 (все остальные 0). В параметры для дальнейшего формирования запроса добавила параметр “толькоПодразделение”. Анализируя этот параметр к запросу по Доп начислениям присоединяю левым соединением таблицы ДополнительныеНачисления.БазаОсновныеНачисления и ДополнительныеНачисления.БазаДополнительныеНачисления. с измерениями по подразделениям. При расчете результат = (результатБазаПодразделения – результатБаза)* размер/100 получается 0.
после 1 цикла по категории виртуальная таблица дополнительныеНачисления.БазаДополнительныеНачисления по регистратору пустая. После второго цикла перед записью набора записей эта же таблица тоже пустая. Я так понимаю, что в нее должны были записаться сведения по ежемесячным премиям как базовые для расчета ДобавкиЗаРуководство. Не пойму в чем дело. Не найду ошибку.Оставила, посмотрю решение у вас.
Отчет по Начислениям выполнен.
Обратная связь. Практически все в этой теме новое. Очень понятно изложено, до этого не могла разобраться в регистрах расчета.
Учитывая то, что ежемесячная премия вычисляется по всем начислениям, СДЕЛАННЫМ В ТЕКУЩЕМ МЕСЯЦЕ, создан новый план видов расчета ДополнительныеНачисленияПР (Дополнительные начисления по периоду регистрации). Т. е. зависимость от базы в нем установлена по периоду регистрации. В базовые включены все планы видов расчета. Виды расчета Премия ежемесячная и Надбавка руководителю отдела включены в ПВР ДополнительныеНачисленияПР. В планы видов расчета ОсновныеНачисления и ДополнительныеНачисления в числе базовых включен и новый план ВР. Для обработки подобных видов расчета и хранения результатов расчета создан регистр расчета ДополнительныеНачисленияПР с установленной необходимостью использования базового периода и структурой, аналогичной регистру ДополнительныеНачисления.
Задаются следующие значения перечисления СпособыРасчета: ПоОтработаннымДням, ПоСреднемуЗаработку, Прогул, Процентом, ПоДневномуТарифу, ПроцентомПоПодразделению.
Алгоритмы расчета заработной платы находятся в модуле объекта документа НачислениеЗаработнойПлаты:
<code>
Процедура ОбработкаПроведения(Отказ, Режим)
Движения.ОсновныеНачисления.Записывать = Истина;
Движения.ДополнительныеНачисления.Записывать = Истина;
Движения.ДополнительныеНачисленияПР.Записывать = Истина;
Для Каждого ТекСтрокаНачисления Из Начисления Цикл
Если ТипЗнч(ТекСтрокаНачисления.ВидРасчета) = Тип(“ПланВидовРасчетаСсылка.ОсновныеНачисления”) Тогда
Движение = Движения.ОсновныеНачисления.Добавить();
Если ТекСтрокаНачисления.ВидРасчета = ПланыВидовРасчета.ОсновныеНачисления.Отпуск Тогда
Движение.ТипГрафика = Константы.Шестидневка.Получить();
Иначе
Движение.ТипГрафика = ТекСтрокаНачисления.ТипГрафика;
КонецЕсли;
Движение.ПериодДействияНачало = ТекСтрокаНачисления.ДатаНачала;
Движение.ПериодДействияКонец = ТекСтрокаНачисления.ДатаОкончания;
ИначеЕсли ТипЗнч(ТекСтрокаНачисления.ВидРасчета) = Тип(“ПланВидовРасчетаСсылка.ДополнительныеНачисления”) Тогда
Движение = Движения.ДополнительныеНачисления.Добавить();
ИначеЕсли ТипЗнч(ТекСтрокаНачисления.ВидРасчета) = Тип(“ПланВидовРасчетаСсылка.ДополнительныеНачисленияПР”) Тогда
Движение = Движения.ДополнительныеНачисленияПР.Добавить();
Иначе
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = “Алгоритм вида расчета “+ТекСтрокаНачисления.ВидРасчета+” не поддерживается”;
Сообщение.Сообщить();
Отказ = Истина;
Продолжить;
КонецЕсли;
Движение.Сотрудник = ТекСтрокаНачисления.Сотрудник;
Движение.Подразделение = ТекСтрокаНачисления.Подразделение;
Движение.ВидРасчета = ТекСтрокаНачисления.ВидРасчета;
Движение.ПериодРегистрации = ПериодРегистрации;
Движение.БазовыйПериодНачало = ТекСтрокаНачисления.БазовыйПериодНачало;
Движение.БазовыйПериодКонец = ТекСтрокаНачисления.БазовыйПериодКонец;
Движение.Размер = ТекСтрокаНачисления.Размер;
Движение.Сторно = ТекСтрокаНачисления.Сторно;
КонецЦикла;
Если НЕ Отказ Тогда
Движения.Записать();
РасчетЗП.РассчитатьРегистрРасчета(Движения.ОсновныеНачисления, Отказ);
РасчетЗП.РассчитатьРегистрРасчета(Движения.ДополнительныеНачисления, Отказ);
РасчетЗП.РассчитатьРегистрРасчета(Движения.ДополнительныеНачисленияПР, Отказ);
КонецЕсли;
КонецПроцедуры
</code>
и в общем модуле НачислениеЗП:
<code>
Процедура РассчитатьРегистрРасчета(Набор, Отказ) Экспорт
Ссылка = Набор.Отбор.Регистратор.Значение;
ИмяРегистра = Набор.Метаданные().Имя;
Запрос = Новый Запрос;
Запрос.Текст =
“ВЫБРАТЬ РАЗЛИЧНЫЕ
| ОсновныеНачисления.ВидРасчета.КатегорияРасчета КАК Категория,
| ОсновныеНачисления.ВидРасчета.СпособРасчета КАК Способ
|ИЗ
| РегистрРасчета.ОсновныеНачисления КАК ОсновныеНачисления
|ГДЕ
| ОсновныеНачисления.Регистратор = &Ссылка
|
|УПОРЯДОЧИТЬ ПО
| Категория
|ИТОГИ ПО
| Категория”;
Запрос.Текст = СтрЗаменить(Запрос.Текст, “ОсновныеНачисления”, ИмяРегистра);
Запрос.УстановитьПараметр(“Ссылка”, Ссылка);
Результат = Запрос.Выполнить();
ВыборкаКатегории = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока ВыборкаКатегории.Следующий() Цикл
ВыборкаСпособы = ВыборкаКатегории.Выбрать();
Параметры = ПолучитьСтруктуруНеобходимыхДанных(ВыборкаСпособы);
Результат = ПолучитьДанныеДляРасчета(Параметры, ИмяРегистра, Ссылка, ВыборкаКатегории.Категория);
Выборка = Результат.Выбрать();
РассчитатьЗаписиРегистраРасчета(Выборка, Набор, Отказ);
Набор.Записать( , Истина);
КонецЦикла;
КонецПроцедуры
Процедура РассчитатьЗаписиРегистраРасчета(Выборка, Набор, Отказ)
ПоОтработаннымДням = Перечисления.СпособыРасчета.ПоОтработаннымДням;
ПоСреднемуЗаработку = Перечисления.СпособыРасчета.ПоСреднемуЗаработку;
Прогул = Перечисления.СпособыРасчета.Прогул;
Процентом = Перечисления.СпособыРасчета.Процентом;
ПоДневномуТарифу = Перечисления.СпособыРасчета.ПоДневномуТарифу;
ПроцентомПоПодразделению = Перечисления.СпособыРасчета.ПроцентомПоПодразделению;
Поиск = Новый Структура(“НомерСтроки”);
Для каждого Запись Из Набор Цикл
Поиск.НомерСтроки = Запись.НомерСтроки;
Выборка.Сбросить();
Если Выборка.НайтиСледующий(Поиск) Тогда
Если Выборка.Способ = ПоОтработаннымДням Тогда
Если Выборка.ПланДней = 0 Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = “Не заполнен график – ” + Запись.ТипГрафика;
Сообщение.Сообщить();
Отказ = Истина;
Иначе
Результат = Запись.Размер * Выборка.ФактДней / Выборка.ПланДней;
КонецЕсли;
ИначеЕсли Выборка.Способ = ПоСреднемуЗаработку Тогда
Если Выборка.БазаДней = 0 Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = “Не заполнен график – ” + Запись.ТипГрафика;
Сообщение.Сообщить();
Отказ = Истина;
Иначе
Результат = Выборка.ФактДней * Выборка.База / Выборка.БазаДней;
КонецЕсли;
ИначеЕсли Выборка.Способ = Прогул Тогда
Результат = 0;
ИначеЕсли Выборка.Способ = Процентом Тогда
Результат = Выборка.База*Запись.Размер/100;
ИначеЕсли Выборка.Способ = ПоДневномуТарифу Тогда
Результат = Запись.Размер * Выборка.ФактДней;
ИначеЕсли Выборка.Способ = ПроцентомПоПодразделению Тогда
Результат = Запись.Размер * (Выборка.БазаПоПодразделению – Выборка.База) / 100;
КонецЕсли;
Запись.Результат = Результат * ?(Запись.Сторно, -1, 1);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция ПолучитьСтруктуруНеобходимыхДанных(Выборка)
Параметры = Новый Структура;
Параметры.Вставить(“ДанныеГрафика”, Ложь);
Параметры.Вставить(“База”, Ложь);
Параметры.Вставить(“БазаПоПодразделению”, Ложь);
Пока Выборка.Следующий() Цикл
Если Выборка.Способ = Перечисления.СпособыРасчета.ПоОтработаннымДням
Или Выборка.Способ = Перечисления.СпособыРасчета.ПоСреднемуЗаработку
Или Выборка.Способ = Перечисления.СпособыРасчета.Прогул
Или Выборка.Способ = Перечисления.СпособыРасчета.ПоДневномуТарифу Тогда
Параметры.ДанныеГрафика = Истина;
Если Выборка.Способ = Перечисления.СпособыРасчета.ПоСреднемуЗаработку Тогда
Параметры.База = Истина;
КонецЕсли;
ИначеЕсли Выборка.Способ = Перечисления.СпособыРасчета.Процентом Тогда
Параметры.База = Истина;
ИначеЕсли Выборка.Способ = Перечисления.СпособыРасчета.ПроцентомПоПодразделению Тогда
Параметры.База = Истина;
Параметры.БазаПоПодразделению = Истина;
КонецЕсли;
КонецЦикла;
Возврат Параметры;
КонецФункции // ПолучитьСтруктуруНеобходимыхДанных()
Функция ПолучитьДанныеДляРасчета(Параметры, ИмяРегистра, Ссылка, КатегорияРасчета)
Запрос = Новый Запрос;
Запрос.УстановитьПараметр(“Ссылка”, Ссылка);
Измерения = Новый Массив;
Измерения.Добавить(“Сотрудник”);
Измерения.Добавить(“Подразделение”);
Запрос.УстановитьПараметр(“Измерения”, Измерения);
Запрос.УстановитьПараметр(“КатегорияРасчета”, КатегорияРасчета);
Подразделение = Новый Массив;
Подразделение.Добавить(“Подразделение”);
Запрос.УстановитьПараметр(“Подразделение”, Подразделение);
Если ИмяРегистра = “ОсновныеНачисления” Тогда
Запрос.Текст = “ВЫБРАТЬ
| ОсновныеНачисления.НомерСтроки,
| ОсновныеНачисления.ВидРасчета.СпособРасчета КАК Способ,
| ОсновныеНачисления.Размер”;
Если Параметры.ДанныеГрафика Тогда
Запрос.Текст = Запрос.Текст + ”
| ,ЕСТЬNULL(ОсновныеНачисленияДанныеГрафика.ЗначениеПериодДействия, 0) КАК ПланДней,
| ЕСТЬNULL(ОсновныеНачисленияДанныеГрафика.ЗначениеФактическийПериодДействия, 0) КАК ФактДней,
| ЕСТЬNULL(ОсновныеНачисленияДанныеГрафика.ЗначениеБазовыйПериод, 0) КАК БазаДней”;
КонецЕсли;
Если Параметры.База Тогда
Запрос.Текст = Запрос.Текст + ”
| ,ЕСТЬNULL(ОсновныеНачисленияБазаОсновныеНачисления.РезультатБаза, 0) + ЕСТЬNULL(ОсновныеНачисленияБазаДополнительныеНачисления.РезультатБаза, 0) + ЕСТЬNULL(ОсновныеНачисленияБазаДополнительныеНачисленияПР.РезультатБаза, 0) КАК База”;
КонецЕсли;
Запрос.Текст = Запрос.Текст + ”
|ИЗ
| РегистрРасчета.ОсновныеНачисления КАК ОсновныеНачисления”;
Если Параметры.ДанныеГрафика Тогда
Запрос.Текст = Запрос.Текст + ”
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ОсновныеНачисления.ДанныеГрафика(
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК ОсновныеНачисленияДанныеГрафика
| ПО ОсновныеНачисления.НомерСтроки = ОсновныеНачисленияДанныеГрафика.НомерСтроки”;
КонецЕсли;
Если Параметры.База Тогда
Запрос.Текст = Запрос.Текст + ”
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ОсновныеНачисления.БазаОсновныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК ОсновныеНачисленияБазаОсновныеНачисления
| ПО ОсновныеНачисления.НомерСтроки = ОсновныеНачисленияБазаОсновныеНачисления.НомерСтроки
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ОсновныеНачисления.БазаДополнительныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК ОсновныеНачисленияБазаДополнительныеНачисления
| ПО ОсновныеНачисления.НомерСтроки = ОсновныеНачисленияБазаДополнительныеНачисления.НомерСтроки
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ОсновныеНачисления.БазаДополнительныеНачисленияПР(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК ОсновныеНачисленияБазаДополнительныеНачисленияПР
| ПО ОсновныеНачисления.НомерСтроки = ОсновныеНачисленияБазаДополнительныеНачисленияПР.НомерСтроки”;
КонецЕсли;
Запрос.Текст = Запрос.Текст + ”
|ГДЕ
| ОсновныеНачисления.Регистратор = &Ссылка
| И ОсновныеНачисления.ВидРасчета.КатегорияРасчета = &КатегорияРасчета”;
ИначеЕсли ИмяРегистра = “ДополнительныеНачисления” Тогда
Запрос.Текст = “ВЫБРАТЬ
| ДополнительныеНачисления.НомерСтроки,
| ДополнительныеНачисления.ВидРасчета.СпособРасчета КАК Способ,
| ДополнительныеНачисления.Размер”;
Если Параметры.База Тогда
Запрос.Текст = Запрос.Текст + ”
| ,ЕСТЬNULL(ДополнительныеНачисленияБазаОсновныеНачисления.РезультатБаза, 0) + ЕСТЬNULL(ДополнительныеНачисленияБазаДополнительныеНачисления.РезультатБаза, 0) + ЕСТЬNULL(ДополнительныеНачисленияБазаДополнительныеНачисленияПР.РезультатБаза, 0) КАК База”;
КонецЕсли;
Запрос.Текст = Запрос.Текст + ”
|ИЗ
| РегистрРасчета.ДополнительныеНачисления КАК ДополнительныеНачисления”;
Если Параметры.База Тогда
Запрос.Текст = Запрос.Текст + ”
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисления.БазаОсновныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК ДополнительныеНачисленияБазаОсновныеНачисления
| ПО ДополнительныеНачисления.НомерСтроки = ДополнительныеНачисленияБазаОсновныеНачисления.НомерСтроки
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисления.БазаДополнительныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК ДополнительныеНачисленияБазаДополнительныеНачисления
| ПО ДополнительныеНачисления.НомерСтроки = ДополнительныеНачисленияБазаДополнительныеНачисления.НомерСтроки
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисления.БазаДополнительныеНачисленияПР(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК ДополнительныеНачисленияБазаДополнительныеНачисленияПР
| ПО ДополнительныеНачисления.НомерСтроки = ДополнительныеНачисленияБазаДополнительныеНачисленияПР.НомерСтроки”;
КонецЕсли;
Запрос.Текст = Запрос.Текст + ”
|ГДЕ
| ДополнительныеНачисления.Регистратор = &Ссылка
| И ДополнительныеНачисления.ВидРасчета.КатегорияРасчета = &КатегорияРасчета”;
ИначеЕсли ИмяРегистра = “ДополнительныеНачисленияПР” Тогда
Запрос.Текст = “ВЫБРАТЬ
| ДополнительныеНачисленияПР.НомерСтроки,
| ДополнительныеНачисленияПР.ВидРасчета.СпособРасчета КАК Способ,
| ДополнительныеНачисленияПР.Размер”;
Если Параметры.База Тогда
Запрос.Текст = Запрос.Текст + ”
| ,ЕСТЬNULL(БазаОсновныеНачисления.РезультатБаза, 0) + ЕСТЬNULL(БазаДополнительныеНачисления.РезультатБаза, 0) + ЕСТЬNULL(БазаДополнительныеНачисленияПР.РезультатБаза, 0) КАК База”;
КонецЕсли;
Если Параметры.БазаПоПодразделению Тогда
Запрос.Текст = Запрос.Текст + ”
| ,ЕСТЬNULL(БазаОсновныеНачисленияПодразделение.РезультатБаза, 0) + ЕСТЬNULL(БазаДополнительныеНачисленияПодразделение.РезультатБаза, 0) + ЕСТЬNULL(БазаДополнительныеНачисленияПРПодразделение.РезультатБаза, 0) КАК БазаПоПодразделению”;
КонецЕсли;
Запрос.Текст = Запрос.Текст + ”
|ИЗ
| РегистрРасчета.ДополнительныеНачисленияПР КАК ДополнительныеНачисленияПР”;
Если Параметры.База Тогда
Запрос.Текст = Запрос.Текст + ”
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисленияПР.БазаОсновныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК БазаОсновныеНачисления
| ПО ДополнительныеНачисленияПР.НомерСтроки = БазаОсновныеНачисления.НомерСтроки
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисленияПР.БазаДополнительныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК БазаДополнительныеНачисления
| ПО ДополнительныеНачисленияПР.НомерСтроки = БазаДополнительныеНачисления.НомерСтроки
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисленияПР.БазаДополнительныеНачисленияПР(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК БазаДополнительныеНачисленияПР
| ПО ДополнительныеНачисленияПР.НомерСтроки = БазаДополнительныеНачисленияПР.НомерСтроки”;
КонецЕсли;
Если Параметры.БазаПоПодразделению Тогда
Запрос.Текст = Запрос.Текст + ”
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисленияПР.БазаОсновныеНачисления(
| &Подразделение,
| &Подразделение,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК БазаОсновныеНачисленияПодразделение
| ПО ДополнительныеНачисленияПР.НомерСтроки = БазаОсновныеНачисленияПодразделение.НомерСтроки
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисленияПР.БазаДополнительныеНачисления(
| &Подразделение,
| &Подразделение,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК БазаДополнительныеНачисленияПодразделение
| ПО ДополнительныеНачисленияПР.НомерСтроки = БазаДополнительныеНачисленияПодразделение.НомерСтроки
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисленияПР.БазаДополнительныеНачисленияПР(
| &Подразделение,
| &Подразделение,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК БазаДополнительныеНачисленияПРПодразделение
| ПО ДополнительныеНачисленияПР.НомерСтроки = БазаДополнительныеНачисленияПРПодразделение.НомерСтроки”;
КонецЕсли;
Запрос.Текст = Запрос.Текст + ”
|ГДЕ
| ДополнительныеНачисленияПР.Регистратор = &Ссылка
| И ДополнительныеНачисленияПР.ВидРасчета.КатегорияРасчета = &КатегорияРасчета”;
КонецЕсли;
Возврат Запрос.Выполнить();
КонецФункции // ПолучитьДанныеДляРасчета()
</code>
Вид расчета (ВР) Компенсация за обеды включен в ПВР ОсновныеНачисления. Способ расчета (СР) у него ПоДневномуТарифу. Категория расчета (КР) у всех ВР из основных начислений нулевая.
У ВР Премия квартальная и Премия по итогам года из ПВР ДополнительныеНачисления СР установлен в значение Процентом. КР квартальной премии – 0, премии по итогам года – 1.
Премия ежемесячная: СР – Процентом, КР = 0. Надбавка руководителю отдела: СР – ПроцентомПоПодразделению, КР = 1. Два последних ВР, как было указано выше, находятся в ПВР ДополнительныеНачисленияПР (Дополнительные начисления по периоду регистрации).
Вопрос в догонку, уж очень хотелось воспользоваться имеющимся динамическим запросом по «ДополнительнымНачислениям» в место нового Запроса с объединением двух таблиц и завернутого во Вложенный запрос, для расчета «Надбавки», пытался так – определил массив из одного измерения «Подразделение», передавал в запрос параметр Сотрудник, который проверял в условии в параметрах виртуальных таблиц БазаДополнительныеНачисления и БазаОсновныеНачисления, вот так
<code>| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисления.БазаДополнительныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Ссылка
| Сотрудник <> &Сотрудник
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК ДополнительныеНачисленияБазаДополнительныеНачисления
| ПО ДополнительныеНачисления.НомерСтроки = ДополнительныеНачисленияБазаДополнительныеНачисления.НомерСтроки </code>
В случае Сотрудник = Справочники.Сотрудники.ПустаяСсылка() возвращалась база по Подразделению, а вот базу без этого Сотрудника так извлечь не удалось. В чем моя ошибка?
К сожалению, не получится сделать задуманное и вот почему.
Условие накладывается на записи, для которых нужно рассчитать базу. Оно не применяется к записям, образующим базу.
Отчет ДЗ №15
Созданы:
Перечисление «СпособыРасчета» (ПоМесячнойТарифнойСтавке, НулеваяСумма, ПоСреднемуЗаработкуДляОтпуска, Процентом, КомпенсацияЗаОбед, Надбавка)
Реквизиты «СпособРасчета» и «КатегорияРасчета» в планах расчета.
В пользовательском режиме добавлены виды расчета в «Основные начисления» – «Компенсация за обед», остальные в «Дополнительные».
«Премия ежемесячная» получила категорию 1, «Надбавка» – категорию 2.
«Компенсация за обед» вытесняется Отпуском и Прогулом.
Для «Надбавки» базовый вид расчета «Премия ежемесячная»
Для остальных премий, база все имеющиеся начисления.
Алгоритмы модифицировал как учили в Главе 14. Универсальные алгоритмы.
Для расчета «Надбавки»
В структуру Параметры функции ПолучитьСтруктуруНеобходимыхДанных() добавил параметр «БазаПоПодразделению», далее в функции ПолучитьДанныеДляРасчета() вот так обработал
<code>Если Параметры.БазаПоПодразделению Тогда
Измерения1 = Новый Массив;
Измерения1.Добавить(“Подразделение”);
Запрос.УстановитьПараметр(“Измерения1”, Измерения1);
КонецЕсли;</code>
При формировании Запроса по «ДополнительнымНачислениям», делаю проверку и пускаю алгоритм по другой ветке, в которой и формирую базу для расчета «Надбавки»
<code>ИначеЕсли Параметры.БазаПоПодразделению Тогда
Запрос.Текст =
“ВЫБРАТЬ
| ВложенныйЗапрос.НомерСтроки,
| ВложенныйЗапрос.ВидРасчетаСпособРасчета КАК Способ,
| ВложенныйЗапрос.Размер,
| СУММА(ВложенныйЗапрос.База) КАК База
|ИЗ
| (ВЫБРАТЬ
| ДополнительныеНачисления.НомерСтроки КАК НомерСтроки,
| ДополнительныеНачисления.ВидРасчета.СпособРасчета КАК ВидРасчетаСпособРасчета,
| ДополнительныеНачисления.Размер КАК Размер,
| -1 * (ЕСТЬNULL(ДополнительныеНачисленияБазаОсновныеНачисления.РезультатБаза, 0) + ЕСТЬNULL(ДополнительныеНачисленияБазаДополнительныеНачисления.РезультатБаза, 0)) КАК База
| ИЗ
| РегистрРасчета.ДополнительныеНачисления КАК ДополнительныеНачисления
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисления.БазаДополнительныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК ДополнительныеНачисленияБазаДополнительныеНачисления
| ПО ДополнительныеНачисления.НомерСтроки = ДополнительныеНачисленияБазаДополнительныеНачисления.НомерСтроки
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисления.БазаОсновныеНачисления(
| &Измерения,
| &Измерения,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК ДополнительныеНачисленияБазаОсновныеНачисления
| ПО ДополнительныеНачисления.НомерСтроки = ДополнительныеНачисленияБазаОсновныеНачисления.НомерСтроки
| ГДЕ
| ДополнительныеНачисления.Регистратор = &Ссылка
| И ДополнительныеНачисления.ВидРасчета.КатегорияРасчета = &КатегорияРасчета
|
| ОБЪЕДИНИТЬ ВСЕ
|
| ВЫБРАТЬ
| ДополнительныеНачисления.НомерСтроки,
| ДополнительныеНачисления.ВидРасчета.СпособРасчета,
| ДополнительныеНачисления.Размер,
| ЕСТЬNULL(ДополнительныеНачисленияБазаОсновныеНачисления.РезультатБаза, 0) + ЕСТЬNULL(ДополнительныеНачисленияБазаДополнительныеНачисления.РезультатБаза, 0)
| ИЗ
| РегистрРасчета.ДополнительныеНачисления КАК ДополнительныеНачисления
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисления.БазаДополнительныеНачисления(
| &Измерения1,
| &Измерения1,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК ДополнительныеНачисленияБазаДополнительныеНачисления
| ПО ДополнительныеНачисления.НомерСтроки = ДополнительныеНачисленияБазаДополнительныеНачисления.НомерСтроки
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисления.БазаОсновныеНачисления(
| &Измерения1,
| &Измерения1,
| ,
| Регистратор = &Ссылка
| И ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК ДополнительныеНачисленияБазаОсновныеНачисления
| ПО ДополнительныеНачисления.НомерСтроки = ДополнительныеНачисленияБазаОсновныеНачисления.НомерСтроки
| ГДЕ
| ДополнительныеНачисления.Регистратор = &Ссылка
| И ДополнительныеНачисления.ВидРасчета.КатегорияРасчета = &КатегорияРасчета) КАК ВложенныйЗапрос
|
|СГРУППИРОВАТЬ ПО
| ВложенныйЗапрос.НомерСтроки,
| ВложенныйЗапрос.ВидРасчетаСпособРасчета,
| ВложенныйЗапрос.Размер”;
КонецЕсли; </code>
В Процедуре РассчитатьЗаписиРегистраРасчета() реализовал вот такие ветки
<code>Если Выборка.Способ = Перечисления.СпособРасчета.ПоМесячнойТарифнойСтавкеПоДням Тогда
…
ИначеЕсли Выборка.Способ = Перечисления.СпособРасчета.НулеваяСумма Тогда
…
ИначеЕсли Выборка.Способ = Перечисления.СпособРасчета.ПоСреднемуЗаработкуДляОтпуска Тогда
..
ИначеЕсли Выборка.Способ = Перечисления.СпособРасчета.КомпенсацияЗаОбед Тогда
…
ИначеЕсли Выборка.Способ = Перечисления.СпособРасчета.Процентом
ИЛИ Выборка.Способ = Перечисления.СпособРасчета.Надбавка Тогда
…
КонецЕсли;</code>
Отчет изготовил компоновкой, выходная форма таблица.
Всем доброго времени суток!
Представляю отчёт по пятнадцатому домашнему заданию.
В связи с неприлично большими объёмами кода, постараюсь ограничиться общим описанием получившегося решения.
В планы видов расчёта добавил реквизиты СпособРасчета, КатегорияРасчета и БазовыйПериод (последний – типа Число, для указания количества месяцев, за которые выбирается база). В табличную часть документа НачислениеЗП добавил реквизит БазовыйПериод (так же типа Число), который заполняется автоматически при выборе вида расчёта, в соответствии со значением одноимённого реквизита вида расчёта.
Модифицировал алгоритм заполнения плановых данных регистров расчёта, в случае, если в виде расчёта значение базового периода не установлено – базовый период заполняется как месяц периода регистрации, в остальных случаях от месяца регистрации отнимется количество месяцев базового периода.
Создал перечисление СпособыРасчета, в котором указал значения: ПоОтработанномуВремени, ПоСреднемуЗаработку, Прогул, Процентом и на будущее – ФиксированныйРазмер. Адаптировал алгоритм универсального расчёта из уроков под условия задачи. Проверил – проведение работает, значения рассчитываются как прежде.
В пользовательском режиме создал новые виды расчёта. Ежемесячная и годовая премии запустились без вмешательства в уже написанные алгоритмы, обе завёл в дополнительных начислениях, способ расчёта указал Процентом, для ежемесячной премии базовый период не указываю, базу для обоих видов расчёта установил как все начисления. (ну не очень это правильно на мой взгляд, премии начислять сами на себя и перекрёстно друг на друга, равно как и средний заработок на средний заработок – в случае с отпускными).
Для расчёта компенсаций за обеды создал дополнительный способ расчёта – Компенсация. Сам вид расчёта отнёс к основным, поскольку по смыслу нужен фактический период действия. Базы соответственно нет, рассчитывается по формуле: ПлановыйРазмер * ФактическийПД. Внёс соответствующие изменения в алгоритм расчёта и дополнил условие в записи плановых данных.
Больше всего времени ушло на решение четвёртого вида расчёта – Надбавку руководителю отдела. “При этом должности сотрудников хранить не требуется. Считается, что расчет сам укажет для руководителя требуемый вид расчета.” Не совсем понял данное условие, поэтому никаких дополнительных требований у меня нет. Расчёт данной надбавки производится при указании в табличной части соответствующего вида расчёта.
Для реализации расчёта пришлось создать дополнительный параметр в функции ПолучитьСтруктуруНеобходимыхДанных общего модуля РасчетЗП, назвал его – ЗаПодразделение. Кроме того, в перечислении СпособыРасчета добавил значение ПоПодразделению. Так как вид расчёта был отнесён мной к дополнительным начислениям – в процедуре формирования динамического запроса по дополнительным начислениям добавил условие на проверку параметра ЗаПодразделение и добавление поля выборки, а так же двух левых соединений виртуальных таблиц с данными базы. Формула расчёта аналогична формуле для способа расчёта Процентом, с поправкой на условия задачи. В запросе поле выборки для расчёта базы по данному виду расчёта выглядит следующим образом:
| ,(ЕСТЬNULL(ДополнительныеНачисленияБазаОсновныеНачисленияПодразделения.РазмерБаза, 0) + ЕСТЬNULL(ДополнительныеНачисленияБазаДополнительныеНачисленияПодразделения.РазмерБаза, 0)) - (ЕСТЬNULL(ДополнительныеНачисленияБазаДополнительныеНачисления.РазмерБаза, 0) + ЕСТЬNULL(ДополнительныеНачисленияБазаОсновныеНачисления.РазмерБаза, 0)) КАК БазаПодразделения";
В качестве измерений для виртуальной таблицы ДополнительныеНачисленияБазаОсновныеНачисленияПодразделения указывается только подразделение, для виртуальной таблицы ДополнительныеНачисленияБазаОсновныеНачисления – сотрудник и подразделение. При проверке расчёта – ошибок не было.
С отчётом по начислениям проблем не возникло, единственное – в отличии от скриншота в задании – у меня не сворачивается группировка по дате, где такое настроить – не нашёл. Подожду решения.
В уроке “Разработка универсальных запросов для дополнительных начислений и удержаний” (Block4-Chapter14-lesson18-add.exe, в районе 3:49), в итоговом тексте запроса по всей видимости – ошибка, так как первое соединение – ЛЕВОЕ, а второе – ВНУТРЕННЕЕ. Хотя на сколько я помню – заметных ошибок это не вызвало.
Спасибо, это ошибка, которая может привести к расчету неправильного результата.
Обратная связь по четвёртому блоку.
1) Общее представление о расчётах в 8.2 я уже имел, после изучения материалов 4-го блока я понял – на сколько общим было это представление )))) Можно сказать – всё изучал заново.
2) Трудности были только в самом начале, когда материал стал подаваться быстро, в конфигурации Евгения уже были какие-то заготовки, трудно было сразу уловить взаимосвязь между объектами расчёта, что на что влияет… Помогло со всем разобраться – выполнение домашних заданий. Считаю, что теперь стал ориентироваться в объектах достаточно, чтоб разобраться что к чему.
3) Даже затрудняюсь что-то придумать, вроде бы непонятных вопросов в рамках базового курса не осталось.
Евгений, у меня вопрос, в продолжение заданного после 14-го ДЗ. Снова по поводу различных базовых периодов для видов расчётов, находящихся в одном плане видов расчётов.
В ходе выполнения 15-го ДЗ я попытался реализовать механизм, описанный в предыдущем ответе. Если не трудно – хотелось бы услышать Ваше мнение: правильно ли получилось, или возможны проблемы в будущем?
Описание механизма приведена в начале отчёта по данному ДЗ, здесь приведу кусочек кода, отвечающий за заполнение базового периода:
<code>
Движение.БазовыйПериодНачало = ДобавитьМесяц(ПериодРегистрации, -ТекСтрокаНачисление.БазовыйПериод);
Если ТекСтрокаНачисление.БазовыйПериод > 0 Тогда
Движение.БазовыйПериодКонец = ПериодРегистрации – 1;
Иначе
Движение.БазовыйПериодКонец = КонецМесяца(ПериодРегистрации);
КонецЕсли;
</code>
могу добавить, что период регистрации автоматически приводится к началу заданного месяца (от даты указанной в реквизите документа Расчётный период).
Проблем в коде не вижу, все должно работать корректно.
Спасибо
Задание выполнено проблем не возникло.
Добавил способ и категорию расчета, алгоритмы постравнению с 14 ДЗ менять сильно не пришлось, т.к. делал сразу универсально :)
По отчету:
1. Небыло практики реализации расчетных задач с “нуля”, поэтому блок очень полезен.
2. затруднений небыло
3. все вопросы которые возникли рассатриваются в продвинутом курсе, т.е. в рамках данного курса вопросов нет
Задание выполнила.
http://fotoifolder.ru/view_full_size/fyd3qa5fu__k
http://fotoifolder.ru/view_full_size/umc8opp2y40b
Задание выполнил. Уроки взял как практически пошаговую инструкцию к реализации.
Отчет в СКД больших трудностей не вызывает.
Обратная связь: Нового узнал-все.
Так как компонента Расчет мне была совсем неизвестна (даже в 7.7) по-началу были проблемы с понимаем материала. Даже приходили мысли что не справлюсь. Но благодаря
более детальному изучению материала все вставало на свои места. Очень хорошо что ДЗ не сильно отличались от того что говорится в уроках
Иначе бы было тяжело. Мне кажется материал изложен просто прекрасно . Большое спасибо.
Задание выполнено.
Модуль доработан аналогично описанному в курсе. Для расчета надбавки руководителю сделан дополнительный запрос для расчета премии по всему подразделению, выполняемый при расчете надбавки по сотруднику. Результат равен разнице между расчетом по подразделению и расчетом по сотруднику. Отчет сделан с помощью СКД
Добрый день!
В уроке “Обход способов расчета текущей категории” структура значений перечисления наполняется с помощью функции СтрЗаменить().
Мне кажется, что тут лучше подойдет функция XMLСтрока().
Спасибо, это действительно более красивое решение.
Выполнено.
Алгоритм реализован по “мотивам” видео-уроков.
В соответствующее перечисление добавил способы расчета:
– по тарифу (для ВР = По окладу)
– процентом (для ВР = Премия месячная, квартальная, по итогам года)
– по ставке за единицу времени (для ВР = Компенсация обедов)
– фиксированной суммой (собственные надбавки из дополнительных начислений – для теста)
– суммой, согласно отработанного времени (собственные надбавки из основных начислений – для теста)
– по среднему (для ВР = Отпуск)
– процентом от объема (для ВР = Надбавка руководителю)
Какие внес изменения в алгоритм видео-уроков.
Во-первых, рассчитываю ОТДЕЛЬНО базы по сотруднику и по сотруднику в подразделении – для этого два раза левым соединением связываюсь с виртуальными таблицами получения базы.
Кроме того, если в наборе встречаю способ расчета процентом от объема – третий раз соединяюсь с ВТ для получения базы ПО ПОДРАЗДЕЛЕНИЮ. Соответственно приходится создвать три массива с измерениями.
……………………………….
//определимся с измерениями
ИзмеренияСотр = Новый Массив(); //для базы по сотруднику
ИзмеренияСотр.Добавить(“Сотрудник”);
ИзмеренияСотрПодр = Новый Массив(); //для базы по сотруднику в подразделении
ИзмеренияСотрПодр.Добавить(“Сотрудник”);
ИзмеренияСотрПодр.Добавить(“Подразделение”);
Запрос.УстановитьПараметр(“ИзмеренияСотр”,ИзмеренияСотр);
Запрос.УстановитьПараметр(“ИзмеренияСотрПодр”,ИзмеренияСотрПодр);
Если СтруктураПризнаков.ПоБазеПодразделения Тогда
ИзмеренияПодр = Новый Массив(); //для базы по подразделению
ИзмеренияПодр.Добавить(“Подразделение”);
Запрос.УстановитьПараметр(“ИзмеренияПодр”,ИзмеренияПодр);
КонецЕсли;
………………………………..
Запрос.Текст =
“ВЫБРАТЬ
| ОсновныеНачисления.НомерСтроки,
| ОсновныеНачисления.ВидРасчета,
| ОсновныеНачисления.ВидРасчета.СпособРасчета КАК Способ,
| ОсновныеНачисления.Размер”;
Если СтруктураПризнаков.ПоГрафику Тогда
Запрос.Текст = Запрос.Текст + “,
| ЕСТЬNULL(ОсновныеНачисленияДанныеГрафика.ЗначениеПериодДействия, 0) КАК ДниПлан,
| ЕСТЬNULL(ОсновныеНачисленияДанныеГрафика.ЗначениеФактическийПериодДействия, 0) КАК ДниФакт,
| ЕСТЬNULL(ОсновныеНачисленияДанныеГрафика.ЗначениеБазовыйПериод, 0) КАК ДниБаза,
| ЕСТЬNULL(КалендарныеДниФактическогоПериода.КалендарныеДни, 0) КАК ДниФактКалендарь”;
КонецЕсли;
Если СтруктураПризнаков.ПоБазе Тогда
Запрос.Текст = Запрос.Текст + “,
| ЕСТЬNULL(ОсновныеНачисленияБазаОсновныеНачисления1.РезультатБаза, 0) + ЕСТЬNULL(ОсновныеНачисленияБазаДополнительныеНачисления1.РезультатБаза, 0) КАК БазаРезультатСотр,
| ЕСТЬNULL(ОсновныеНачисленияБазаОсновныеНачисления2.РезультатБаза, 0) + ЕСТЬNULL(ОсновныеНачисленияБазаДополнительныеНачисления2.РезультатБаза, 0) КАК БазаРезультатСотрПодр”;
КонецЕсли;
Если СтруктураПризнаков.ПоБазеПодразделения Тогда
Запрос.Текст = Запрос.Текст + “,
| ЕСТЬNULL(ОсновныеНачисленияБазаОсновныеНачисления3.РезультатБаза, 0) + ЕСТЬNULL(ОсновныеНачисленияБазаДополнительныеНачисления3.РезультатБаза, 0) КАК БазаРезультатПодр”;
КонецЕсли;
………………………………..
Надбавку руководителю подразделения (имеет самую высокую категорию среди дополнительных начислений) рассчитываю в общем алгоритме:
………………………………..
Если Выборка.Способ = Перечисления.СпособыРасчета.ПоТарифу ИЛИ
Выборка.Способ = Перечисления.СпособыРасчета.Суммой
Тогда
Если Выборка.ДниПлан = 0 Тогда
Отказ = Истина;
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = “Не задан график расчета в строке “+Запись.НомерСтроки;
Сообщение.Сообщить();
Иначе
Результат = Запись.Размер * Выборка.ДниФакт / Выборка.ДниПлан;
КонецЕсли;
ИначеЕсли Выборка.Способ = Перечисления.СпособыРасчета.ПоСтавке Тогда //например, компенсация обедов
Результат = Запись.Размер * Выборка.ДниФакт;
ИначеЕсли Выборка.Способ = Перечисления.СпособыРасчета.ПоСреднему Тогда //например, отпуск
Если Выборка.ДниБаза = 0 Тогда
Отказ = Истина;
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = “Не задан график расчета для базового периода в строке “+Запись.НомерСтроки;
Сообщение.Сообщить();
Иначе
СредЗаработок = Выборка.БазаРезультатСотр / Выборка.ДниБаза; //базовая величина не зависит от подразделения, где работал сотр!!
Результат = СредЗаработок * ?(Запись.ВидРасчета = ПланыВидовРасчета.ОсновныеНачисления.Отпуск, Выборка.ДниФактКалендарь, Выборка.ДниФакт);
КонецЕсли;
ИначеЕсли Выборка.Способ = Перечисления.СпособыРасчета.ФиксированнойСуммой Тогда
Результат = Запись.Размер;
ИначеЕсли Выборка.Способ = Перечисления.СпособыРасчета.Процентом Тогда //всякого рода премии, надбавки
Результат = Выборка.БазаРезультатСотр * Запись.Размер / 100; //базовая величина не зависит от подразделения, где работал сотр!!
ИначеЕсли Выборка.Способ = Перечисления.СпособыРасчета.ПроцентомОтОбъема Тогда //надбавка руководителю подразделения
Результат = (Выборка.БазаРезультатПодр – Выборка.БазаРезультатСотрПодр) * Запись.Размер / 100;
………………………………..
Отчет без затруднений
Был опыт работы с механизмом расчетов в 7.7. Считаю, что самое сложное – не в механизме, как таковом, а в многообразии всякий ньансов в методологии расчета заработной платы на крупном предприятии, где каждый неучтенный рубль сотудника в результате погрешности “выпивает” сил не меньше, чем миллион…
Что нового: приходится обращать внимание на секунды в дате; больше свободы в реализации периодических расчетов (по-сравнению с 7.7.)
Сложности: наверное, они еще впереди – перерасчеты. Без них ни один месяц не проходит на предприятии
Задание выполнено.
Добавлены реквизиты ВР Категория, СпособРасчета(перечисление).
Сделано как в уроках – в общем серверном привилегированном модуле процедуры расчета.
Уроки пересматривать не было возможности, так что на память и через грабельки.
Так, забыл сначала в запросе по категориям сделать сортировку. Потом – отбор по категории
в запросе для получения данных расчета. Отладка и здравый смысл помогли.
Все виды расчетов добавлялись в польз. режиме.
Описаны алгоритмы для способов расчета: ФиксированнойСуммой, ПроцентомОтБазы, ПропорциональноОтработаннымДням,
Прогул, ПоСреднемуОтпуск, СуммойНаКаждыйОтработанныйДень, НадбавкаРуководителюОтдела.
1.”Премия по итогам года” – ПроцентомОтБазы, категория 0, доп.начисления.
2.”Премия ежемесячная” – ПроцентомОтБазы, категория 1, доп.начисления.
3.”Комп. за обеды” – СуммойНаКаждыйОтработанныйДень, категория 0, Осн.начисления.
Настроено вытеснение Прогулом и Отпуском. Своя формула расчета
<code>Результат = Выборка.Размер*Выборка.ФактДней;</code>
4.”Надбавка руководителю отдела” – НадбавкаРуководителюОтдела(способ), категория 2, доп.начисления.
Баз. в.р. “Премия ежемесячная”.
Передаю соотв. опцию в функцию, динамически строющую запрос. Она делает соединение (еще одно) с
табл. баз, но по всем сотрудникам. Измерение – только подразделение.
Базу считаю как разницу базы подр.(все сотр.) минус база по всем измерениям(по подр. и сотр.)
Не удержался привести наиболее интересный запрос:
<code>Функция ПолучитьДанныеДляРасчета(ОпцииЗапроса, ИмяРегистра, Ссылка, Категория, Отказ)
ДанныеГрафика = ОпцииЗапроса.ДанныеГрафика;
ДанныеБазы = ОпцииЗапроса.ДанныеБазы;
ДанныеБазыНадбавкаРуководителюОтдела = ОпцииЗапроса.ДанныеБазыНадбавкаРуководителюОтдела;
Запрос = Новый Запрос;
Запрос.Текст =
“ВЫБРАТЬ
| ТаблицаРегистра.НомерСтроки,
| ТаблицаРегистра.ВидРасчета.СпособРасчета КАК СпособРасчета,
| ТаблицаРегистра.Размер”;
Если ДанныеГрафика Тогда
Запрос.Текст = Запрос.Текст +”
| ,ЕСТЬNULL(ДанныеГрафика.ЗначениеПериодДействия, 0) КАК ПланДней,
| ЕСТЬNULL(ДанныеГрафика.ЗначениеФактическийПериодДействия, 0) КАК ФактДней,
| ЕСТЬNULL(ДанныеГрафика.ЗначениеБазовыйПериод, 0) КАК БазаДней”;
КонецЕсли;
Если ДанныеБазы Тогда
Запрос.Текст = Запрос.Текст +”
| ,ЕСТЬNULL(БазаОсновныеНачисления.РезультатБаза, 0) + ЕСТЬNULL(БазаДополнительныеНачисления.РезультатБаза, 0) КАК База”;
КонецЕсли;
Если ДанныеБазыНадбавкаРуководителюОтдела Тогда
Запрос.Текст = Запрос.Текст +”
| ,ЕСТЬNULL(БазаДополнительныеНачисленияП.РезультатБаза, 0)-ЕСТЬNULL(БазаДополнительныеНачисления.РезультатБаза, 0) КАК БазаДляНадбавкиРО”;
КонецЕсли;
Запрос.Текст = Запрос.Текст +”
|ИЗ
| РегистрРасчета.”+ИмяРегистра+” КАК ТаблицаРегистра”;
Если ДанныеГрафика Тогда
Запрос.Текст = Запрос.Текст +”
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.”+ИмяРегистра+”.ДанныеГрафика(Регистратор = &Ссылка И ВидРасчета.Категория = &Категория) КАК ДанныеГрафика
| ПО ТаблицаРегистра.НомерСтроки = ДанныеГрафика.НомерСтроки”;
КонецЕсли;
Если ДанныеБазы Тогда
Запрос.Текст = Запрос.Текст +”
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.”+ИмяРегистра+”.БазаОсновныеНачисления(&Измерения, &Измерения, , Регистратор = &Ссылка И ВидРасчета.Категория = &Категория) КАК БазаОсновныеНачисления
| ПО ТаблицаРегистра.НомерСтроки = БазаОсновныеНачисления.НомерСтроки
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.”+ИмяРегистра+”.БазаДополнительныеНачисления(&Измерения, &Измерения, , Регистратор = &Ссылка И ВидРасчета.Категория = &Категория) КАК БазаДополнительныеНачисления
| ПО ТаблицаРегистра.НомерСтроки = БазаДополнительныеНачисления.НомерСтроки”;
КонецЕсли;
Если ДанныеБазыНадбавкаРуководителюОтдела Тогда
Запрос.Текст = Запрос.Текст +”
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.”+ИмяРегистра+”.БазаДополнительныеНачисления(&ИзмеренияП, &ИзмеренияП, , Регистратор = &Ссылка И ВидРасчета.Категория = &Категория) КАК БазаДополнительныеНачисленияП
| ПО ТаблицаРегистра.НомерСтроки = БазаДополнительныеНачисленияП.НомерСтроки”;
КонецЕсли;
Запрос.Текст = Запрос.Текст +”
|ГДЕ
| ТаблицаРегистра.Регистратор = &Ссылка И ТаблицаРегистра.ВидРасчета.Категория = &Категория”;
Измерения = Новый Массив;
Измерения.Добавить(“Сотрудник”);
Измерения.Добавить(“Подразделение”);
Если ДанныеБазыНадбавкаРуководителюОтдела Тогда
ИзмеренияП = Новый Массив;
ИзмеренияП.Добавить(“Подразделение”);
Запрос.УстановитьПараметр(“ИзмеренияП”, ИзмеренияП);
Запрос.УстановитьПараметр(“НадбавкаРуководителюОтдела”, Перечисления.СпособыРасчета.НадбавкаРуководителюОтдела);
КонецЕсли;
Запрос.УстановитьПараметр(“Измерения”, Измерения);
Запрос.УстановитьПараметр(“Ссылка”, Ссылка);
Запрос.УстановитьПараметр(“Категория”, Категория);
Результат = Запрос.Выполнить();
Возврат Результат;
КонецФункции</code>
По отчету трудностей не возникло, спасибо СКД.
Обратная связь:
1. В этом блоке узнал много нового. Как по бух. так и по периодическим расчетам.
Особенно по расчетам. Перечислять устану.
Поменялось отношение к своему коду, написанному до курса. Есть что делать в плане
“красоты”. Не хватало модульности, универсальности.
Вы дали возможность расти дальше, опипаясть на новые стандарты. Дорогого стоит.
Спасибо – от души.
2. В понимании материала трудностей не было. Некоторые задания давались легче,
последнее – по труднее (в плане реализации). Так как работал с предметкой (ЗП),
возникало много вопросов и вариаций. Помог пример Евгения – читать условие задачи и не усложнять
решение, там, где не требовалось.
3. Расчеты (перерасчеты) наверное. Хотя понравился способ и порция данного материала, как раз для базового.
Сделано!
Категории я реализовал еще в прошлом ДЗ. Сейчас добавли Перечисление СпособРасчета и соответсвующий реквизит в ВидыРасчета. Кроме того в погоне за “универсальностью” добавил в виды расчета два строковых реквизита БазаНачало и БазаКонец. Содержимое которых, если задано, по оператору ВЫПОЛНИТЬ, дает возможность каждому виду расчета устанавливать собственные границы базовых периодов. После этого легко в пользовательском режиме создал новые виды расчета. С надбавкой руководителю пришлось допиливать “универсальный” запрос. К тому что было пришлось еще раз ЛевымСоединением добавлять ДопБазы с одним измерением “Подразделение”. Но зато запрос получился один и единожды выполняется на каждую категорию. Таким образом получилась условно “универсальная” схема проведения по регистрам расчета, которая даже “осмысленно” ругается на ошибки задания базового периода и не делает(на мой взгляд) лишних движений.
Отчет сделал на СКД и про него добавить нечего.
По блоку: в семерке избегал всего связанного с расчетом, поэтому и теория и практика в этой области была в новинку. Но все ДЗ по этой теме вроде работают. Спасибо за поддержку в мастер группе.
Задание выполнил.
Ввел понятия категории расчета и способа расчета. Соответствующим образом доработал конфигурацию, аналогично методике рассмотренной в теоретическом материале. Для расчета надбавки руководителю отдела в запрос для получения базы по дополнительным начислениям добавил второй запрос объединением, в который передаю массив измерений без сотрудника. В результате имеем в первом запросе базу по сотруднику, во втором – базу по подразделению в целом. При обработке результата, как разницу получаем базу для премии.
Запрос по дополнительным начислениям до унификации.
Построил указанный отчет по начислениям при помощи схемы компоновки данных, проблем не возникло.
Обратная связь.
1. Большая часть информации была новой, поскольку расчетные задачи встречаются в практике программиста на порядок реже и знаний по ним, соответственно, тоже меньше.
2. Непросто с ходу представить механизм работы вытеснений, подход с организацией рабочих наборов при расчете записей регистров расчета. Но понимание работы всей системы приходит со временем. Как правильно сказал Евгений в одном из своих уроков – нужно хорошо представлять как устроены и взаимодействуют между собой инструменты для реализации сложных расчетов и тогда сложностей не будет.
3. Все было рассмотрено достаточно подробно.
Посмотрел еще раз запрос из своего отчета, и обнаружил какую-то странную группировку на верхнем уровне. Не нужна там абсолютно. Видимо, осталась от каких-то экспериментов.. спал уже одним глазом =)
Да, бывает :)
Задание сделала.
Премия по итогам года – План видов расчета Дополнительные начисления, категория 0
Премия ежемесячная – План видов расчета Основные начисления, категория 1. Флажок Базовый период как период регистрации.
Компенсация за обеды – План видов расчета Основные начисления, категория 0, вытесняется прогулом и отпуском.
Надбавка руководителю. Основные начисления, категория2. Базовый период как период регистрации.
Немного переделала функцию ПолучитьСтруктуруРасчета, чтобы не приходилось ее дописывать при введении новых значений Перечислений.
<code> Функция ПолучитьСтруктуруРасчета(Выборка)
СтруктураРасчета = Новый Структура;
Для каждого ЗнПеречисл из Метаданные.Перечисления.СпособРасчета.ЗначенияПеречисления Цикл
СтруктураРасчета.Вставить(СтрЗаменить(трег(ЗнПеречисл),” ” ,””),0);
КонецЦикла;
Пока Выборка.Следующий() Цикл
СтрСпособ = СтрЗаменить(трег(Выборка.СпособРасчета),” “,””);
СтруктураРасчета.Вставить(СтрСпособ,1);
КонецЦикла;
Возврат СтруктураРасчета;
КонецФункции </code>
Так как для получения суммы премий по всему подразделению необходимо устанавливать массив измерений только по подразделениям, исключая сотрудников, то на этапе категории 2 получилось два запроса и два цикла – один с разрезом по сотрудникам и подразделениям, второй с разрезом по подразделениям. В цикле первом в записи с надбавками сначала пишется с минусом сумма по премии руководителя, затем в эти же записи в цикле втором дописывается сумма из второго запроса с общим результатом по подразделению.
<code> Для каждого Запись из Набор Цикл
Выборка.Сбросить();
Отбор.Вставить(“НомерСтроки”,Запись.НомерСтроки);
//первый цикл
Пока Выборка.НайтиСледующий(Отбор) Цикл
СпособРасчета = Выборка.СпособРасчета;
Если
….
ИначеЕсли СпособРасчета = Перечисления.СпособРасчета.НадбавкаРуководителя Тогда
Запись.Сумма = – Выборка.СуммаБаза;
Иначе
…
КонецЕсли;
//второй цикл
Если СтруктураРасчета.НадбавкаРуководителя=1 Тогда
ВыборкаПодразделения.Сбросить();
Отбор.Вставить(“НомерСтроки”,Запись.НомерСтроки);
Пока ВыборкаПодразделения.НайтиСледующий(Отбор) Цикл
Если СпособРасчета = Перечисления.СпособРасчета.НадбавкаРуководителя Тогда
Запись.Сумма = (Запись.Сумма + ВыборкаПодразделения.СуммаБаза) * Запись.Размер/100 * ?(Запись.Сторно,-1,1);
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЦикла; //конец общего цикла </code>
Отчет без затруднений.
Обратная связь – вообще не было никакого опыта по программированию в компоненте Расчет, кроме теории. Поэтому все, связанное с практикой, очень полезно и познавательно, огромное спасибо!
26.06.11 уезжаю в долгожданный отпуск. Еду далеко и без возможности сделать там финальное задание. Есть ли какой либо шанс финализироваться после? (в Москве буду 12.07)
Если будет возможность, то выложим финальное задание раньше, возможно 23.06.
Если не получиться, то Вам можно будет зафиналиться по возвращению.
Спасибо.
У меня перестал читаться диск с 4 блоком… Что делать? Файлы на диск скопированы ранее.
То есть, просмотр 4-го блока сейчас невозможен?
Я нашел способ просмотра – запускаю сразу все файлы, идет проверка диска (минут 15) потом все открываются. Я их смотрю по очереди. Думаю, последние главы я досмотрю.
Ситуация ясна. Предложенное решение можно считать временным.
Необходимо запустить процедуру замены диска 4-го блока – как это делается написал почтой.
Спасибо!
Что будет из себя представлять финальное задание? Хотя бы в общих чертах. =)
Подождать осталось совсем немного, скоро все подробно объясним :)