При разработке прикладных решений в 1С часто возникает задача зафиксировать автора документа или элемента справочника при его создании. Распространенный подход — обращение к параметру сеанса ПараметрыСеанса.ТекущийПользователь в обработчиках записи объекта. Разберем подробно, гарантирует ли платформа 1С наличие значения в этом параметре, как устроена его инициализация и какие подводные камни могут встретиться в регламентных заданиях и нестандартных сценариях работы.
Для понимания поведения параметров сеанса проанализируем базовый механизм платформы — инициализацию по требованию (ленивую инициализацию). Платформа не заполняет все параметры сеанса заранее при запуске программы. Обработка выполняется по следующему алгоритму:
УстановкаПараметровСеанса в модуле сеанса. В эту процедуру передается массив ТребуемыеПараметры, содержащий имена параметров, к которым произошло обращение.Таким образом, параметр сеанса технически не может находиться в неинициализированном состоянии в момент успешного чтения: либо ему присвоено значение (пусть даже пустая ссылка), либо выполнение кода прерывается исключением.
Несмотря на то, что параметр обязательно будет проинициализирован обработчиком, значение внутри него далеко не всегда будет ссылкой на реального пользователя. Выясним причину, почему это происходит:
ПользовательИнформационнойБазы не является ссылкой на элемент справочника. Если администратор завел пользователя через конфигуратор, но в справочнике Справочники.Пользователи соответствующий элемент еще не создан, поиск по имени выдаст пустую ссылку.В типовых конфигурациях на базе Библиотеки стандартных подсистем (БСП) прямое обращение к ПараметрыСеанса.ТекущийПользователь не рекомендуется. В БСП предусмотрен модуль Пользователи со специализированными функциями:
Пользователи.АвторизованныйПользователь() — возвращает элемент справочника пользователя, от имени которого открыт сеанс. Функция предназначена для определения контекста сеанса.Пользователи.ТекущийПользователь() — возвращает заполненное значение для интерактивной работы, однако при неинтерактивных вызовах (например, во внешних соединениях) возвращает пустую ссылку, защищая данные от ложного указания автора.Если конфигурация разработана с нуля без использования БСП, обращение к общему модулю Пользователи вызовет синтаксическую ошибку. В чисто самописных конфигурациях разработчик обязан самостоятельно спроектировать механизм заполнения в модуле сеанса.
Рассмотрим пример корректного заполнения параметра сеанса в модуле сеанса. Нам необходимо предусмотреть сценарий, когда пользователь ИБ не найден в справочнике, чтобы платформа не вызывала системную ошибку:
Процедура УстановкаПараметровСеанса(ТребуемыеПараметры)
Если ТребуемыеПараметры = Неопределено
Или ТребуемыеПараметры.Найти("ТекущийПользователь") <> Неопределено Тогда
ИмяТекущего = ПользователиИнформационнойБазы.ТекущийПользователь().Имя;
СсылкаНаПользователя = Справочники.Пользователи.НайтиПоНаименованию(ИмяТекущего, Истина);
Если ЗначениеЗаполнено(СсылкаНаПользователя) Тогда
ПараметрыСеанса.ТекущийПользователь = СсылкаНаПользователя;
Иначе
ПараметрыСеанса.ТекущийПользователь = Справочники.Пользователи.ПустаяСсылка();
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Такой подход гарантирует, что даже при входе неопознанного или системного пользователя параметр сеанса будет корректно проинициализирован пустой ссылкой нужного типа.
Обратим внимание на частую ошибку: заполнение автора в событии ПриЗаписи без проверки признака нового объекта. Если объект редактируется повторно другим сотрудником, первоначальный создатель будет перезаписан. Кроме того, событие ПриЗаписи вызывается уже после фиксации изменений в базе данных, поэтому реквизиты объекта рекомендуется заполнять в событии ПередЗаписью.
Посмотрим на безопасный пример кода в модуле объекта справочника или документа:
Процедура ПередЗаписью(Отказ)
// Предотвращаем изменение автора при выгрузке/загрузке данных
Если ОбменДанными.Загрузка Тогда
Возврат;
КонецЕсли;
// Заполняем автора только для создаваемого объекта, если поле еще не заполнено
Если ЭтоНовый() И Не ЗначениеЗаполнено(Сотрудник) Тогда
Если ЗначениеЗаполнено(ПараметрыСеанса.ТекущийПользователь) Тогда
Сотрудник = ПараметрыСеанса.ТекущийПользователь;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Разберем, почему эти проверки обязательны:
ОбменДанными.Загрузка: исключает замену оригинального автора при переносе данных, загрузке из XML/JSON или синхронизации между базами.ЭтоНовый(): сохраняет значение автора при всех последующих перезаписях документа или справочника.Не ЗначениеЗаполнено(Сотрудник): позволяет явно установить автора программно перед вызовом Записать(), не перетирая переданное значение параметром сеанса.ЗначениеЗаполнено(ПараметрыСеанса.ТекущийПользователь): предотвращает запись пустой ссылки, если операция выполняется системным фоновым заданием.При соблюдении этих правил реквизит автора будет заполняться предсказуемо и стабильно во всех режимах работы конфигурации.