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