Как разблокировать одну колонку табличной части для редактирования, если вся форма документа защищена?

Программист 1С v8.3 (Обычные формы) 1С:Управление торговлей Торговля и дистрибуция
← На главную

При работе в 1С:Управление торговлей 10.3 (и других конфигурациях на обычных формах) разработчики часто сталкиваются с ситуацией, когда по условиям бизнес-логики или прав доступа форма документа должна открываться только для чтения. Однако пользователям бывает необходимо вносить изменения в одно конкретное поле — например, в комментарий, статус или специфический реквизит табличной части. Стандартная установка свойства ТолькоПросмотр = Истина для всей формы блокирует любые изменения, что делает невозможным редактирование даже одной ячейки. Разберем подробно, как элегантно решить эту задачу.

Понимание иерархии свойства «ТолькоПросмотр»

Для начала проанализируем, как работает механизм блокировки в платформе 1С. Свойство ТолькоПросмотр (ReadOnly) имеет иерархическую структуру. Если мы установим ЭтаФорма.ТолькоПросмотр = Истина, то абсолютно все элементы управления, включая кнопки, списки и табличные части, станут недоступными для изменения, независимо от их собственных настроек. Принцип работает «сверху вниз»: родительский запрет всегда приоритетнее разрешений дочерних элементов.

Следовательно, для реализации нашей задачи нам необходимо применить обратный алгоритм:

  1. Оставить форму (и табличную часть в целом) доступной для редактирования (ТолькоПросмотр = Ложь).
  2. Программно заблокировать все элементы, которые не должны изменяться.
  3. Оставить нужную нам колонку открытой.

Способ 1. Программный перебор колонок табличного поля

Рассмотрим ситуацию в контексте УТ 10.3. Поскольку это обычные формы, мы не можем просто объединить колонки в группы, как в управляемом интерфейсе. Нам придется работать с коллекцией колонок табличного поля. Посмотрим на пример кода, который можно разместить в процедуре ПриОткрытии или в специальном методе для настройки доступности:


// Сначала разрешаем редактирование формы и самой таблицы
ЭтаФорма.ТолькоПросмотр = Ложь;
ЭлементыФормы.Товары.ТолькоПросмотр = Ложь;

// Блокируем изменение состава строк (чтобы нельзя было добавлять/удалять)
ЭлементыФормы.Товары.ИзменятьСоставСтрок = Ложь;

// Проходим циклом по всем колонкам табличного поля
Для Каждого Колонка Из ЭлементыФормы.Товары.Колонки Цикл
    // Проверяем имя колонки. Если это не та, которую нужно оставить...
    Если Колонка.Имя <> "НужнаяКолонка" Тогда
        Колонка.ТолькоПросмотр = Истина;
    Иначе
        Колонка.ТолькоПросмотр = Ложь;
    КонецЕсли;
КонецЦикла;

Этот подход гарантирует, что пользователь сможет зайти в режим редактирования только в целевой ячейке. Однако помните, что если на форме есть другие реквизиты (дата, номер, контрагент), их также придется заблокировать аналогичным перебором или вручную.

Способ 2. Рекурсивный обход всех элементов формы

Чтобы не прописывать блокировку для каждого отдельного поля (которых в документе «Заказ поставщику» может быть очень много), проанализируем метод рекурсивного обхода. Мы можем создать универсальную процедуру, которая «заморозит» всю форму, сделав исключение только для нашей колонки и ее родительского контейнера.

Разберем логику такой процедуры:

  1. Проходим по коллекции ЭлементыФормы.
  2. Если элемент — это наша табличная часть, мы оставляем ее доступной, но внутри нее запускаем цикл по колонкам (как в первом способе).
  3. Если элемент — это кнопка, текстовое поле или флажок, и он не входит в наш список исключений, устанавливаем ТолькоПросмотр = Истина или Доступность = Ложь.

Важный нюанс: свойство Доступность в отличие от ТолькоПросмотр делает элемент «серым» и не позволяет даже выделить текст или нажать на кнопку. Для текстовых полей лучше использовать ТолькоПросмотр, чтобы пользователи могли копировать данные.

Способ 3. Управление через событие «ПриВыводеСтроки»

Выясним причину, почему иногда стандартная блокировка колонок не подходит. Бывает, что доступность колонки должна зависеть от данных в самой строке. В обычных формах для этого идеально подходит событие ПриВыводеСтроки. Через параметр ОформлениеСтроки мы можем дотянуться до конкретной ячейки.

Рассмотрим пример:


Процедура ТоварыПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки)
    // Блокируем ячейку программно для конкретной строки
    ОформлениеСтроки.Ячейки.Цена.ТолькоПросмотр = Истина;
    
    // Оставляем доступной только нужную колонку, например, "Комментарий"
    ОформлениеСтроки.Ячейки.Комментарий.ТолькоПросмотр = Ложь;
КонецПроцедуры

Важно: Этот метод работает только для визуального отображения в табличном поле. Чтобы он корректно отрабатывал при попытке входа в ячейку, свойство самого ТабличногоПоля.ТолькоПросмотр должно быть установлено в Ложь.

Способ 4. Использование события «ПередНачаломИзменения»

Если мы не хотим менять визуальное состояние колонок (чтобы они не выглядели заблокированными), но хотим запретить редактирование, можно использовать «логический» запрет. Разберем, как это работает через обработчик события табличной части ПередНачаломИзменения.


Процедура ТоварыПередНачаломИзменения(Элемент, Отказ)
    // Определяем, в какой колонке сейчас находится пользователь
    ТекущаяКолонка = ЭлементыФормы.Товары.ТекущаяКолонка;
    
    // Если пользователь пытается изменить что-то, кроме разрешенной колонки
    Если ТекущаяКолонка.Имя <> "РазрешеннаяКолонка" Тогда
        // Отменяем действие
        Отказ = Истина;
    КонецЕсли;
КонецПроцедуры

Этот метод хорош тем, что он максимально прост в реализации и не требует циклов по всем элементам формы. Мы просто «выбрасываем» пользователя из режима редактирования везде, кроме одного места.

Нюансы с записью данных и «звездочкой» в заголовке

Проанализируем ситуацию: когда пользователь меняет значение в разблокированной колонке, документ помечается как измененный (появляется символ «*» в заголовке). Если ваша задача — разрешить редактирование чисто информационного поля, которое не должно влиять на статус документа или требовать его перепроведения, проверьте свойство колонки ИзменяетДанные. Если его снять, модифицированность формы не будет срабатывать при правке этой ячейки.

Также не забывайте про права доступа (RLS). Если у пользователя в роли запрещено право «Редактирование» для конкретного реквизита на уровне метаданных, то никакие манипуляции с ТолькоПросмотр в коде формы не помогут — платформа заблокирует поле на уровне ядра.

Подведем итог: оптимальный путь для УТ 10.3 — это комбинация снятия ТолькоПросмотр с формы и последующей точечной блокировки ненужных колонок в цикле при открытии, либо использование события ПередНачаломИзменения для быстрого перехвата действий пользователя.

← На главную