Как вывести и зафиксировать текущего пользователя в поле ввода в 1С 8.3

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке конфигураций на платформе 1С:Предприятие 8.3 одной из самых частых задач является автоматическое заполнение реквизита Ответственный при создании нового документа или справочника. Несмотря на кажущуюся простоту, начинающие разработчики часто сталкиваются с трудностями, связанными с разделением контекста исполнения кода на "Клиент" и "Сервер", а также с вопросами сохранения авторства документа при его последующем редактировании другими пользователями.

В этой статье мы подробно разберем, как правильно реализовать этот механизм, проанализируем типичные ошибки и рассмотрим методические рекомендации по работе с данными о пользователях.

Разбор проблемы: Почему код не работает на клиенте?

Рассмотрим ситуацию: вы пытаетесь написать код в модуле формы, который должен получить текущего пользователя и записать его в поле ввода (например, реализовать сохранение настроек формы для всех пользователей). Часто новички пытаются использовать объект ПользователиИнформационнойБазы напрямую в клиентских процедурах. Проанализируем, почему это приводит к ошибке "Переменная не определена".

Объект ПользователиИнформационнойБазы доступен только на стороне сервера. В тонком и веб-клиенте платформа "не знает" о существовании этого объекта в целях безопасности и оптимизации трафика. Чтобы получить данные о пользователе на клиенте, нам необходимо либо переходить в серверный контекст, либо использовать заранее подготовленные данные.

Решение 1: Использование параметров сеанса (Рекомендуемый способ)

Методически наиболее правильным решением является использование Параметров сеанса. В типовых конфигурациях 1С (таких как БП 3.0, УТ 11 или ERP) уже существует параметр сеанса ТекущийПользователь. Он инициализируется при запуске системы и содержит ссылку на текущего пользователя из справочника Пользователи.

Рассмотрим пример установки ответственного в процедуре формы ПриСозданииНаСервере. Этот метод хорош тем, что он срабатывает только один раз при открытии формы нового объекта:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Проверяем, что объект новый (еще не записан в базу)
    Если Объект.Ссылка.Пустая() Тогда
        // Используем параметр сеанса для заполнения реквизита
        Объект.Ответственный = ПараметрыСеанса.ТекущийПользователь;
    КонецЕсли;
    
КонецПроцедуры

Использование ПараметрыСеанса работает быстрее, чем обращение к ПользователиИнформационнойБазы.ТекущийПользователь(), так как данные уже кэшированы в рамках текущего сеанса работы пользователя.

Решение 2: Доступ к пользователю с клиента через общие модули

Если вам все же необходимо получить текущего пользователя непосредственно в клиентском коде (например, для интерактивного оповещения или изменения логики формы без лишних серверных вызовов), мы можем создать "обертку".

Для этого выполним следующие шаги:

  1. Создадим общий модуль (например, с именем РаботаСПользователямиПолныйДоступ).
  2. В свойствах модуля установим галочки "Сервер" и "Вызов сервера".
  3. Напишем экспортную функцию:

Функция ПолучитьТекущегоПользователя() Экспорт
    Возврат ПараметрыСеанса.ТекущийПользователь;
КонецФункции

Теперь в любой клиентской процедуре модуля формы мы сможем вызвать эту функцию:


&НаКлиенте
Процедура КомандаПолучитьПользователя(Команда)
    ТекущийЮзер = РаботаСПользователямиПолныйДоступ.ПолучитьТекущегоПользователя();
    Сообщить("Приветствуем, " + ТекущийЮзер);
КонецПроцедуры

Решение 3: Фиксация ответственного при записи и управление датами запрета изменений

Часто возникает задача: если документ редактирует другой человек (например, администратор или бухгалтер), поле Ответственный не должно меняться — в нем должен остаться тот, кто создал документ. Проанализируем, как это реализовать правильно в процедуре ПриЗаписиНаСервере.

Важно помнить, что в процедуре ПриЗаписиНаСервере мы работаем с объектом ТекущийОбъект, который представляет собой копию данных из базы данных. Выясним причину использования условия проверки:


&НаСервере
Процедура ПриЗаписиНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
    
    // Вариант 1: Проверка на пустую ссылку (только для новых объектов)
    Если ТекущийОбъект.Ссылка.Пустая() Тогда
        ТекущийОбъект.Ответственный = ПараметрыСеанса.ТекущийПользователь;
    КонецЕсли;

    // Вариант 2: Если реквизит - строка и нужно проверить на заполненность
    Если ПустаяСтрока(ТекущийОбъект.Ответственный) Тогда
         ТекущийОбъект.Ответственный = Строка(ПользователиИнформационнойБазы.ТекущийПользователь());
    КонецЕсли;
    
КонецПроцедуры

Важный нюанс: Если вы используете проверку Если ТекущийОбъект.Ответственный = "", убедитесь, что тип данных вашего реквизита действительно Строка. Однако, согласно стандартам разработки 1С, реквизит Ответственный всегда должен иметь тип СправочникСсылка.Пользователи (это позволяет интерактивно управлять свойствами элементов дополнительных реквизитов). Это позволяет строить отчеты, настраивать права доступа (RLS) и избегать ошибок при переименовании учетных записей — с этой задачей поможет справиться модуль автоматического назначения ответственных и ограничения прав доступа.

Решение 4: Использование Библиотеки Стандартных Подсистем (БСП)

Если ваша конфигурация разработана на основе БСП (что верно для большинства современных решений), рекомендуется использовать встроенные функции библиотеки. Это делает ваш код более профессиональным и устойчивым к обновлениям платформы.

Для получения текущего пользователя в БСП используется программный интерфейс модуля Пользователи:


// На сервере
Объект.Ответственный = Пользователи.АвторизованныйПользователь();

// На клиенте (если модуль имеет признак ВызовСервера или Клиент)
ТекущийПользователь = ПользователиКлиентСервер.ТекущийПользователь();

Проблема копирования объектов

Проанализируем ситуацию с копированием документа. Когда пользователь нажимает кнопку "Скопировать", создается новый объект, и его ссылка также будет пустой (Ссылка.Пустая() = Истина). В этом случае логика "заполнять, если ссылка пустая" приведет к тому, что ответственным станет тот, кто копирует документ, а не тот, кто был в оригинале.

Если вы хотите сохранить ответственного из оригинала при копировании, логику заполнения лучше перенести в модуль объекта в процедуру ОбработкаЗаполнения:


Процедура ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка)
    
    Если ТипЗнч(ДанныеЗаполнения) = Тип("ДокументСсылка.ИмяВашегоДокумента") Тогда
        // При копировании оставляем ответственного из оригинала
        // Или наоборот, принудительно меняем - решение за разработчиком
        ЭтотОбъект.Ответственный = ПараметрыСеанса.ТекущийПользователь;
    ИначеЕсли ДанныеЗаполнения = Неопределено Тогда
        // При создании нового (не копированием)
        ЭтотОбъект.Ответственный = ПараметрыСеанса.ТекущийПользователь;
    КонецЕсли;
    
КонецПроцедуры

Советы по оформлению интерфейса

Чтобы пользователь случайно не изменил автора документа, мы можем ограничить редактирование поля на уровне формы — для этого удобно использовать модуль настройки запрета редактирования реквизитов в 1С. Рассмотрим, как это сделать:

Подводя итог, можно сказать, что правильный вывод текущего пользователя базируется на трех китах: использование параметров сеанса, соблюдение контекстности (клиент/сервер) и использование ссылочных типов данных вместо строк.

← На главную