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