1С 8.3 Регистры расчета - Программист 1С Минск. Автоматизация бизнеса.

Перейти к контенту

1С 8.3 Регистры расчета

Данные > Примеры кода 1С > 1С 8.3 Регистры расчета
Регистры расчета в 1С 8.3 - это объекты конфигурации, которые используются в механизме сложных периодических расчетов и служат для хранения записей о видах расчета заработной платы. Информация в регистре расчета хранится в виде записей, каждая из которых содержит значения измерений и соответствующие им значения ресурсов.
  • Измерения регистра расчета представляют разрезы, в которых хранится информация
  • Ресурсы регистра расчета содержат хранимую информацию
Перерасчеты регистра расчета (необязательный объект) хранят данные о записях утративших свою актуальность и подлежащих перерасчету.

Распространенные ошибки в формировании движений документов по регистрам:
  1. Не свернуть Табличную часть перед построением движений. Бывают ситуации исключения, но если их не предусмотрено, то ТЧ документа при построении движений документа необходимо сворачивать. Пользователи часто копируют строки и может быть большое количество дублей строк. Чревато увеличением, как минимум, количества записей в регистрах. Например, можно решить в запросе так: СГРУППИРОВАТЬ ПО Документ.Материалы
  2. Не знать, что в 1 секунде времени может быть несколько тысяч документов, и для определения последовательности использовать поле "Дата" из документа. Необходимо использовать МоментВремени(), который равен Дата + Ссылка. И еще нужно иметь ввиду, что Ссылка - это не только УИД, но и идентификатор типа документа. Поэтому при упорядочивании внутри одной секунды сначала идут документы одного типа, а потом уже другого.
Создание движения по регистру расчета в 1С 8.3:
Процедура ОбработкаПроведения(Отказ, РежимПроведения)

   
Движения.ДопНачисления.Записывать = Истина;
   
Движения.ДопНачисления.Очистить();

    Для Каждого
ТекСтрока Из ДопНачисления Цикл

       
Движение = Движения.ДопНачисления.Добавить();
       
Движение.Сторно = Ложь;
       
Движение.ВидРасчета = ТекСтрока.ВидРасчета;
       
Движение.ПериодДействияНачало = ТекСтрока.ДатаНачала;
       
Движение.ПериодДействияКонец = КонецДня(ТекСтрока.ДатаОкончания);
       
Движение.ПериодРегистрации = ТекСтрока.ДатаНачала;
       
Движение.Сотрудник = ТекСтрока.Сотрудник;
       
Движение.График = ТекСтрока.ГрафикРаботы;
       
Движение.Параметр = ТекСтрока.Размер;

    КонецЦикла;

   
Движения.Записать();
   
Расчет.РассчитатьДопНачисления(Ссылка, Движения.ДопНачисления);

КонецПроцедуры

Процедура
РассчитатьДопНачисления(ДокРегистратор, НаборЗаписей) Экспорт

   
Запрос=Новый Запрос;
   
Запрос.Текст="ВЫБРАТЬ
    |   ЕСТЬNULL(ДопНачисленияДанныеГрафика.КоличествоОтработанныхЧасовПериодДействия, 0) КАК ОтработанныеЧасы,
    |   ДопНачисленияДанныеГрафика.Параметр,
    |   ЕСТЬNULL(ДопНачисленияДанныеГрафика.КоличествоЧасовПериодДействия, 0) КАК ПланЧасов,
    |   ДопНачисленияДанныеГрафика.НомерСтроки
    |ИЗ
    |   РегистрРасчета.ДопНачисления.ДанныеГрафика(Регистратор = &ДокРегистратор
    |   И ВидРасчета = &ВидРасчетаДоплата) КАК ДопНачисленияДанныеГрафика"
;

   
Запрос.УстановитьПараметр("ДокРегистрато", ДокРегистратор); // Передача документа-регистратора
   
Запрос.УстановитьПараметр("ВидРасчетаДоплата", ПланыВидовРасчета.ДопНачисления.Доплата);

   
Выборка=Запрос.Выполнить().Выбрать();

   
Поиск=Новый Структура;
   
Поиск.Вставить("НомерСтроки",0); // Создание структуры для поиска данных для расчёта по номеру строки
   
Для Каждого Запись Из НаборЗаписей Цикл // Цикл по набору записей текущего документа

       
Поиск.НомерСтроки=Запись.НомерСтроки; // Заполнение номера строки для поиска
       
Если Выборка.НайтиСледующий(Поиск) Тогда // Поиск в выборке данных для расчёта по текущему номеру строки
            // Расчет суммы доп.начислений пропорционально отработанным дням
           
Запись.Сумма =?(Выборка.ПланЧасов=0,0, Выборка.ОтработанныеЧасы/Выборка.ПланЧасов * Выборка.Параметр);
        КонецЕсли;
       
Выборка.Сбросить(); // Сброс выборки - нужен чтобы следующая запись набора записей делала поиск по выборке сначала

   
КонецЦикла;

   
НаборЗаписей.Записать(,Истина); // Запись и замещение рассчитанных записей в базу

КонецПроцедуры
Расчет набора записей в 1С 8.3:
Процедура РассчитатьНаборЗаписей(НаборЗаписей, Приоритет, ТабличнаяЧасть = Неопределено)

   
Структура = Новый Структура;
   
Структура.Вставить("ОтработанныеЧасы", 0);
   
Структура.Вставить("ПланЧасов", 0);

    Для Каждого
ЭлементЗаписи из НаборЗаписей Цикл
        Если
ЭлементЗаписи.ВидРасчета.Приоритет = Приоритет Тогда

           
// Получить данные для расчета записи.
           
ДанныеДляРасчета = ПолучитьДанные(ЭлементЗаписи);

           
// Вызвать процедуру расчета записи.
           
РасчетЗаписи(ЭлементЗаписи, ДанныеДляРасчета);

           
// Возвратить результат расчета в табличную часть документа.
           
Если Не ТабличнаяЧасть = Неопределено Тогда

               
СтрокаТабличнойЧасти = ТабличнаяЧасть.Получить(ЭлементЗаписи.НомерСтроки-1);
               
СтрокаТабличнойЧасти.Результат = ЭлементЗаписи.Результат;

            КонецЕсли;

        КонецЕсли;
    КонецЦикла;

КонецПроцедуры

//Получение данных для трех видов расчета
Функция ПолучитьДанные(ЭлементЗаписи)

   
Структура = Новый Структура;
   
СпособРасчета = ЭлементЗаписи.ВидРасчета.СпособРасчета;

    Если
СпособРасчета = Перечисления.СпособыРасчета.ПоТарифнойСтавке Тогда

       
// Получить данные графика.
       
Запрос = Новый Запрос("ВЫБРАТЬ
        | ДанныеГрафика.ЗначениеФактическийПериодДействия КАК ГрафикФакт,
        | ДанныеГрафика.ЗначениеПериодДействия КАК ГрафикПлан
        |ИЗ
        | РегистрРасчета.ДопНачисления.ДанныеГрафика(
        | Регистратор = &Регистратор
        | И НомерСтроки = &НомерСтроки)
        | КАК ДанныеГрафика"
);

       
Запрос.УстановитьПараметр("Регистратор", ЭлементЗаписи.Регистратор);
       
Запрос.УстановитьПараметр("НомерСтроки", ЭлементЗаписи.НомерСтроки);

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

           
Структура.Вставить("ОтработанныеЧасы", Выборка.ГрафикФакт);
           
Структура.Вставить("ПланЧасов", Выборка.ГрафикПлан);

        КонецЕсли;

    ИначеЕсли
СпособРасчета = Перечисления.СпособыРасчета.ПроцентомОтБазы Тогда

       
Запрос = Новый Запрос("ВЫБРАТЬ
        | База.РезультатБаза
        |ИЗ
        | РегистрРасчета.ДопНачисления.БазаДопНачисления(
        | &Измерения, &Измерения, ,
        | Регистратор = &Регистратор
        | И НомерСтроки = &НомерСтроки) КАК База"
);

       
Измерения = Новый Массив(2);
       
Измерения[0] = "Сотрудник";
       
Измерения[1] = "Организация";

       
Запрос.УстановитьПараметр("Регистратор", ЭлементЗаписи.Регистратор);
       
Запрос.УстановитьПараметр("НомерСтроки", ЭлементЗаписи.НомерСтроки);
       
Запрос.УстановитьПараметр("Измерения", Измерения);

       
Выборка = Запрос.Выполнить().Выбрать();
        Если
Выборка.Следующий() Тогда
           
Структура.Вставить("База", Выборка.РезультатБаза);
        Иначе
           
Структура.Вставить("База", 0);
        КонецЕсли;

    ИначеЕсли
СпособРасчета = Перечисления.СпособыРасчета.ПоСдельнойВыработке Тогда

       
// Получить данные регистра накопления факт.выработка за период действия записи.
       
Запрос = Новый Запрос("ВЫБРАТЬ
        | СУММА(СдельнаяВыработкаОбороты.ВыработкаОборот) КАК ВыработкаОборот
        |ИЗ
        | РегистрНакопления.СдельнаяВыработка.Обороты( &ДатаНачало, &ДатаКонец,,
        | Организация = &Организация И Сотрудник = &Сотрудник)
        | КАК СдельнаяВыработкаОбороты"
);

       
Запрос.УстановитьПараметр("ДатаНачало", НачалоДня(ЭлементЗаписи.ПериодДействияНачало));
       
Запрос.УстановитьПараметр("ДатаКонец", КонецДня(ЭлементЗаписи.ПериодДействияКонец));
       
Запрос.УстановитьПараметр("Сотрудник", ЭлементЗаписи.Сотрудник);
       
Запрос.УстановитьПараметр("Организация", ЭлементЗаписи.Организация);

       
Выборка = Запрос.Выполнить().Выбрать();
        Если
Выборка.Следующий() Тогда
           
Структура.Вставить("Выработка", Выборка.ВыработкаОборот);
        Иначе
           
Структура.Вставить("Выработка", 0);
        КонецЕсли;

    КонецЕсли;

    Возврат
Структура;

КонецФункции

//Процедура расчета записей
Процедура РасчетЗаписи(ЭлементЗаписи, Данные)

   
СпособРасчета = ЭлементЗаписи.ВидРасчета.СпособРасчета;
    Если
СпособРасчета = Перечисления.СпособыРасчета.ПоТарифнойСтавке Тогда

        Если Не
Данные.ПланЧасов = 0 Тогда
           
Результат = ЭлементЗаписи.Размер * Данные.ОтработанныеЧасы / Данные.ПланЧасов;
        Иначе
           
Результат = 0;
        КонецЕсли;

    ИначеЕсли
СпособРасчета = Перечисления.СпособыРасчета.ПроцентомОтБазы Тогда
       
Результат = ЭлементЗаписи.Размер * Данные.База / 100;
    ИначеЕсли
СпособРасчета = Перечисления.СпособыРасчета.ФиксированнойСуммой Тогда
       
Результат = ЭлементЗаписи.Размер;
    ИначеЕсли
СпособРасчета = Перечисления.СпособыРасчета.ПоСдельнойВыработке Тогда
       
Результат = Данные.Выработка;
    КонецЕсли;

   
ЭлементЗаписи.Результат = Результат * ?(ЭлементЗаписи.Сторно, -1, 1);

КонецПроцедуры
Добавление сторно-записи в набор и в табличную часть в 1С 8.3:
Процедура РасчетНачислений() Экспорт

   
ТаблицаСторно = НаборОсновныеНачисления.ПолучитьДополнение();
    Для Каждого
ТекСтрока из ТаблицаСторно Цикл

       
// По каждой строке
       
ДобавитьСторноЗаписи(ТекСтрока, НаборОсновныеНачисления, ОсновныеНачисления);

    КонецЦикла;

КонецПроцедуры

Процедура
ДобавитьСторноЗаписи(Данные, НаборЗаписей, ТабличнаяЧасть = Неопределено)

   
Движение = НаборЗаписей.Добавить();

   
// Предопределенные поля
   
Движение.ПериодРегистрации = Данные.ПериодРегистрацииСторно;
   
Движение.ПериодДействияНачало = Данные.ПериодДействияНачалоСторно;
   
Движение.ПериодДействияКонец = Данные.ПериодДействияКонецСторно;
   
Движение.ВидРасчета = Данные.ВидРасчета;
   
Движение.Сторно = Истина;

   
// Измерения
   
Движение.Сотрудник = Данные.Сотрудник;
   
Движение.Организация = Данные.Организация;

   
// Реквизиты
   
Движение.ГрафикРаботы = Данные.ГрафикРаботы;
   
Движение.Размер = Данные.Размер;
   
Движение.ВидУчетаВремени = Данные.ВидУчетаВремени;
   
Движение.Подразделение = Данные.Подразделение;
   
Движение.СтатьяЗатрат = Данные.СтатьяЗатрат;

    Если Не
ТабличнаяЧасть = Неопределено Тогда

       
НоваяСтрока = ТабличнаяЧасть.Добавить();
       
НоваяСтрока.Сотрудник = Данные.Сотрудник;
       
НоваяСтрока.ВидРасчета = Данные.ВидРасчета;
       
НоваяСтрока.ДатаНачало = Данные.ПериодДействияНачалоСторно;
       
НоваяСтрока.ДатаКонец = Данные.ПериодДействияКонецСторно;
       
НоваяСтрока.Размер = Данные.Размер;
       
НоваяСтрока.Подразделение = Данные.Подразделение;
       
НоваяСтрока.Сторно = Истина;

    КонецЕсли;

КонецПроцедуры
0
комментарии
____________________
Copyright©, «Программист 1С в г.Минске», 04.04.2020
Перепечатка текста и фотографий разрешена при наличии прямой ссылки на источник
Яндекс.Метрика
Защищенное соединение ssl
visa
mastercard
Maestro
Яндекс деньги
Назад к содержимому