Как реализовать проверку месяца в Больничном листе и автоматическую установку порядка пересчета в Приеме на работу в 1С:ERP?

Программист 1С v8.3 (Управляемые формы) 1С:ERP Управление предприятием Управленческий учет IT и автоматизация бизнеса
← На главную

В процессе сопровождения систем 1С:ERP Управление предприятием или 1С:Зарплата и управление персоналом 3.1 часто возникают задачи по кастомизации типовых документов под требования конкретного отдела кадров или бухгалтерии. Рассмотрим две классические задачи: установку контроля соответствия дат в документе БольничныйЛист и автоматическое заполнение параметров расчета в документе ПриемНаРаботу.

Для реализации этих задач мы будем использовать механизм расширений конфигурации, так как это позволяет сохранить типовую конфигурацию на поддержке и минимизировать риски при обновлении системы.

Решение задачи №1: Проверка соответствия месяца окончания больничного и периода регистрации

Суть задачи заключается в том, чтобы система выдавала предупреждение или вопрос пользователю, если месяц даты окончания нетрудоспособности не совпадает с месяцем периода регистрации документа. Это критично для корректного отражения начислений в налоговых и учетных периодах.

Разберем по шагам, почему обычный метод Вопрос() не сработает в процедуре ПередЗаписью на сервере. В управляемом приложении 1С разделяет выполнение кода на клиентский и серверный контексты. Серверный код не может прерывать выполнение для ожидания ответа пользователя. Поэтому нам необходимо организовать «двухэтапную» проверку.

Проанализируем алгоритм реализации в расширении для формы документа БольничныйЛист:

  1. Создадим в расширении процедуру-обработчик ПередЗаписью на клиенте.
  2. Выполним сравнение месяцев. Для этого используем функцию НачалоМесяца(), которая позволяет игнорировать число и время, сравнивая только начало периода.
  3. Если месяцы различаются, вызовем асинхронный метод ПоказатьВопрос().

Посмотрим на пример программного кода, который реализует данную логику:


&НаКлиенте
Процедура Расш1_ПередЗаписьюПосле(Отказ, ПараметрыЗаписи)
    
    // Проверяем, что даты заполнены
    Если ЗначениеЗаполнено(Объект.ДатаОкончания) И ЗначениеЗаполнено(Объект.ПериодРегистрации) Тогда
        
        // Сравниваем начала месяцев
        Если НачалоМесяца(Объект.ДатаОкончания) <> НачалоМесяца(Объект.ПериодРегистрации) Тогда
            
            // Если флаг подтверждения еще не установлен в параметрах записи
            Если Не ПараметрыЗаписи.Свойство("ПодтвержденоНесовпадениеМесяцев") Тогда
                Отказ = Истина;
                Оповещение = Новый ОписаниеОповещения("ЗавершитьЗаписьПослеВопроса", ЭтотОбъект, ПараметрыЗаписи);
                ПоказатьВопрос(Оповещение, "Месяц даты окончания не совпадает с месяцем периода регистрации. Продолжить запись?", РежимДиалогаВопрос.ДаНет);
            КонецЕсли;
            
        КонецЕсли;
        
    КонецЕсли;
    
КонецПроцедуры

&НаКлиенте
Процедура ЗавершитьЗаписьПослеВопроса(Результат, ДополнительныеПараметры) Экспорт
    Если Результат = КодВозвратаДиалога.Да Тогда
        // Добавляем признак того, что пользователь согласился
        ДополнительныеПараметры.Вставить("ПодтвержденоНесовпадениеМесяцев", Истина);
        ЭтотОбъект.Записать(ДополнительныеПараметры);
    КонецЕсли;
КонецПроцедуры

Важный момент: использование метода НачалоМесяца гораздо надежнее, чем простое сравнение свойства .Месяц у даты, так как прямое обращение к месяцу вернет число от 1 до 12, и программа может ошибочно посчитать даты за разные годы (например, декабрь 2023 и декабрь 2024) одинаковыми.

Решение задачи №2: Автоматическая установка порядка пересчета в Приеме на работу

Вторая задача требует изменения логики заполнения документа ПриемНаРаботу. Нам необходимо, чтобы при выборе определенного графика работы автоматически устанавливался ПорядокПересчета стоимости часа.

Разберем ситуацию: если выбран график «Основной пятидневка», устанавливаем значение «По норме графика», во всех остальных случаях — «По среднемесячному количеству часов/дней».

Для реализации этой задачи лучше всего использовать обработчик события ПриИзменении для реквизита ГрафикРаботы на форме документа. Это позволит пользователю сразу увидеть результат работы алгоритма.

Проанализируем использование перечислений. В системе 1С порядок пересчета хранится в объекте Перечисления.ПорядокПересчетаСтоимостиЧаса. Нам понадобятся значения ПоНормеГрафика и ПоСреднемесячнойНорме.

Рассмотрим пример кода для расширения формы документа:


&НаКлиенте
Процедура Расш1_ГрафикРаботыПриИзмененииПосле(Элемент)
    
    // Выясним причину изменения и установим порядок пересчета
    Если ЗначениеЗаполнено(Объект.ГрафикРаботы) Тогда
        
        // Получаем наименование графика для условия
        // Внимание: поиск по наименованию считается "хрупким", 
        // лучше использовать дополнительные реквизиты графика
        НаименованиеГрафика = СокрЛП(Объект.ГрафикРаботы.Наименование);
        
        Если НаименованиеГрафика = "Основной пятидневка" Тогда
            Объект.ПорядокПересчета = ПредопределенноеЗначение("Перечисление.ПорядокПересчетаСтоимостиЧаса.ПоНормеГрафика");
        Иначе
            Объект.ПорядокПересчета = ПредопределенноеЗначение("Перечисление.ПорядокПересчетаСтоимостиЧаса.ПоСреднемесячнойНорме");
        КонецЕсли;
        
    КонецЕсли;
    
КонецПроцедуры

Выясним некоторые технические нюансы. В документе ПриемНаРаботу поле ПорядокПересчета может быть недоступно для редактирования, если в настройках расчета зарплаты (раздел Настройка — Расчет зарплаты) установлен фиксированный порядок для всей организации. Чтобы наша доработка имела смысл, в настройках должна быть активна опция «При изменении нормы времени в течение месяца».

Рекомендации по работе с расширениями

При написании кода в расширениях всегда придерживайтесь следующих правил:

  1. Используйте аннотации &После или &Вместо крайне осторожно. Для простых проверок идеально подходит &После, так как она не заменяет типовую логику, а дополняет её.
  2. Всегда проверяйте ЗначениеЗаполнено() для ссылочных полей, чтобы избежать ошибок при обращении к свойствам пустой ссылки (например, Объект.ГрафикРаботы.Наименование вызовет ошибку, если график не выбран).
  3. Помните о списочных документах. В 1С:ERP документ ПриемНаРаботу может быть как на одного сотрудника, так и списком (ПриемНаРаботуСписком). Если в вашей компании используются оба вида, код необходимо продублировать или вынести в общий модуль расширения, учитывая, что в списочном документе данные хранятся в табличной части.

Таким образом, мы рассмотрели, как с помощью нескольких строк кода и механизма расширений можно значительно упростить работу кадровой службы, автоматизировав рутинные проверки и заполнение данных в 1С:ERP.

← На главную