При разработке внешних печатных форм в конфигурациях на базе 1С, таких как Зарплата и управление персоналом, часто возникает необходимость вывести один и тот же отчет из разных мест: из документа и из карточки справочника. Рассмотрим, почему возникает ошибка при простом переносе кода и как правильно перестроить логику получения данных.
Основная причина заключается в разной архитектуре объектов 1С. Документ ПриемНаРаботу — это событие, в котором уже зафиксированы данные на момент приема (организация, должность, подразделение, ФИО и т.д.). Справочник Сотрудники — это лишь «карточка» человека, которая сама по себе не хранит историю кадровых изменений. В современных конфигурациях 1С данные о должности, подразделении и графике работы вынесены в периодические РегистрыСведений (например, КадроваяИсторияСотрудников).
Когда вы пытаетесь выполнить запрос, написанный для документа, система обращается к полям, которых в справочнике Сотрудники физически нет (например, поле Организация в справочнике заменено на ГоловнаяОрганизация, а кадровые данные отсутствуют вовсе). Это приводит либо к ошибке «Поле объекта не обнаружено», либо к «зависанию» системы при попытке инициализировать пустую выборку.
Для того чтобы печатная форма работала из карточки сотрудника, необходимо полностью переписать текст запроса. Мы не можем просто сослаться на СсылкаНаОбъект как на документ. Нам нужно получить актуальные сведения на текущую дату через механизмы СрезПоследних.
Рассмотрим пример правильного построения запроса для получения данных сотрудника:
ВЫБРАТЬ
ФИОФизЛиц.Фамилия КАК Фамилия,
ФИОФизЛиц.Имя КАК Имя,
ФИОФизЛиц.Отчество КАК Отчество,
КадроваяИсторияСотрудниковСрезПоследних.Должность КАК Должность,
КадроваяИсторияСотрудниковСрезПоследних.Подразделение КАК Подразделение,
АдресРегистрации.Представление КАК АдресРегистрации
ИЗ
Справочник.Сотрудники КАК Сотрудник
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ФИОФизическихЛиц.СрезПоследних(&ДатаДокумента, ФизическоеЛицо = &Физлицо) КАК ФИОФизЛиц
ПО (ИСТИНА)
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КадроваяИсторияСотрудников.СрезПоследних(&ДатаДокумента, Сотрудник = &Сотрудник) КАК КадроваяИсторияСотрудниковСрезПоследних
ПО (ИСТИНА)
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ФизическиеЛица.КонтактнаяИнформация КАК АдресРегистрации
ПО АдресРегистрации.Ссылка = &Физлицо
И (АдресРегистрации.Вид = ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации.АдресПоПропискеФизическиеЛица))
ГДЕ
Сотрудник = &Сотрудник
После подготовки запроса важно правильно передать параметры. Если вы используете метод Запрос.УстановитьПараметр, убедитесь, что дата документа (или ТекущаяДата()) передается корректно. Это критически важно для работы виртуальных таблиц СрезПоследних, так как именно по дате 1С определяет «актуальные» данные.
Сотрудники используйте ТекущаяДата() или дату, на которую должен быть сформирован договор.КадровыйУчет. Это позволит избежать проблем, если у пользователя настроены ограничения на просмотр данных определенных организаций или подразделений.Чтобы не переписывать код дважды, мы рекомендуем разделить логику формирования ВПФ на три этапа:
СтруктурыПараметров — одну для документа, другую для справочника. Они обе должны возвращать идентичную структуру, которую потом будет «читать» процедура заполнения Word-документа.Замена.Execute, без изменений. Пусть она получает на вход готовую структуру, не заботясь о том, откуда именно были взяты данные.КадровыйУчетРасширенный или КадровыйУчет, чтобы избежать ручного расчета в запросе — это защитит вас от ошибок при смене законодательства.Следуя этим шагам, вы сможете превратить свою внешнюю печатную форму в универсальный инструмент, который будет стабильно работать и из приказов о приеме, и непосредственно из карточки сотрудника.