Задачи по расчету заработной платы в системе 1С:Предприятие часто вызывают сложности у начинающих разработчиков. Основная проблема заключается в специфике работы с регистрами расчета и понимании того, как платформа оперирует временными интервалами. В данной статье мы подробно разберем, как правильно создать вычисляемое поле в консоли запросов, как избежать типичных ошибок при делении дат и как объединить данные из нескольких регистров для получения итоговой суммы оклада.
Рассмотрим ситуацию, когда необходимо рассчитать оклад по формуле: Оклад * (ОтработанноеВремя / НормаВремени). Начинающие программисты часто пытаются подставить в формулу напрямую поля ПериодДействия или ПериодРегистрации из регистра расчета. В результате возникает ошибка, так как эти поля имеют тип Дата, а арифметические операции деления применимы только к числовым значениям.
Проанализируем причину: дата в 1С — это сложный тип, хранящий момент времени. Если вы попытаетесь разделить "1 января" на "31 января", система не поймет, какое числовое значение вы хотите получить. Для корректного расчета нам нужно сначала преобразовать временные интервалы в числа (дни или часы).
Самый правильный и эффективный способ получить числовые показатели для расчета зарплаты — это обращение к виртуальной таблице ДанныеГрафика регистра расчета. Рассмотрим подробнее, какие поля она предоставляет:
Посмотрим на пример того, как должно выглядеть вычисляемое поле в конструкторе запроса при использовании этих данных:
ВЫБРАТЬ
ОсновныеНачисления.Сотрудник,
ОсновныеНачисления.РезультатБаза * (ОсновныеНачисления.ЗначениеФактическийПериодДействия / ОсновныеНачисления.ЗначениеПериодДействия) КАК РассчитанныйОклад
ИЗ
РегистрРасчета.ОсновныеНачисления.ДанныеГрафика(Регистратор = &Регистратор) КАК ОсновныеНачисления
Если в вашей конфигурации по каким-то причинам не настроены графики работы или вам нужно посчитать календарную разницу между датами, мы рекомендуем использовать встроенную функцию языка запросов РАЗНОСТЬДАТ. Она позволяет получить разницу между двумя датами в заданных единицах (секундах, минутах, часах, днях).
Выясним, как применить эту функцию для получения числового коэффициента:
ВЫБРАТЬ
РАЗНОСТЬДАТ(ОсновныеНачисления.ПериодДействияНачало, ОсновныеНачисления.ПериодДействияКонец, ДЕНЬ) КАК КоличествоДней,
(РАЗНОСТЬДАТ(ОсновныеНачисления.ПериодДействияНачало, ОсновныеНачисления.ПериодДействияКонец, СЕКУНДА) / 3600) КАК КоличествоЧасов
ИЗ
РегистрРасчета.ОсновныеНачисления КАК ОсновныеНачисления
Часто задача звучит сложнее: нужно взять результат расчета из основного регистра, добавить данные из регистра дополнительных начислений и вычесть удержания. В этом случае мы используем ЛЕВОЕ СОЕДИНЕНИЕ таблиц по полям Сотрудник, ФизЛицо или НомерСтроки.
Важный нюанс: при соединении таблиц велика вероятность получить значение NULL, если по конкретному сотруднику нет данных в одном из регистров (например, нет удержаний в этом месяце). Помните правило: любое число + NULL = NULL. Чтобы расчет не "обнулился", каждое поле необходимо оборачивать в функцию ЕСТЬNULL.
Разберем пример комплексной формулы в запросе:
ВЫБРАТЬ
ЕСТЬNULL(Основные.Результат, 0) + ЕСТЬNULL(Дополнительные.Результат, 0) - ЕСТЬNULL(Удержания.Результат, 0) КАК ИтогоКВыплате
ИЗ
РегистрРасчета.ОсновныеНачисления КАК Основные
ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисления КАК Дополнительные
ПО Основные.Сотрудник = Дополнительные.Сотрудник
ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.Удержания КАК Удержания
ПО Основные.Сотрудник = Удержания.Сотрудник
При делении чисел в запросе часто возникают бесконечные десятичные дроби. Для того чтобы данные корректно отображались в отчетах и не вызывали ошибок в консоли, мы советуем использовать оператор ВЫРАЗИТЬ. Он позволяет ограничить количество знаков после запятой.
Проанализируем финальный синтаксис вычисляемого поля:
ВЫРАЗИТЬ(ЕСТЬNULL(Основные.РезультатБаза, 0) * (ЕСТЬNULL(Основные.ЗначениеФактическийПериодДействия, 0) / Основные.ЗначениеПериодДействия) КАК ЧИСЛО(15, 2))
Здесь ЧИСЛО(15, 2) означает, что число может содержать до 15 знаков всего, из которых 2 знака отведены под дробную часть.
ЕСТЬNULL, ВЫРАЗИТЬ и арифметические операторы +, -, *, /.ОкладИтоговый.Таким образом, комбинируя работу с виртуальными таблицами, функциями обработки NULL и правильным приведением типов, вы сможете построить гибкий и надежный запрос для любых расчетных задач в 1С.