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