Вид начисление Подарок 1с. Задача для программистов 1с
Добрый день! Задача по программированию, для 1с-разработчиков. Версия программы: 1С:Предприятие 8.3, учебная версия (8.3.14.1694). Существует вид допначисления подарок. Также есть основное начисление оклад и допначисление премия. Значение подарка задается вручную пользователем в документе начисление зарплаты в колонке Размер. Оклад считается запросом, здесь проблем нет. Проблема возникает при расчете Премии, а конкретно не садится значение подарка в РезультатБаза виртуальной таблицы ДопНачисленияБазаДопНачисления. И так, премия рассчитывается по формуле: Премия=(Оклад+Подарок)*ПроценПремии. ПроцентПремии задается пользователем вручную в документе начисление зарплаты на вкладке ДопНачисления в той же колонке Размер. Вся проблема в том, что РезультатБаза по подарку нулевое значение. Вопрос: как решить эту проблему, чтобы все корректно считалось. Код по расчету премии:
Движения.ДополнительныеНачисления.Записывать=Истина;
Для Каждого ТекСтрокаНачисленияДоп Из НачисленияДоп Цикл
Движение2=Движения.ДополнительныеНачисления.Добавить();
Движение2.Сторно=Ложь;
ЗаполнитьЗначенияСвойств(Движение2, ТекСтрокаНачисленияДоп);
Движение2.ВидРасчета=ТекСтрокаНачисленияДоп.ВидНачисления;
Движение2.ПериодРегистрации=Дата;
Если Движение2.ВидРасчета=ПланыВидовРасчета.ДополнительныеНачисления.Премия ИЛИ Движение2.ВидРасчета=ПланыВидовРасчета.ДополнительныеНачисления.Подарок Тогда
ПрошлыйМесяц=ДобавитьМесяц(Дата, -1);
Движение2.БазовыйПериодНачало=НачалоМесяца(ПрошлыйМесяц);
Движение2.БазовыйПериодКонец=КонецМесяца(ПрошлыйМесяц);
Иначе
Движение2.БазовыйПериодНачало=НачалоМесяца(Дата);
Движение2.БазовыйПериодКонец=КонецМесяца(Дата);
КонецЕсли;
Если Движение2.ВидРасчета=ПланыВидовРасчета.ДополнительныеНачисления.Подарок Тогда
Движение2.Результат=ТекСтрокаНачисленияДоп.Размер;
КонецЕсли;
КонецЦикла;
Движения.ДополнительныеНачисления.Записать();
//{{КОНСТРУКТОР_ЗАПРОСА_С_ОБРАБОТКОЙ_РЕЗУЛЬТАТА
// Данный фрагмент построен конструктором.
// При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ДополнительныеНачисления.НомерСтроки КАК НомерСтроки,
| ЕСТЬNULL(ДополнительныеНачисленияБазаДополнительныеНачисления.РезультатБаза, 0) КАК БазаДопНач,
| ЕСТЬNULL(ДополнительныеНачисленияБазаОсновныеНачисления.РезультатБаза, 0) КАК БазаОснНач
|ИЗ
| РегистрРасчета.ДополнительныеНачисления КАК ДополнительныеНачисления
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисления.БазаДополнительныеНачисления(
| &МассивИзмерений,
| &МассивИзмерений,
| ,
| ВидРасчета = &Премия
| И Регистратор = &Ссылка) КАК ДополнительныеНачисленияБазаДополнительныеНачисления
| ПО ДополнительныеНачисления.НомерСтроки = ДополнительныеНачисленияБазаДополнительныеНачисления.НомерСтроки
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисления.БазаОсновныеНачисления(
| &МассивИзмерений,
| &МассивИзмерений,
| ,
| ВидРасчета = &Премия
| И Регистратор = &Ссылка) КАК ДополнительныеНачисленияБазаОсновныеНачисления
| ПО ДополнительныеНачисления.НомерСтроки = ДополнительныеНачисленияБазаОсновныеНачисления.НомерСтроки
|ГДЕ
| ДополнительныеНачисления.Регистратор = &Ссылка";
МассивИзмерений=Новый Массив;
МассивИзмерений.Добавить("Сотрудник");
Запрос.УстановитьПараметр("МассивИзмерений", МассивИзмерений);
Запрос.УстановитьПараметр("Премия", ПланыВидовРасчета.ДополнительныеНачисления.Премия);
Запрос.УстановитьПараметр("Ссылка", Ссылка);
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Для Каждого СтрДвижение Из Движения.ДополнительныеНачисления Цикл
Если СтрДвижение.ВидРасчета<>ПланыВидовРасчета.ДополнительныеНачисления.Премия Тогда
Продолжить;
КонецЕсли;
ВыборкаДетальныеЗаписи.Сбросить();
ВыборкаДетальныеЗаписи.НайтиСледующий(СтрДвижение.НомерСтроки, "НомерСтроки");
СтрДвижение.Результат=СтрДвижение.Размер/100 *(ВыборкаДетальныеЗаписи.БазаДопНач+ВыборкаДетальныеЗаписи.БазаОснНач);
КонецЦикла;
//}}КОНСТРУКТОР_ЗАПРОСА_С_ОБРАБОТКОЙ_РЕЗУЛЬТАТА
Движения.ДополнительныеНачисления.Записать();
ПоказатьПо теме из базы знаний
Найденные решения
Движения.ДополнительныеНачисления.Записывать=Истина;
Для Каждого ТекСтрокаНачисленияДоп Из НачисленияДоп Цикл
Движение2=Движения.ДополнительныеНачисления.Добавить();
Движение2.Сторно=Ложь;
ЗаполнитьЗначенияСвойств (Движение2, ТекСтрокаНачисленияДоп);
Движение2.ВидРасчета=ТекСтрокаНачисленияДоп.ВидНачисления;
Движение2.ПериодРегистрации=НачалоМесяца(Дата);
Движение2.ПериодДействияНачало=ТекСтрокаНачисления.ДатаНачала;
Движение2.ПериодДействияКонец=КонецДня (ТекСтрокаНачисления.ДатаОкончания);
Движение2.Размер=ТекСтрокаНачисленияДоп.Размер;
//Если Движение2.ВидРасчета=ПланыВидовРасчета.ДополнительныеНачисления.Премия Тогда
// ПрошлыйМесяц=ДобавитьМесяц (Дата, -1);
// Движение2.БазовыйПериодНачало = НачалоМесяца(ПрошлыйМесяц);
// Движение2.БазовыйПериодКонец = КонецМесяца(ПрошлыйМесяц);
//Иначе
Движение2.БазовыйПериодНачало = НачалоМесяца(Дата);
Движение2.БазовыйПериодКонец = КонецМесяца(Дата);
//КонецЕсли;
Если Движение2.ВидРасчета=ПланыВидовРасчета.ДополнительныеНачисления.Подарок Тогда
Движение2.Результат=ТекСтрокаНачисленияДоп.Размер;
КонецЕсли;
КонецЦикла;
Движения.ДополнительныеНачисления.Записать();
Для Каждого Запись из Движения.ДополнительныеНачисления Цикл
Если Запись.ВидРасчета<>ПланыВидовРасчета.ДополнительныеНачисления.Премия Тогда
Продолжить;
КонецЕсли;
РазмерБазыО = Новый Массив;
РазмерБазыО.Добавить("ОсновныеНачисления.Результат");
ИзмеренияБазыО = Новый Структура;
ИзмеренияБазыО.Вставить("Сотрудник","ОсновныеНачисления.Сотрудник");
СуммаБазыО = Запись.ПолучитьБазу( РазмерБазыО,ИзмеренияБазыО).Итог("Результат");
РазмерБазыД = Новый Массив;
РазмерБазыД.Добавить("ДополнительныеНачисления.Результат");
ИзмеренияБазыД = Новый Структура;
ИзмеренияБазыД.Вставить("Сотрудник","ДополнительныеНачисления.Сотрудник");
СуммаБазыД = Запись.ПолучитьБазу( РазмерБазыД,ИзмеренияБазыД).Итог("Результат");
Запись.Результат = (СуммаБазыО+СуммаБазыД)*Запись.Размер/100;
КонецЦикла;
Движения.ДополнительныеНачисления.Записать();
ПоказатьОстальные ответы
Подписаться на ответы
Инфостарт бот
Сортировка:
Древо развёрнутое
Свернуть все
проблема, что все в одном документе и премия и подарок
обойти....
в рег.расчета создать реквизит "параметрРасчета", там хранить размер оклада, премии и т.д.
при проведении документа записываем в регистр все, кроме суммы премии
а Сумму премии считать в модуле менеджера рег.расчета
вот там всю базу будет видно
обойти....
в рег.расчета создать реквизит "параметрРасчета", там хранить размер оклада, премии и т.д.
при проведении документа записываем в регистр все, кроме суммы премии
а Сумму премии считать в модуле менеджера рег.расчета
вот там всю базу будет видно
(6) Не совсем Вас понимаю, опыта совсем мало, только учусь. Можете сделать это в моей базе. Скину.
Прикрепленные файлы:
база 30.11.2021.dt
Процедура ОбработкаПроведения(Отказ, РежимПроведения)
Движения.ОсновныеНачисления.Записывать=Истина;
Для Каждого ТекСтрокаНачисления Из Начисления Цикл
Движение=Движения.ОсновныеНачисления.Добавить();
Движение.Сторно=Ложь;
ЗаполнитьЗначенияСвойств (Движение, ТекСтрокаНачисления);
Движение.ВидРасчета=ТекСтрокаНачисления.ВидНачисления;
Движение.ПериодДействияНачало=ТекСтрокаНачисления.ДатаНачала;
Движение.ПериодДействияКонец=КонецДня (ТекСтрокаНачисления.ДатаОкончания);
Движение.ПериодРегистрации=Дата;
КонецЦикла;
Движения.ОсновныеНачисления.Записать();
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| ОсновныеНачисленияДанныеГрафика.Сотрудник КАК Сотрудник,
| ОсновныеНачисленияДанныеГрафика.НомерСтроки КАК НомерСтроки,
| ЕСТЬNULL(ОсновныеНачисленияДанныеГрафика.ЗначениеДниПериодДействия, 0) КАК ПланДни,
| ЕСТЬNULL(ОсновныеНачисленияДанныеГрафика.ЗначениеДниФактическийПериодДействия, 0) КАК ФактДни
|ПОМЕСТИТЬ ВТ_ДанныеГрафика
|ИЗ
| РегистрРасчета.ОсновныеНачисления.ДанныеГрафика(
| Регистратор = &Ссылка
| И ВидРасчета = &Оклад) КАК ОсновныеНачисленияДанныеГрафика
|
|ИНДЕКСИРОВАТЬ ПО
| Сотрудник
|;
|
|//////////////////////////////////////////////////////////// ////////////////////
|ВЫБРАТЬ
| ВТ_ДанныеГрафика.НомерСтроки КАК НомерСтроки,
| ЕСТЬNULL(ОкладыСотрудниковСрезПоследних.Оклад, 0) КАК Оклад,
| ВТ_ДанныеГрафика.ПланДни КАК ПланДни,
| ВТ_ДанныеГрафика.ФактДни КАК ФактДни
|ИЗ
| ВТ_ДанныеГрафика КАК ВТ_ДанныеГрафика
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ОкладыСотрудников.СрезПоследних(
| &Дата,
| Сотрудник В
| (ВЫБРАТЬ
| ВТ_ДанныеГрафика.Сотрудник КАК Сотрудник
| ИЗ
| ВТ_ДанныеГрафика КАК ВТ_ДанныеГрафика)) КАК ОкладыСотрудниковСрезПоследних
| ПО ВТ_ДанныеГрафика.Сотрудник = ОкладыСотрудниковСрезПоследних.Сотрудник";
Запрос.УстановитьПараметр("Дата", НачалоМесяца(Дата));
Запрос.УстановитьПараметр("Оклад", ПланыВидовРасчета.ОсновныеНачисления.Оклад);
Запрос.УстановитьПараметр("Ссылка", Ссылка);
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Для Каждого СтрДвижение Из Движения.ОсновныеНачисления Цикл
Если СтрДвижение.ВидРасчета<>ПланыВидовРасчета.ОсновныеНачисления.Оклад Тогда
Продолжить;
КонецЕсли;
ВыборкаДетальныеЗаписи.Сбросить();
ВыборкаДетальныеЗаписи.НайтиСледующий(СтрДвижение.НомерСтроки, "НомерСтроки");
Если ВыборкаДетальныеЗаписи.Оклад=0 Тогда
Сообщить ("Оклад для сотрудника "+ВыборкаДетальныеЗаписи.Сотрудник+" не задан");
Отказ=Истина;
КонецЕсли;
СтрДвижение.Факт=ВыборкаДетальныеЗаписи.ФактДни;
СтрДвижение.Результат=ВыборкаДетальныеЗаписи.ФактДни/ВыборкаДетальныеЗаписи.ПланДни*ВыборкаДетальныеЗаписи.Оклад;
КонецЦикла;
Движения.ОсновныеНачисления.Записать(,Истина);
Движения.ДополнительныеНачисления.Записывать=Истина;
Для Каждого ТекСтрокаНачисленияДоп Из НачисленияДоп Цикл
Движение2=Движения.ДополнительныеНачисления.Добавить();
Движение2.Сторно=Ложь;
ЗаполнитьЗначенияСвойств (Движение2, ТекСтрокаНачисленияДоп);
Движение2.ВидРасчета=ТекСтрокаНачисленияДоп.ВидНачисления;
Движение2.ПериодРегистрации=НачалоМесяца(Дата);
Движение2.ПериодДействияНачало=ТекСтрокаНачисления.ДатаНачала;
Движение2.ПериодДействияКонец=КонецДня (ТекСтрокаНачисления.ДатаОкончания);
Движение2.Размер=ТекСтрокаНачисленияДоп.Размер;
Если Движение2.ВидРасчета=ПланыВидовРасчета.ДополнительныеНачисления.Премия Тогда
ПрошлыйМесяц=ДобавитьМесяц (Дата, -1);
Движение2.БазовыйПериодНачало = НачалоМесяца(ПрошлыйМесяц);
Движение2.БазовыйПериодКонец = КонецМесяца(ПрошлыйМесяц);
Иначе
Движение2.БазовыйПериодНачало = НачалоМесяца(Дата);
Движение2.БазовыйПериодКонец = КонецМесяца(Дата);
КонецЕсли;
Если Движение2.ВидРасчета=ПланыВидовРасчета.ДополнительныеНачисления.Подарок Тогда
Движение2.Результат=ТекСтрокаНачисленияДоп.Размер;
КонецЕсли;
КонецЦикла;
Движения.ДополнительныеНачисления.Записать();
Для Каждого Запись из Движения.ДополнительныеНачисления Цикл
Если Запись.ВидРасчета<>ПланыВидовРасчета.ДополнительныеНачисления.Премия Тогда
Продолжить;
КонецЕсли;
РазмерБазыО = Новый Массив;
РазмерБазыО.Добавить("ОсновныеНачисления.Результат");
ИзмеренияБазыО = Новый Структура;
ИзмеренияБазыО.Вставить("Сотрудник","ОсновныеНачисления.Сотрудник");
СуммаБазыО = Запись.ПолучитьБазу( РазмерБазыО,ИзмеренияБазыО).Итог("Результат");
РазмерБазыД = Новый Массив;
РазмерБазыД.Добавить("ДополнительныеНачисления.Результат");
ИзмеренияБазыД = Новый Структура;
ИзмеренияБазыД.Вставить("Сотрудник","ДополнительныеНачисления.Сотрудник");
СуммаБазыД = Запись.ПолучитьБазу( РазмерБазыД,ИзмеренияБазыД).Итог("Результат");
Запись.Результат = (СуммаБазыО+СуммаБазыД)*Запись.Размер/100;
КонецЦикла;
Движения.ДополнительныеНачисления.Записать();
КонецПроцедуры
Показать
(9) Здравствуйте! Извините, что не мог ответить сразу, работал двое суток. Очень благодарен что откликнулись на призыв о помощи. Спасибо Вам за предоставленное решение, но к сожалению возникает та же проблема - База по допначислениям пустая,т.е. равна 0 (полностью скопировал ваш написанный код, прошелся точкой остановой, посчитал результат вручную на калькуляторе в пользовательском режиме). Нужно другое решение. По поводу базового периода у подарка, чтобы база по нему бралась за тот же период что и премия, сделал вот так:
Если Движение2.ВидРасчета=ПланыВидовРасчета.ДополнительныеНачисления.Премия ИЛИ Движение2.ВидРасчета=ПланыВидовРасчета.ДополнительныеНачисления.Подарок Тогда
ПрошлыйМесяц=ДобавитьМесяц (Дата, -1);
Движение2.БазовыйПериодНачало = НачалоМесяца(ПрошлыйМесяц);
Движение2.БазовыйПериодКонец = КонецМесяца(ПрошлыйМесяц);
Иначе
Движение2.БазовыйПериодНачало = НачалоМесяца(Дата);
Движение2.БазовыйПериодКонец = КонецМесяца(Дата);
КонецЕсли;
Движения.ДополнительныеНачисления.Записывать=Истина;
Для Каждого ТекСтрокаНачисленияДоп Из НачисленияДоп Цикл
Движение2=Движения.ДополнительныеНачисления.Добавить();
Движение2.Сторно=Ложь;
ЗаполнитьЗначенияСвойств (Движение2, ТекСтрокаНачисленияДоп);
Движение2.ВидРасчета=ТекСтрокаНачисленияДоп.ВидНачисления;
Движение2.ПериодРегистрации=НачалоМесяца(Дата);
Движение2.ПериодДействияНачало=ТекСтрокаНачисления.ДатаНачала;
Движение2.ПериодДействияКонец=КонецДня (ТекСтрокаНачисления.ДатаОкончания);
Движение2.Размер=ТекСтрокаНачисленияДоп.Размер;
//Если Движение2.ВидРасчета=ПланыВидовРасчета.ДополнительныеНачисления.Премия Тогда
// ПрошлыйМесяц=ДобавитьМесяц (Дата, -1);
// Движение2.БазовыйПериодНачало = НачалоМесяца(ПрошлыйМесяц);
// Движение2.БазовыйПериодКонец = КонецМесяца(ПрошлыйМесяц);
//Иначе
Движение2.БазовыйПериодНачало = НачалоМесяца(Дата);
Движение2.БазовыйПериодКонец = КонецМесяца(Дата);
//КонецЕсли;
Если Движение2.ВидРасчета=ПланыВидовРасчета.ДополнительныеНачисления.Подарок Тогда
Движение2.Результат=ТекСтрокаНачисленияДоп.Размер;
КонецЕсли;
КонецЦикла;
Движения.ДополнительныеНачисления.Записать();
Для Каждого Запись из Движения.ДополнительныеНачисления Цикл
Если Запись.ВидРасчета<>ПланыВидовРасчета.ДополнительныеНачисления.Премия Тогда
Продолжить;
КонецЕсли;
РазмерБазыО = Новый Массив;
РазмерБазыО.Добавить("ОсновныеНачисления.Результат");
ИзмеренияБазыО = Новый Структура;
ИзмеренияБазыО.Вставить("Сотрудник","ОсновныеНачисления.Сотрудник");
СуммаБазыО = Запись.ПолучитьБазу( РазмерБазыО,ИзмеренияБазыО).Итог("Результат");
РазмерБазыД = Новый Массив;
РазмерБазыД.Добавить("ДополнительныеНачисления.Результат");
ИзмеренияБазыД = Новый Структура;
ИзмеренияБазыД.Вставить("Сотрудник","ДополнительныеНачисления.Сотрудник");
СуммаБазыД = Запись.ПолучитьБазу( РазмерБазыД,ИзмеренияБазыД).Итог("Результат");
Запись.Результат = (СуммаБазыО+СуммаБазыД)*Запись.Размер/100;
КонецЦикла;
Движения.ДополнительныеНачисления.Записать();
Показать
(18) (19) Так у меня так и было, но не бралась база по подарку
Если Движение2.ВидРасчета=ПланыВидовРасчета.ДополнительныеНачисления.Премия ИЛИ Движение2.ВидРасчета=ПланыВидовРасчета.ДополнительныеНачисления.Подарок Тогда
ПрошлыйМесяц=ДобавитьМесяц (Дата, -1);
Движение2.БазовыйПериодНачало = НачалоМесяца(ПрошлыйМесяц);
Движение2.БазовыйПериодКонец = КонецМесяца(ПрошлыйМесяц);
Иначе
Движение2.БазовыйПериодНачало = НачалоМесяца(Дата);
Движение2.БазовыйПериодКонец = КонецМесяца(Дата);
КонецЕсли;
(22) Не сказал бы. Вот если бы не было подарка, то остальное без проблем работало. Оклад период действия задается пользователем не зависимо от даты документа; премия можно считать по базовому периоду за прошлый месяц, отнимая месяц от даты документа и т.д. Только подарок как-то не подчиняется этим правилам
1. В предлагаемом найденном решении запросы в цикле, что есть нарушение канона 1с программирования. Так соломаха из скилбокса утверждает.
2. В этом кусочке кода
вылетает малоинформативная ошибка, по памяти что-то про неправильный первый параметр.
2. В этом кусочке кода
ИзмеренияБазыД = Новый Структура;
ИзмеренияБазыД.Вставить("Сотрудник","ДополнительныеНачисления.Сотрудник");
СуммаБазыД = Запись.ПолучитьБазу( РазмерБазыД,ИзмеренияБазыД).Итог("Результат");
вылетает малоинформативная ошибка, по памяти что-то про неправильный первый параметр.
Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот