В разработке на платформе 1С:Предприятие часто возникает задача программного заполнения реквизитов. Одной из самых распространенных операций является поиск конкретного пользователя в справочнике Пользователи и подстановка его в поле документа или формы. Несмотря на кажущуюся простоту, новички часто сталкиваются с тем, что код не выдает ошибок, но поле реквизита остается пустым. Разберем подробно, почему это происходит и как правильно решить эту задачу разными способами.
Рассмотрим стандартную ситуацию: разработчик пытается присвоить значение реквизиту, используя поиск по строке. В коде это обычно выглядит так:
Реквизит1 = Справочники.Пользователи.НайтиПоНаименованию("Иванов");
Почему этот код может не работать? Проанализируем основные причины:
НайтиПоНаименованию по умолчанию ищет точное совпадение. Если в справочнике пользователь записан как «Иванов Иван Иванович» или просто имеет лишний пробел в конце («Иванов »), система не найдет его по строке «Иванов» и вернет Справочники.Пользователи.ПустаяСсылка().НайтиПоНаименованию("Иванов", Ложь), поиск будет идти строго с начала строки. Если установить Истина, поиск станет более гибким, но возникнет риск найти не того пользователя, если в базе несколько людей с похожими фамилиями.Справочники напрямую на стороне клиента (в процедурах &НаКлиенте) невозможно. Подобный код должен выполняться только на сервере.Если ваша задача — заполнить реквизит по нажатию кнопки на форме, необходимо правильно распределить код между клиентом и сервером. Выясним, как это реализовать. На клиенте мы вызываем команду, а поиск выполняем на сервере, чтобы иметь доступ к базе данных.
Пример реализации в модуле формы:
&НаКлиенте
Процедура ЗаполнитьПользователя(Команда)
// Вызываем серверную функцию для поиска
НайденныйПользователь = НайтиПользователяНаСервере("Иванов");
Если НЕ НайденныйПользователь.Пустая() Тогда
Объект.Реквизит1 = НайденныйПользователь;
Иначе
Сообщить("Пользователь не найден!");
КонецЕсли;
КонецПроцедуры
&НаСервереБезКонтекста
Функция НайтиПользователяНаСервере(ИмяПользователя)
// На сервере нам доступен глобальный менеджер справочников
Возврат Справочники.Пользователи.НайтиПоНаименованию(ИмяПользователя);
КонецФункции
Важный момент: Использование директивы &НаСервереБезКонтекста повышает производительность, так как на сервер не передаются все данные формы.
Опытные разработчики редко используют НайтиПоНаименованию для критически важных участков кода. Запрос работает быстрее, надежнее и позволяет точно контролировать результат. Посмотрим на пример поиска через запрос, который исключает ошибки типизации и позволяет найти пользователя, даже если его наименование содержит лишние символы.
&НаСервереБезКонтекста
Функция НайтиПользователяЧерезЗапрос(ИмяПользователя)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| Пользователи.Ссылка КАК Ссылка
|ИЗ
| Справочник.Пользователи КАК Пользователи
|ГДЕ
| Пользователи.Наименование ПОДОБНО &Наименование + ""%""
| И НЕ Пользователи.ПометкаУдаления";
Запрос.УстановитьПараметр("Наименование", ИмяПользователя);
РезультатЗапроса = Запрос.Выполнить();
Если НЕ РезультатЗапроса.Пустой() Тогда
Выборка = РезультатЗапроса.Выбрать();
Выборка.Следующий();
Возврат Выборка.Ссылка;
КонецЕсли;
Возврат Справочники.Пользователи.ПустаяСсылка();
КонецФункции
В данном примере мы использовали оператор ПОДОБНО, что позволяет найти пользователя, даже если в базе указано его полное имя, а мы ищем только по фамилии. Также мы добавили проверку на ПометкаУдаления, чтобы не выбирать неактивных сотрудников.
Рассмотрим ситуацию, когда нужно найти не просто строку, а именно того пользователя, который сейчас работает в программе. Проанализируем разницу: в 1С есть «Пользователь информационной базы» (системная учетная запись) и элемент справочника Пользователи. Реквизиты документов всегда имеют тип СправочникСсылка.Пользователи.
Если ваша задача — подставить текущего пользователя, используйте функции Библиотеки стандартных подсистем (БСП), если она интегрирована в вашу конфигурацию:
// В современных конфигурациях (УТ 11, БП 3.0, ЗУП 3.1)
Объект.Реквизит1 = Пользователи.АвторизованныйПользователь();
Если БСП не используется, можно найти ссылку по имени системного пользователя:
ИмяИБ = ПользователиИнформационнойБазы.ТекущийПользователь().ПолноеИмя;
СсылкаНаПользователя = Справочники.Пользователи.НайтиПоНаименованию(ИмяИБ);
Прописывание имен пользователей строками прямо в коде (например, "Иванов") считается плохой практикой (так называемый «хардкод»). Если завтра пользователя «Иванов» переименуют в интерфейсе или он сменит фамилию, ваш код перестанет работать.
Рассмотрим более правильные альтернативы:
Справочники.Пользователи.СистемныйПользователь.Подведем итог: если НайтиПоНаименованию не срабатывает, в первую очередь проверьте точность строки в отладчике, убедитесь, что код выполняется на сервере, и рассмотрите возможность перехода на использование запросов для более стабильной работы программы.