В практике разработки на платформе «1С:Предприятие 8» часто возникает задача: ограничить редактирование документа в зависимости от его статуса или роли пользователя, но при этом оставить возможность изменять строго определенные поля. Например, менеджеру нужно разрешить менять цену или примечание в уже завершенном заказе, не открывая доступ ко всем остальным реквизитам.
В этой статье мы разберем, почему стандартные попытки включить доступность колонок часто не работают, проанализируем иерархию свойств элементов формы и выработаем оптимальный алгоритм решения задачи для Обычных форм.
Рассмотрим типичную ситуацию, с которой столкнулся автор темы. При попытке программно включить доступность колонки в цикле ничего не происходит. Причина кроется в свойстве ТолькоПросмотр самой формы.
В системе 1С существует жесткая иерархия: если свойство ТолькоПросмотр установлено в значение Истина на уровне всей формы, платформа игнорирует любые настройки доступности (Доступность) или режима просмотра (ТолькоПросмотр) для вложенных элементов. Форма «заморожена» целиком. Поэтому первым шагом в решении всегда должна быть «разблокировка» основной формы.
Чтобы разрешить редактирование хотя бы одного поля, нам придется установить ЭтаФорма.ТолькоПросмотр = Ложь. Однако это откроет для редактирования все элементы формы. Чтобы этого избежать, мы должны применить стратегию «инверсии»: сначала разрешить редактирование формы, а затем программно запретить доступ ко всем элементам, кроме нужных нам.
Проанализируем пример кода, который позволяет подготовить форму к точечной настройке:
Если РольДоступна("Менеджер") И Стадия = Перечисления.Стадия.Завершен Тогда
// 1. Разрешаем редактирование формы в целом
ЭтаФорма.ТолькоПросмотр = Ложь;
// 2. Блокируем все элементы формы по умолчанию
Для каждого Элемент Из ЭтаФорма.ЭлементыФормы Цикл
Элемент.Доступность = Ложь;
КонецЦикла;
// 3. Теперь точечно включаем нужные элементы
ЭлементыФормы.Товары.Доступность = Истина;
ЭлементыФормы.ОсновныеДействияФормы.Доступность = Истина;
КонецЕсли;
После того как сама табличная часть (например, Товары) стала доступной, нам нужно разобраться с ее колонками. В Обычных формах табличное поле состоит из коллекции Колонки. Каждая колонка имеет свои свойства управления доступом.
Частой ошибкой является использование сложных вложенных циклов с одинаковыми именами итераторов. Рассмотрим, как правильно обратиться к конкретным колонкам, используя наиболее эффективный метод — прямое обращение.
Вместо того чтобы перебирать все колонки в цикле и сравнивать их имена, мы можем обратиться к ним напрямую через коллекцию ЭлементыФормы.Товары.Колонки. Это делает код чище и быстрее.
// Включаем возможность редактирования конкретных колонок
ЭлементыФормы.Товары.Колонки.Цена.ТолькоПросмотр = Ложь;
ЭлементыФормы.Товары.Колонки.Оплата.ТолькоПросмотр = Ложь;
// Если нужно, чтобы остальные колонки были только для чтения
Для каждого Колонка Из ЭлементыФормы.Товары.Колонки Цикл
Если Колонка.Имя <> "Цена" И Колонка.Имя <> "Оплата" Тогда
Колонка.ТолькоПросмотр = Истина;
КонецЕсли;
КонецЦикла;
Важный нюанс: обратите внимание на разницу между Доступность и ТолькоПросмотр. Если установить Доступность = Ложь для колонки, пользователь не сможет даже выделить текст в ней или установить туда курсор. Свойство ТолькоПросмотр = Истина позволяет просматривать и копировать данные, но запрещает их изменение, что обычно более удобно для пользователя.
В процессе обсуждения на форуме была замечена классическая ошибка программиста — использование переменной с одним и тем же именем во вложенных циклах:
Для каждого Элемент Из ЭтаФорма.ЭлементыФормы цикл
// ... какой-то код ...
Для каждого Элемент Из ЭтаФорма.ЭлементыФормы.Товары.Колонки цикл // ОШИБКА! Переменная 'Элемент' перезаписывается
// ...
КонецЦикла;
КонецЦикла;
При таком подходе внешний цикл ломается сразу после завершения внутреннего, так как переменная Элемент больше не указывает на объект из коллекции элементов формы. Всегда используйте уникальные имена итераторов, например, ТекЭлемент и ТекКолонка.
Для того чтобы логика блокировки отрабатывала корректно, ее необходимо вызывать в правильных обработчиках событий формы:
Выясним причину, почему даже при идеально написанном коде колонки могут оставаться недоступными. Если в конфигураторе для роли «Менеджер» сняты права на «Редактирование» конкретного реквизита объекта, то никакие программные манипуляции с ЭтаФорма.ТолькоПросмотр не помогут. Платформа всегда отдает приоритет правам доступа (Roles) и ограничениям доступа на уровне записей (RLS).
Перед написанием кода обязательно убедитесь, что:
ТолькоПросмотр = Истина после выполнения вашего кода (часто встречается в конфигурациях УПП или УТ 10.3).Используя предложенный подход с инверсией прав и прямым обращением к коллекции колонок, мы обеспечиваем надежную и понятную работу интерфейса, сохраняя при этом целостность данных в закрытых документах.