При работе в распределенных информационных базах (РИБ) на платформе 1С:Предприятие 8.3 пользователи и администраторы периодически сталкиваются с загадочным поведением программы. Одна из таких сложных ситуаций возникает в программе 1С:Зарплата и Управление Персоналом 3.1, когда расчет зарплаты за текущий месяц в центральной базе выполняется абсолютно корректно, а в подчиненном узле РИБ ломается, начисляя сотруднику существенно меньше рабочих дней (например, 4 дня вместо положенных 14). При этом в файловой копии базы расчет также может проходить без ошибок.
В этой статье мы подробно разберем методологические и технические причины этой коллизии, выясним, какую роль в этом играет документ Табель, проанализируем особенности обмена данными в РИБ и предложим пошаговый алгоритм решения проблемы.
Рассмотрим классическую расчетную ситуацию:
Отсутствие (болезнь, прогул, неявка). Этот документ зарегистрировал неоплачиваемое отсутствие.В нормальных условиях при расчете зарплаты за июнь программа должна автоматически определить, какие периоды были вытеснены, скорректировать норму и отработанное время и начислить зарплату за все фактически отработанные дни июня (в нашем случае — за 14 дней). Однако на практике расчетный механизм дает сбой, начисляя зарплату только за 4 дня. Выясним, почему это происходит.
В методологии учета рабочего времени в 1С:ЗУП 3.1 документ Табель имеет абсолютный приоритет. Программа проектировалась с расчетом на то, что учет времени ведется по отклонениям от графика работы, а сам документ Табель вводится только в крайних случаях (когда нужно отразить сложные, нетиповые изменения времени, которые невозможно зарегистрировать обычными документами-отклонениями).
Если документ Табель уже создан и проведен в информационной базе, он буквально «замораживает» картину рабочего времени. Любые проведенные позже документы-отклонения (такие как новые больничные листы) не смогут автоматически скорректировать данные для расчета начислений, поскольку расчетный модуль будет принудительно брать данные об отработанных днях и часах именно из проведенного Табеля. В результате возникает ситуация, когда сам отчет «Табель» и расчет начислений показывают некорректные 4 дня, хотя в кадровом учете больничные зарегистрированы правильно.
Почему же в центральном узле РИБ (или при локальном расчете в файловой копии) все считается правильно, а в подчиненном узле данные ломаются? Ответ кроется в механизмах платформы 1С по обмену данными в распределенных базах.
Когда данные переносятся из центральной базы в подчиненную, запись объектов (документов, справочников и движений регистров) происходит при установленном свойстве ОбменДанными.Загрузка = Истина. Этот режим имеет ключевые особенности:
ОбработкаПроведения не выполняются).СостоянияСотрудников или КадроваяИсторияСотрудниковИнтервальный) не была передана, подчиненная база не будет пересчитывать их автоматически при записи документа.Если в подчиненном узле РИБ у исправленного документа зависли старые движения (то есть не очистилась регистрация изменений после взаимного обмена), то регистры подчиненного узла продолжают хранить неверную информацию о состоянии сотрудника. Программа считает, что старая неявка все еще действует, и «срезает» оплачиваемые рабочие дни при расчете зарплаты.
Чтобы восстановить корректный расчет и устранить рассогласование данных между узлами РИБ, выполним следующие шаги.
Прежде всего необходимо разблокировать расчет времени. Для этого в подчиненном узле (или в центральной базе с последующим обменом) выполним следующие действия:
Начисление зарплаты и взносов за июнь по проблемному сотруднику.Табель за июнь, в который входит данный сотрудник, и распроведем его. Важно: если учет времени ведется по графикам, этот документ вообще рекомендуется удалить или исключить из него сотрудника.Отсутствие (болезнь, прогул, неявка), затем июньские документы Больничный лист. Это заставит систему правильно сформировать движения вытеснения времени.Табель действительно необходим, откроем его, перезаполним по сотруднику (убедившись, что теперь там подтягивается корректное время — 14 дней) и проведем.Начисление зарплаты и взносов.Если проблема вызвана тем, что при загрузке через РИБ заблокировались внутренние механизмы проведения, нам нужно заставить подчиненную базу перепровести документы в «обычном» режиме (с выключенным флагом загрузки). Для этого напишем и запустим в подчиненном узле простую обработку, которая перепроведет документы, заново сформировав все интервальные регистры.
Рассмотрим пример кода для принудительного проведения документов без режима загрузки обмена:
Процедура ПерепровестиДокументыБезРежимаЗагрузки(МассивСсылок) Экспорт
Для Каждого СсылкаНаДок Из МассивСсылок Цикл
ДокОбъект = СсылкаНаДок.ПолучитьОбъект();
Если ДокОбъект <> Неопределено Тогда
// Принудительно сбрасываем признак загрузки обмена данными
ДокОбъект.ОбменДанными.Загрузка = Ложь;
Попытка
// Проводим документ с вызовом всех обработчиков и бизнес-логики
ДокОбъект.Записать(РежимЗаписиДокумента.Проведение);
Сообщить("Документ успешно перепроведен: " + Строка(СсылкаНаДок));
Исключение
Сообщить("Ошибка проведения документа " + Строка(СсылкаНаДок) + ": " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Запуск этого кода по отношению к проблемным больничным листам и неявкам в подчиненной базе гарантированно очистит «зависшие» движения и пересчитает фактическое время сотрудника.
Чтобы предотвратить повторное затирание данных при следующем сеансе синхронизации, мы должны принудительно отправить правильные движения из центральной базы в подчиненную. Для этого выполним регистрацию объектов вручную:
Отсутствие (болезнь, прогул, неявка), все июньские Больничный лист и документ Начисление зарплаты и взносов.СостоянияСотрудников).Для окончательной проверки и локализации скрытых нестыковок в движениях воспользуемся стандартным инструментом платформы — Универсальным отчетом. Мы можем сформировать его отдельно в центральной базе и отдельно в подчиненном узле, после чего сравнить результаты.
Проанализируем записи по следующим регистрам:
Состояния сотрудников: проверим, какие периоды зафиксированы для сотрудника. Если в подчиненном узле на период больничного все еще накладывается состояние «Неявка по невыясненным причинам», значит, вытеснение не отработало.Начисления: посмотрим на колонки «Отработано дней» и «Оплачено дней». Это позволит точно увидеть, какой документ начислил «лишние» дни отсутствия или проигнорировал дни болезни.Сравнив детальные записи регистров двух баз, мы сможем безошибочно выявить «зависший» набор записей и скорректировать его одним из описанных выше способов.