В процессе доработки конфигурации 1С:ERP Управление предприятием 2 часто возникает необходимость реализации сложной проверки бизнес-логики. Одной из таких задач является контроль уникальности электронных адресов у контактных лиц в зависимости от их ролей (например, разделение на роли Master и User). Рассмотрим ситуацию, когда при вводе дублирующего email система выдает ошибку, но стандартные средства отладки не сразу позволяют найти место возникновения отказа, а информационные сообщения пропадают при закрытии формы.
Проанализируем ситуацию: если при попытке записи контактного лица выводится сообщение «Не удалось записать Контактное лицо», но глобальный поиск по конфигурации не дает результатов, скорее всего, проверка реализована программно в одном из общих модулей или модуле объекта, отвечающем за контактную информацию. Разберем по шагам, как найти этот участок кода:
ПередЗаписью для справочника КонтактныеЛицаПартнеров или связанных объектов контактной информации.Выясним причину, почему типовая конфигурация может блокировать ввод email. В ERP существует справочник ВидыКонтактнойИнформации. Для каждого вида (например, «Email контактного лица») в настройках можно установить флаг «Запрещать вводить некорректные адреса» или настроить проверку на уникальность. Однако, если логика зависит от ролей контактных лиц (табличная часть РолиКонтактногоЛица), это однозначно указывает на кастомную доработку.
Рассмотрим пример кода, который может находиться в модуле объекта Справочник.КонтактныеЛицаПартнеров или в процедуре, вызываемой из него:
Процедура ПроверитьУникальностьEmail(ТекущийОбъект, Отказ)
EmailДляПроверки = "";
// Логика получения Email из контактной информации объекта
// ...
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| КонтактныеЛицаРоли.Ссылка КАК КонтактноеЛицо
|ИЗ
| Справочник.КонтактныеЛицаПартнеров.РолиКонтактногоЛица КАК КонтактныеЛицаРоли
|ГДЕ
| КонтактныеЛицаРоли.Роль.Наименование = &РольНаименование
| И КонтактныеЛицаРоли.Ссылка.АдресЭП = &Email";
Запрос.УстановитьПараметр("Email", EmailДляПроверки);
Запрос.УстановитьПараметр("РольНаименование", "Master");
РезультатЗапроса = Запрос.Выполнить();
Если Не РезультатЗапроса.Пустой() Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Этот email уже занят лицом с ролью Master. Обратитесь к администратору.";
Сообщение.Сообщить();
Отказ = Истина;
КонецЕсли;
КонецПроцедуры
Проанализируем технический нюанс: почему метод Сообщить() или Сообщение.Сообщить() иногда не срабатывает. Если процедура выполняется в модуле объекта, и после успешной записи форма закрывается, пользователь может просто не успеть увидеть сообщение. Платформа 8.3 при закрытии формы «очищает» контекст сообщений, привязанных к этой форме.
Чтобы вывести информационное окно, которое не пропадет, разберем следующие способы:
Этот метод выводит всплывающее окно в углу экрана, которое не блокирует работу системы и не привязано жестко к контексту закрывающейся формы. Это идеальный вариант для информационных уведомлений после успешной записи.
// В модуле формы или через описание оповещения
ТекстЗаголовка = "Внимание: проверка ролей";
ТекстОповещения = "Email успешно сохранен, но данный адрес также используется у роли Master.";
ПоказатьОповещениеПользователю(ТекстЗаголовка, , ТекстОповещения, БиблиотекаКартинок.Важно);
Если необходимо использовать именно СообщениеПользователю, можно попробовать не привязывать его к конкретному полю текущего объекта, чтобы оно попало в общий список сообщений системы. Однако в управляемых формах эффективнее использовать механизм оповещений.
Рассмотрим вариант реализации логики в модуле формы ПослеЗаписи. Это позволит гарантированно вывести окно пользователю, так как объект уже записан, и мы находимся в контексте формы:
&НаКлиенте
Процедура ПослеЗаписи(ПараметрыЗаписи)
// Проверяем условия, при которых нужно вывести доп. информацию
Если ПроверкаТребуетУведомления Тогда
Текст = "Вы ввели email, который уже используется пользователем с ролью User. Продолжение работы возможно.";
ПоказатьПредупреждение(, Текст);
КонецЕсли;
КонецПроцедуры
Для корректной работы системы разберем правильную структуру кода:
ПередЗаписью. Это гарантирует целостность данных вне зависимости от того, откуда записывается объект (из формы или программно).ПослеЗаписи или ПриЗаписи (на стороне клиента).Таким образом, мы выяснили, что для решения задачи необходимо сначала точно определить место кастомной проверки через Замер производительности, а затем выбрать способ оповещения (ПоказатьОповещениеПользователю или ПоказатьПредупреждение), исходя из того, должен ли процесс записи прерываться или же сообщение носит чисто ознакомительный характер.