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