Многие разработчики и администраторы систем на базе «1С:Зарплата и управление персоналом 3.1» (а также 1С:ERP и 1С:Комплексная автоматизация) сталкиваются с неприятной ситуацией: после очередного обновления конфигурации (начиная с версий 3.1.6/3.1.7) во внешних отчетах, печатных формах или обработках обмена начинают пропадать данные о сотрудниках. При детальном анализе выясняется, что популярный и очень удобный ранее регистр сведений ТекущиеКадровыеДанныеСотрудников заполняется лишь частично. В нем остаются заполненными поля сотрудника, даты приема и увольнения, но колонки Подразделение, Должность, ТекущийВидЗанятости и ОсновноеРабочееМесто остаются абсолютно пустыми для новых кадровых документов.
В этой статье мы подробно разберем, почему разработчики фирмы «1С» приняли такое решение, куда теперь переместились эти данные и какими способами их нужно получать, чтобы ваши доработки больше никогда не ломались при обновлениях конфигурации.
Для начала проанализируем причины такого поведения системы. Разработчики «1С» официально подтвердили, что частичное заполнение регистра сведений ТекущиеКадровыеДанныеСотрудников — это не баг, а задуманное поведение (by design). Логика развития подсистемы кадрового учета ЗУП 3.1 привела к отказу от дублирования оперативной информации в плоских непериодических таблицах.
Почему же реквизиты не были удалены или помечены префиксом «Удалить»? Дело в том, что данный регистр входит в состав Зарплатно-кадровой библиотеки (ЗКБ), которая активно используется в других решениях (например, в «1С:Бухгалтерии предприятия» или различных отраслевых конфигурациях). Чтобы не разрушать совместимость между продуктами, которые могут обновляться с разной периодичностью, структуру регистра оставили прежней, но перестали записывать туда избыточные данные.
Теперь вся оперативная кадровая информация рассчитывается динамически или берется из специализированных периодических регистров сведений:
КадроваяИсторияСотрудников (и его техническом аналоге — интервальном регистре).ВидыЗанятостиСотрудников.РолиСотрудников.Ниже мы подробно рассмотрим три основных метода решения этой проблемы в зависимости от ваших задач: от простых прямых запросов до использования профессионального программного интерфейса и механизмов СКД.
Если вам нужно срочно «починить» старый отчет или печатную форму, а времени на глобальную переработку кода нет, можно пойти по пути прямого обращения к новым регистрам сведений. Вместо чтения одного регистра ТекущиеКадровыеДанныеСотрудников нам придется левым соединением собрать данные из срезов последних других регистров.
Рассмотрим пример запроса, который собирает актуальные кадровые данные на определенную дату:
ВЫБРАТЬ
Сотрудники.Ссылка КАК Сотрудник,
КадроваяИсторияСрезПоследних.Подразделение КАК Подразделение,
КадроваяИсторияСрезПоследних.Должность КАК Должность,
ВидыЗанятостиСрезПоследних.ВидЗанятости КАК ВидЗанятости,
КадроваяИсторияПрием.Период КАК ДатаПриема,
КадроваяИсторияУвольнение.Период КАК ДатаУвольнения
ИЗ
Справочник.Сотрудники КАК Сотрудники
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КадроваяИсторияСотрудников.СрезПоследних(&Период, ) КАК КадроваяИсторияСрезПоследних
ПО Сотрудники.Ссылка = КадроваяИсторияСрезПоследних.Сотрудник
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ВидыЗанятостиСотрудников.СрезПоследних(&Период, ) КАК ВидыЗанятостиСрезПоследних
ПО Сотрудники.Ссылка = ВидыЗанятостиСрезПоследних.Сотрудник
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КадроваяИсторияСотрудников КАК КадроваяИсторияПрием
ПО Сотрудники.Ссылка = КадроваяИсторияПрием.Сотрудник
И КадроваяИсторияПрием.ВидСобытия = ЗНАЧЕНИЕ(Перечисление.ВидыКадровыхСобытий.Прием)
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КадроваяИсторияСотрудников КАК КадроваяИсторияУвольнение
ПО Сотрудники.Ссылка = КадроваяИсторияУвольнение.Сотрудник
И КадроваяИсторияУвольнение.ВидСобытия = ЗНАЧЕНИЕ(Перечисление.ВидыКадровыхСобытий.Увольнение)
Важное предупреждение: Этот подход прост в реализации, но несет в себе огромные риски. Фирма «1С» активно развивает и оптимизирует структуру своих регистров. Физические таблицы (особенно интервальные регистры кадровой истории) могут измениться в любой момент. Если вы напишете десятки таких запросов в своих печатных формах, то при следующем крупном обновлении конфигурации вам придется переписывать их заново.
Чтобы защитить свои разработки от будущих изменений в структуре метаданных, крайне рекомендуется уйти от «физического» уровня таблиц к «логическому» уровню программного интерфейса ЗУП 3.1. Разработчики конфигурации уже написали за нас все сложные запросы и объединили их в удобные методы общих модулей. Если структура регистров изменится, разработчики «1С» сами обновят код внутри этих общих модулей, а ваш код останется работоспособным.
Для получения актуальных данных по списку сотрудников используется экспортный метод КадровыеДанныеСотрудников общего модуля КадровыйУчет. Проанализируем, как с ним работать.
Разберем готовый пример кода, который получает подразделение, должность и вид занятости для списка сотрудников на текущую дату:
// 1. Формируем массив сотрудников, по которым нужны данные
СписокСотрудников = Новый Массив;
СписокСотрудников.Добавить(ВыбранныйСотрудник); // Ссылка на Справочник.Сотрудники
// 2. Строкой через запятую перечисляем только те поля, которые нам необходимы
ПоляКадровыхДанных = "Организация,Подразделение,Должность,ВидЗанятости,ДатаПриема,ДатаУвольнения";
// 3. Вызываем программный интерфейс кадрового учета
ТаблицаДанных = КадровыйУчет.КадровыеДанныеСотрудников(Истина, СписокСотрудников, ПоляКадровыхДанных, ТекущаяДата());
// 4. Обходим полученную таблицу значений с результатами
Для Каждого СтрокаДанных Из ТаблицаДанных Цикл
ТекущееПодразделение = СтрокаДанных.Подразделение;
ТекущаяДолжность = СтрокаДанных.Должность;
ТекущийВидЗанятости = СтрокаДанных.ВидЗанятости;
// Выполняем полезную работу с полученными переменными
КонецЦикла;
Этот метод работает чрезвычайно быстро, учитывает права доступа пользователя (благодаря первому параметру ТолькоРазрешенные) и гарантирует стабильность при обновлениях. Если вам нужно использовать этот механизм внутри своего сложного запроса, вы можете предварительно подготовить временную таблицу с сотрудниками и передать менеджер временных таблиц в метод КадровыйУчет.СоздатьНаДатуВТКадровыеДанныеСотрудников.
Что делать, если вы разрабатываете сложный отчет на Системе компоновки данных (СКД), где нельзя просто вызвать процедуру общего модуля в коде? Специально для этого в ЗУП 3.1 реализован механизм общих запросов и виртуальных представлений.
Разберем по шагам, как интегрировать кадровые данные в отчет на СКД без прямых запросов к регистрам:
Представления_КадровыеДанныеСотрудников.Рассмотрим пример запроса-пустышки, который необходимо поместить в ваш набор данных СКД:
ВЫБРАТЬ РАЗРЕШЕННЫЕ
ВТСотрудники.Сотрудник КАК Сотрудник,
ЗНАЧЕНИЕ(Справочник.Организации.ПустаяСсылка) КАК Организация,
ЗНАЧЕНИЕ(Справочник.ПодразделенияОрганизаций.ПустаяСсылка) КАК Подразделение,
ЗНАЧЕНИЕ(Справочник.Должности.ПустаяСсылка) КАК Должность,
ЗНАЧЕНИЕ(Перечисление.ВидыЗанятости.ПустаяСсылка) КАК ВидЗанятости,
ДАТАВРЕМЯ(1, 1, 1) КАК ДатаПриема,
ДАТАВРЕМЯ(1, 1, 1) КАК ДатаУвольнения
ПОМЕСТИТЬ Представления_КадровыеДанныеСотрудников
ИЗ
ВТСотрудники КАК ВТСотрудники
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
Представления_КадровыеДанныеСотрудников.Сотрудник,
Представления_КадровыеДанныеСотрудников.Организация,
Представления_КадровыеДанныеСотрудников.Подразделение,
Представления_КадровыеДанныеСотрудников.Должность,
Представления_КадровыеДанныеСотрудников.ВидЗанятости,
Представления_КадровыеДанныеСотрудников.ДатаПриема,
Представления_КадровыеДанныеСотрудников.ДатаУвольнения
ИЗ
Представления_КадровыеДанныеСотрудников КАК Представления_КадровыеДанныеСотрудников
После того как схема компоновки подготовлена, в модуле отчета (в процедуре ПриКомпоновкеРезультата) или в коде инициализации формы отчета необходимо написать вызов процедуры, выполняющей подмену:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
// Инициализируем настройки компоновщика
НастройкиОтчета = КомпоновщикНастроек.ПолучитьНастройки();
// Вызываем механизм автоматического заполнения общих источников данных ЗКБ
ЗарплатаКадрыОбщиеНаборыДанных.ЗаполнитьОбщиеИсточникиДанныхОтчета(ЭтотОбъект, НастройкиОтчета);
// Выполняем стандартную компоновку с уже измененными запросами
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, НастройкиОтчета, ДанныеРасшифровки);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки, Истина);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
КонецПроцедуры
Этот изящный метод позволяет динамически формировать запросы любой сложности. Система сама определит, какие поля выбрал пользователь в настройках СКД, и оптимизирует запрос к базе данных так, чтобы не выбирать лишнюю информацию из кадровых регистров.
Отказ от классического ведения регистра ТекущиеКадровыеДанныеСотрудников может спровоцировать появление скрытых ошибок, о которых важно знать заранее:
1. Ошибка «Сотрудник не принят на работу» в расчетах среднего заработка. Иногда при расчете отпусков или командировок программа выдает ошибку о том, что сотрудник не принят на работу, хотя кадровый документ проведения существует. Это происходит из-за того, что в РС ТекущиеКадровыеДанныеСотрудников не установился флаг ОформленПоТрудовомуДоговору. Решается перепроведением документа приема или программной перезаписью этого флага.
2. Проблемы с подбором договорников (ГПХ). При заполнении ведомостей на выплату через форму подбора договорники ГПХ могут неожиданно исчезнуть из списков. Это происходит в тех случаях, когда при обновлении или переносе данных из старых баз некорректно заполнился регистр РолиСотрудников, который теперь работает в связке с кадровыми данными. Рекомендуется запустить тестирование и исправление базы данных или выполнить пересохранение карточек проблемных сотрудников.
Выводы: Мир программирования под ЗУП 3.1 требует изменения подходов. Использование прямых запросов к регистрам постепенно уходит в прошлое. Использование встроенного программного интерфейса (API) общих модулей и механизмов представлений СКД гарантирует, что ваши отчеты и обработки будут служить долгие годы без необходимости постоянной доработки после каждого обновления системы.