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