Разработка внешней печатной формы (ВПФ) для трудового договора — одна из самых частых задач, с которой сталкивается программист 1С при автоматизации кадрового учета. На первый взгляд задача кажется простой: нужно спроектировать макет и заполнить его данными из информационной базы. Однако на практике разработчики часто сталкиваются с трудностями при попытке получить актуальную дату приема сотрудника, его действующую тарифную ставку (оклад), а также при выделении конкретных составляющих адреса (например, только города проживания) из контактной информации.
В этой статье мы подробно разберем, как правильно решать эти задачи в современных конфигурациях на платформе «1С:Предприятие 8» (таких как ЗУП 3.1, ERP 2, КА 2), использующих Библиотеку Стандартных Подсистем (БСП). Мы откажемся от ненадежных прямых запросов к документам и рассмотрим использование профессиональных механизмов БСП, гарантирующих получение точных и актуальных данных.
В процессе обсуждения на форумах часто звучит совет: «Возьмите дату приема и оклад напрямую из документа ПриемНаРаботу». Рассмотрим, почему этот путь ведет к ошибкам в реальной эксплуатации системы:
КадровыйПеревод. Если печатная форма обращается только к первичному документу приема, она выведет устаревшие данные.Поэтому правильным подходом является обращение к специализированным регистрам сведений («Кадровая история сотрудников», «Плановые начисления») или, что еще лучше, использование программного интерфейса (API) самой конфигурации.
Для получения актуальных кадровых сведений на определенную дату разработчики БСП предусмотрели мощный инструмент — программный интерфейс общего модуля КадровыйУчет. Функция КадровыеДанныеСотрудников позволяет получить любые кадровые свойства сотрудника в виде таблицы значений, автоматически учитывая все кадровые перемещения.
Проанализируем пример кода, с помощью которого мы можем гарантированно получить дату приема сотрудника, его должность и подразделение:
// Формируем массив сотрудников (даже если у нас один сотрудник, метод требует массив)
МассивСотрудников = Новый Массив;
МассивСотрудников.Добавить(СсылкаНаСотрудника);
// Определяем список необходимых полей через запятую
Поля = "ДатаПриема,Подразделение,Должность,Организация";
// Вызываем программный интерфейс БСП на нужную дату (например, на текущую дату сеанса)
ТаблицаКадровыхДанных = КадровыйУчет.КадровыеДанныеСотрудников(Истина, МассивСотрудников, Поля, ТекущаяДатаСеанса());
// Проверяем результат и извлекаем данные
Если ТаблицаКадровыхДанных.Количество() > 0 Тогда
СтрокаДанных = ТаблицаКадровыхДанных[0];
ДатаПриема = СтрокаДанных.ДатаПриема;
Должность = СтрокаДанных.Должность;
Подразделение = СтрокаДанных.Подразделение;
КонецЕсли;
Этот метод хорош тем, что платформа сама выполняет оптимизированный запрос к нужным регистрам сведений, освобождая нас от необходимости писать и отлаживать сложные соединения вручную.
Размер оклада сотрудника хранится в регистре сведений ПлановыеНачисления. Поскольку у сотрудника может быть несколько одновременно действующих начислений (например, Оклад и Ежемесячная премия), нам нужно получить именно показатель тарифной ставки.
Для этого мы можем использовать запрос к срезу последних регистра сведений или применить функции общего модуля ОплатаТруда. Рассмотрим пример получения оклада через срез последних плановых начислений с отбором по сотруднику:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
| ПлановыеНачисленияСрезПоследних.Показатель1 КАК Оклад
|ИЗ
| РегистрСведений.ПлановыеНачисления.СрезПоследних(&Период, Сотрудник = &Сотрудник) КАК ПлановыеНачисленияСрезПоследних
|ГДЕ
| ПлановыеНачисленияСрезПоследних.Активность";
Запрос.УстановитьПараметр("Период", ТекущаяДатаСеанса());
Запрос.УстановитьПараметр("Сотрудник", СсылкаНаСотрудника);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
ТарифнаяСтавка = Выборка.Оклад;
Иначе
ТарифнаяСтавка = 0;
КонецЕсли;
Важный нюанс: В различных конфигурациях имя показателя оклада может отличаться (например, Показатель1, ТарифнаяСтавка или Размер). Перед написанием запроса рекомендуется изучить структуру регистра РегистрСведений.ПлановыеНачисления в вашей конкретной базе конфигуратором.
В процессе обсуждения возникла проблема: при попытке получить представление адреса система возвращала электронную почту организации. Выясним причину этой классической ошибки.
Она кроется в некорректном условии связи (ЛЕВОЕ СОЕДИНЕНИЕ) в тексте запроса. Когда разработчик связывает таблицу физических лиц с таблицей контактной информации, он часто забывает наложить жесткий отбор на Вид контактной информации непосредственно в условии связи. В результате СУБД соединяет записи по принципу «многие ко многим» или берет первую попавшуюся строчку КИ, которой часто оказывается рабочий Email организации или телефон, а не адрес проживания физического лица.
Ниже мы разберем три проверенных и надежных способа извлечения города проживания сотрудника, которые полностью исключают подобные ошибки.
В современных конфигурациях 1С адресная информация хранится в сложном структурированном виде (XML или JSON) для обеспечения интеграции со справочниками ФИАС/ГАР. Попытка прочитать город простым запросом к реквизиту адреса часто возвращает пустое значение, так как плоские поля больше не заполняются напрямую.
Лучший способ получить город — запросить XML-строку адреса и передать ее в функцию общего модуля БСП РаботаСАдресами. Этот модуль самостоятельно распарсит XML-структуру и вернет название населенного пункта.
// 1. Получаем таблицу контактной информации сотрудника по нужному виду
ТаблицаКИ = УправлениеКонтактнойИнформацией.КонтактнаяИнформацияОбъекта(
ФизическоеЛицо,
Справочники.ВидыКонтактнойИнформации.ЮрАдресФизЛица // Адрес по прописке
);
Город = "";
Если ТаблицаКИ.Количество() > 0 Тогда
// Получаем XML-представление адреса из колонки "Значение"
XMLАдреса = ТаблицаКИ[0].Значение;
// 2. Используем функцию БСП для вычленения города
Город = РаботаСАдресами.ГородАдресаКонтактнойИнформации(XMLАдреса);
КонецЕсли;
Преимущество этого способа: Метод ГородАдресаКонтактнойИнформации корректно отрабатывает сложные случаи. Например, для городов федерального значения (Москва, Санкт-Петербург, Севастополь) поле «Город» в классификаторе может отсутствовать, а само название города записывается в поле «Регион». Функция БСП учитывает эти особенности и вернет правильное название.
Если в вашей версии конфигурации контактная информация внутри поля Значение сохраняется в формате JSON, мы можем пойти по пути прямого разбора этой структуры. Преобразуем строку JSON в структуру 1С и заберем нужное свойство.
ТаблицаКИ = УправлениеКонтактнойИнформацией.КонтактнаяИнформацияОбъекта(
ФизическоеЛицо,
Справочники.ВидыКонтактнойИнформации.ЮрАдресФизЛица
);
Город = "";
Если ТаблицаКИ.Количество() > 0 Тогда
СтрокаJSON = ТаблицаКИ[0].Значение;
// Преобразуем строку JSON в структуру 1С с помощью системных механизмов
СтруктураАдреса = УправлениеКонтактнойИнформациейСлужебный.СтрокуJSONВСтруктуру(СтрокаJSON);
// Проверяем наличие ключа "city" в структуре адреса
Если СтруктураАдреса.Свойство("city") Тогда
Город = СтруктураАдреса.city;
// Если это город федерального значения, проверяем свойство "area" (регион)
ИначеЕсли СтруктураАдреса.Свойство("area") Тогда
Город = СтруктураАдреса.area;
КонецЕсли;
КонецЕсли;
Если вам необходимо вытащить данные пакетом в одном большом запросе (например, при подготовке источника данных для схемы компоновки данных (СКД)), то соединение со справочником физических лиц и их контактной информацией должно быть строго ограничено по виду КИ.
Посмотрим, как выглядит правильный, безопасный запрос, который никогда не вернет email или телефон вместо адреса:
ВЫБРАТЬ
ФизическиеЛица.Ссылка КАК ФизЛицо,
ЕСТЬNULL(ТаблицаКИ.Представление, "") КАК АдресПропискиПредставление,
ЕСТЬNULL(ТаблицаКИ.Значение, "") КАК АдресПропискиЗначение
ИЗ
Справочник.ФизическиеЛица КАК ФизическиеЛица
// Соединяем строго с табличной частью контактной информации физлица
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ФизическиеЛица.КонтактнаяИнформация КАК ТаблицаКИ
ПО ФизическиеЛица.Ссылка = ТаблицаКИ.Ссылка
И ТаблицаКИ.Вид = ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации.ЮрАдресФизЛица)
ГДЕ
ФизическиеЛица.Ссылка = &ФизическоеЛицо
Обратите внимание на конструкцию соединения. Мы связываем физическое лицо с его табличной частью контактной информации Справочник.ФизическиеЛица.КонтактнаяИнформация, накладывая условие ПО ТаблицаКИ.Вид = ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации.ЮрАдресФизЛица) прямо в секции связи. Это гарантирует, что в выборку попадет только адрес по прописке и никакие другие типы контактных данных.
Мы успешно разобрали основные сложности, возникающие при подготовке данных для внешней печатной формы трудового договора. Подведем итоги совместной работы:
КадровыйУчет. Это избавит вас от ошибок, связанных с кадровыми переводами сотрудников в будущем.ПлановыеНачисления на дату формирования договора.РаботаСАдресами или УправлениеКонтактнойИнформацией для парсинга XML/JSON-значений адресов, чтобы корректно определять города (включая города федерального значения).Использование этих стандартов разработки сделает вашу внешнюю печатную форму отказоустойчивой, производительной и независимой от последующих обновлений типовой конфигурации 1С.