Как сделать ячейку в 1С недоступной для изменения
Содержание
Ячейку чаще всего пытаются закрыть от правки грубо: прячут всю колонку или ставят форму целиком на просмотр. Но задача обычно точечная — заблокировать одно поле или одну ячейку в конкретной строке, оставив остальное доступным для ввода.
В 1С 8.3 для этого есть несколько штатных механизмов: свойство ТолькоПросмотр у колонки формы, установка этого свойства кодом в событии, условное оформление с параметром Доступность и защита табличного документа у печатных форм. Отдельно стоит запрет через права на реквизит — он работает на уровне роли, а не формы.
Какой способ нужен, зависит от того, что именно блокируете: колонку таблицы на форме, отдельную ячейку по условию или ячейки в печатной форме. Разберём все варианты от настройки в конфигураторе до программного кода.
| Способ | Что закрывает | Нужен код | Можно обойти через другую форму |
|---|---|---|---|
ТолькоПросмотр в конфигураторе | колонку или таблицу целиком | нет | да |
ТолькоПросмотр кодом | колонку по состоянию объекта | да | да |
Условное оформление, Доступность | ячейку в отдельных строках | опционально | да |
Защита табличного документа | ячейки печатной формы | да | — |
Право Редактирование в роли | реквизит у всех форм | нет | нет |
Блокировка колонки через свойства формы без кода
Самый быстрый путь, если колонку нужно закрыть всегда и для всех. Делается в конфигураторе, строчки кода не потребуется.
- Откройте конфигуратор, найдите в дереве нужный объект (документ, справочник, отчёт) → ветку
Формы→ саму форму. - В редакторе формы выделите в дереве элементов колонку таблицы, которую закрываете.
- Нажмите
F4(палитра свойств) и поставьте галочкуТолькоПросмотр.
Колонка останется видимой, значения будут отображаться, но курсор в ячейку встать не сможет.
Чтобы закрыть сразу всю таблицу, выделите не колонку, а сам элемент-таблицу и установите ТолькоПросмотр у неё. Всё поддерево колонок унаследует запрет.
ТолькоПросмотр и Доступность — разные вещи. При ТолькоПросмотр = Истина поле читаемо, но не редактируется. При Доступность = Ложь поле становится серым и неактивным — на него нельзя даже навести фокус.
Если колонку нужно закрыть не всегда, а по условию (например, только у проведённого документа) — свойство в конфигураторе не поможет, нужен код из следующего раздела.
Программная установка запрета в управляемой форме
Когда доступность ячеек зависит от состояния объекта, свойство ТолькоПросмотр устанавливают кодом. Обращение идёт к элементу формы через коллекцию Элементы.
Закрыть отдельную колонку:
Элементы.ТоварыЦена.ТолькоПросмотр = Истина;
Имя элемента-колонки по умолчанию складывается из имени таблицы и имени поля: таблица Товары + поле Цена = ТоварыЦена. Проверьте фактическое имя в палитре свойств колонки.
Типичный сценарий — запретить правку таблицы у проведённого документа. Вынесите установку в отдельную процедуру и вызовите её из нужных событий:
&НаСервере
Процедура УстановитьДоступностьТаблицы()
Элементы.Товары.ТолькоПросмотр = Объект.Проведен;
КонецПроцедуры
Здесь Объект — основной реквизит формы документа.
Главная ошибка — вызвать установку только один раз, при открытии формы. После записи или проведения документа форма не перечитывается, и колонка снова станет доступной. Поэтому процедуру вызывают из нескольких событий:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
УстановитьДоступностьТаблицы();
КонецПроцедуры
&НаСервере
Процедура ПослеЗаписиНаСервере(ТекущийОбъект, ПараметрыЗаписи)
УстановитьДоступностьТаблицы();
КонецПроцедуры
Как заблокировать одну ячейку в строке по условию
Свойство ТолькоПросмотр закрывает колонку целиком — во всех строках сразу. Чтобы запретить правку ячейки только в отдельных строках (например, в уже согласованных позициях), используют условное оформление.
Проще всего настроить его в конфигураторе: в редакторе формы откройте ветку Условное оформление → добавьте элемент. В нём задают три части:
- Оформление — параметр
Доступностьсо значениемЛожь. - Условие (отбор) — по какому полю строки срабатывает, например
Товары.СогласованоравноИстина. - Оформляемые поля — колонка, которую закрываем, например
ТоварыЦена.
То же самое кодом:
&НаСервере
Процедура УстановитьЗапретПоУсловию()
Элемент = УсловноеОформление.Элементы.Добавить();
ОформляемоеПоле = Элемент.Поля.Элементы.Добавить();
ОформляемоеПоле.Поле = Новый ПолеКомпоновкиДанных("ТоварыЦена");
Отбор = Элемент.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
Отбор.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Товары.Согласовано");
Отбор.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
Отбор.ПравоеЗначение = Истина;
Элемент.Оформление.УстановитьЗначениеПараметра("Доступность", Ложь);
КонецПроцедуры
Теперь ячейка Цена будет недоступна только в тех строках, где установлен флаг Согласовано. Остальные строки остаются редактируемыми.
Условное оформление с параметром Доступность — единственный штатный способ заблокировать ячейку в конкретной строке, не трогая соседние. Через ТолькоПросмотр построчно управлять не получится.
Защита ячеек в табличном документе печатной формы
Если «ячейка» — это клетка табличного документа (печатная форма, выгрузка, отчёт в виде таблицы), работают другие свойства: ТолькоПросмотр и Защита.
Полностью запретить правку всего документа:
ТабДок = Новый ТабличныйДокумент;
// ... вывод областей макета ...
ТабДок.ТолькоПросмотр = Истина;
Если же часть ячеек должна оставаться доступной для ввода (бланк, куда пользователь что-то вписывает), используют защиту с исключениями. Включите защиту у всего документа, а у областей для ввода её снимите:
ТабДок.Защита = Истина;
ОбластьВвода = ТабДок.Область("R5C2:R10C2");
ОбластьВвода.Защита = Ложь;
Все ячейки, кроме диапазона R5C2:R10C2, будут защищены от изменения, а в указанный столбец можно вводить данные.
Если включить защиту только у отдельных областей, но не выставить Защита = Истина у самого документа, ячейки всё равно останутся редактируемыми. Флаг у документа — главный выключатель.
Запрет изменения через права доступа и роли
Все способы выше действуют на уровне формы. Их можно обойти, открыв объект через другую форму или обработку. Если правку реквизита нужно закрыть жёстко и для определённых пользователей — настраивают права роли.
В платформе 8.3 у ролей есть права не только на объект целиком, но и на отдельные реквизиты. В редакторе роли на вкладке Права разверните нужный реквизит справочника или документа — там отдельно стоят Просмотр и Редактирование.
Снимите Редактирование — и для пользователей с этой ролью поле станет недоступным во всех формах автоматически, без единой строчки кода на форме.
Запрет через права на реквизит нельзя обойти через другую форму — это защита уровня прикладного решения, а не интерфейса.
Ограничение доступа на уровне записей (RLS) для блокировки ячейки не подходит: оно закрывает доступ к целым записям (строкам справочника, документам), а не к отдельным полям внутри открытой записи.
Обычные формы и старые версии: в чём отличие
В обычных формах (конфигурации на устаревшем интерфейсе, а также формы в 1С 7.7 и 8.2) принцип тот же, меняется только коллекция доступа. Запрет ставят через свойство ТолькоПросмотр элемента управления — в конфигураторе галочкой или кодом:
ЭлементыФормы.Таблица.ТолькоПросмотр = Истина;
Условное оформление в обычных формах беднее, чем в управляемых, поэтому построчную блокировку там чаще делают через обработчики событий таблицы. Для новых разработок на 8.3 с интерфейсом «Такси» используйте управляемые формы — условное оформление с Доступность закрывает большинство задач без кода.
Какой способ выбрать под вашу задачу
ТолькоПросмотр у колонки прямо в конфигураторе. Код не нужен.Элементы.Колонка.ТолькоПросмотр кодом в ПриСозданииНаСервере и ПослеЗаписиНаСервере.Доступность = Ложь и отбором по полю строки.ТолькоПросмотр или Защита табличного документа.Редактирование.Типичные ошибки
🔴 Запрет ставят только при открытии формы. После записи или проведения документа колонка снова редактируется, потому что установку не продублировали в ПослеЗаписиНаСервере.
🔴 Колонку прячут вместо блокировки. Видимость = Ложь убирает данные с глаз — пользователь не видит значение. Для защиты от правки нужен ТолькоПросмотр, а не скрытие.
🔴 У табличного документа включена защита областей, но не самого документа. Без ТабДок.Защита = Истина отдельные области ничего не защищают.
🔴 Блокировку городят в динамическом списке. В списке строки и так редактируются только через форму элемента, отдельно закрывать ячейки списка не нужно.
🔴 Путают ТолькоПросмотр и Доступность. Если поле должно оставаться читаемым — это ТолькоПросмотр. Доступность = Ложь гасит поле полностью и мешает, когда значение всё-таки нужно видеть.
Частые вопросы
Можно ли заблокировать одну ячейку, а не всю колонку?
Доступность = Ложь, отбор по полю строки и укажите конкретную колонку в оформляемых полях. Запрет сработает только в строках, подходящих под условие.Почему колонка снова редактируется после записи документа?
ТолькоПросмотр сделали один раз в ПриСозданииНаСервере. Форма после записи не пересоздаётся, поэтому вызов нужно продублировать в ПослеЗаписиНаСервере, а при чтении — в ПриЧтенииНаСервере.Как запретить правку так, чтобы её не обошли через другую форму?
Редактирование на реквизит в роли. Это запрет уровня прав, он действует во всех формах и обработках, а не только в той, где настроен интерфейс.Чем защита табличного документа отличается от `ТолькоПросмотр`?
ТолькоПросмотр закрывает весь документ целиком. Защита позволяет оставить часть ячеек доступными для ввода: у документа ставят Защита = Истина, а у областей для заполнения — Защита = Ложь.