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