Как исправить ошибку расчета дней и вытеснения в 1С:ЗУП 3.1 при использовании РИБ и документа «Табель»?

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

При работе в распределенных информационных базах (РИБ) на платформе 1С:Предприятие 8.3 пользователи и администраторы периодически сталкиваются с загадочным поведением программы. Одна из таких сложных ситуаций возникает в программе 1С:Зарплата и Управление Персоналом 3.1, когда расчет зарплаты за текущий месяц в центральной базе выполняется абсолютно корректно, а в подчиненном узле РИБ ломается, начисляя сотруднику существенно меньше рабочих дней (например, 4 дня вместо положенных 14). При этом в файловой копии базы расчет также может проходить без ошибок.

В этой статье мы подробно разберем методологические и технические причины этой коллизии, выясним, какую роль в этом играет документ Табель, проанализируем особенности обмена данными в РИБ и предложим пошаговый алгоритм решения проблемы.

Суть коллизии: вытеснение времени и наложение документов

Рассмотрим классическую расчетную ситуацию:

  1. В предыдущем отчетном периоде (например, в мае) сотруднику был оформлен документ Отсутствие (болезнь, прогул, неявка). Этот документ зарегистрировал неоплачиваемое отсутствие.
  2. В текущем периоде (в июне) сотрудник приносит больничные листы, которые полностью или частично перекрывают период майской неявки, а также захватывают дни июня.
  3. При проведении больничных листов в июне программа должна автоматически сторнировать (вытеснить) неоплачиваемое время майского отсутствия и заменить его оплачиваемым временем по болезни.

В нормальных условиях при расчете зарплаты за июнь программа должна автоматически определить, какие периоды были вытеснены, скорректировать норму и отработанное время и начислить зарплату за все фактически отработанные дни июня (в нашем случае — за 14 дней). Однако на практике расчетный механизм дает сбой, начисляя зарплату только за 4 дня. Выясним, почему это происходит.

Причина №1: Разрушительное влияние документа «Табель»

В методологии учета рабочего времени в 1С:ЗУП 3.1 документ Табель имеет абсолютный приоритет. Программа проектировалась с расчетом на то, что учет времени ведется по отклонениям от графика работы, а сам документ Табель вводится только в крайних случаях (когда нужно отразить сложные, нетиповые изменения времени, которые невозможно зарегистрировать обычными документами-отклонениями).

Если документ Табель уже создан и проведен в информационной базе, он буквально «замораживает» картину рабочего времени. Любые проведенные позже документы-отклонения (такие как новые больничные листы) не смогут автоматически скорректировать данные для расчета начислений, поскольку расчетный модуль будет принудительно брать данные об отработанных днях и часах именно из проведенного Табеля. В результате возникает ситуация, когда сам отчет «Табель» и расчет начислений показывают некорректные 4 дня, хотя в кадровом учете больничные зарегистрированы правильно.

Причина №2: Специфика РИБ и режим загрузки данных

Почему же в центральном узле РИБ (или при локальном расчете в файловой копии) все считается правильно, а в подчиненном узле данные ломаются? Ответ кроется в механизмах платформы 1С по обмену данными в распределенных базах.

Когда данные переносятся из центральной базы в подчиненную, запись объектов (документов, справочников и движений регистров) происходит при установленном свойстве ОбменДанными.Загрузка = Истина. Этот режим имеет ключевые особенности:

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

Пошаговый алгоритм решения проблемы

Чтобы восстановить корректный расчет и устранить рассогласование данных между узлами РИБ, выполним следующие шаги.

Шаг 1. Устранение конфликта с документом «Табель»

Прежде всего необходимо разблокировать расчет времени. Для этого в подчиненном узле (или в центральной базе с последующим обменом) выполним следующие действия:

  1. Найдем и временно распроведем документ Начисление зарплаты и взносов за июнь по проблемному сотруднику.
  2. Найдем документ Табель за июнь, в который входит данный сотрудник, и распроведем его. Важно: если учет времени ведется по графикам, этот документ вообще рекомендуется удалить или исключить из него сотрудника.
  3. Заново перепроведем цепочку документов отклонений в хронологическом порядке: сначала майский документ Отсутствие (болезнь, прогул, неявка), затем июньские документы Больничный лист. Это заставит систему правильно сформировать движения вытеснения времени.
  4. Если документ Табель действительно необходим, откроем его, перезаполним по сотруднику (убедившись, что теперь там подтягивается корректное время — 14 дней) и проведем.
  5. Создадим заново или перезаполним документ Начисление зарплаты и взносов.

Шаг 2. Принудительное перепроведение документов в подчиненном узле

Если проблема вызвана тем, что при загрузке через РИБ заблокировались внутренние механизмы проведения, нам нужно заставить подчиненную базу перепровести документы в «обычном» режиме (с выключенным флагом загрузки). Для этого напишем и запустим в подчиненном узле простую обработку, которая перепроведет документы, заново сформировав все интервальные регистры.

Рассмотрим пример кода для принудительного проведения документов без режима загрузки обмена:


Процедура ПерепровестиДокументыБезРежимаЗагрузки(МассивСсылок) Экспорт
    Для Каждого СсылкаНаДок Из МассивСсылок Цикл
        ДокОбъект = СсылкаНаДок.ПолучитьОбъект();
        Если ДокОбъект <> Неопределено Тогда
            // Принудительно сбрасываем признак загрузки обмена данными
            ДокОбъект.ОбменДанными.Загрузка = Ложь;
            Попытка
                // Проводим документ с вызовом всех обработчиков и бизнес-логики
                ДокОбъект.Записать(РежимЗаписиДокумента.Проведение);
                Сообщить("Документ успешно перепроведен: " + Строка(СсылкаНаДок));
            Исключение
                Сообщить("Ошибка проведения документа " + Строка(СсылкаНаДок) + ": " + ОписаниеОшибки());
            КонецПопытки;
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

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

Шаг 3. Перерегистрация изменений в центральной базе

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

  1. В центральной базе откроем обработку «Регистрация изменений для обмена».
  2. Найдем узел обмена, соответствующий подчиненной базе.
  3. Добавим в список зарегистрированных объектов проблемные документы: Отсутствие (болезнь, прогул, неявка), все июньские Больничный лист и документ Начисление зарплаты и взносов.
  4. Зарегистрируем изменения не только для самих документов, но и для связанных с ними регистров сведений (в первую очередь — СостоянияСотрудников).
  5. Запустим сеанс обмена данными. При загрузке в подчиненный узел актуальные движения перезапишут поврежденные записи.

Шаг 4. Анализ регистров с помощью Универсального отчета

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

Проанализируем записи по следующим регистрам:

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

← На главную