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