Как ограничить редактирование и удаление сохраненных строк табличной части в 1С

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

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

Рассмотрим, как реализовать такую логику с минимальными затратами производительности и обеспечить надежность работы системы.

Анализ задачи и способов ее решения

Для правильного решения этой задачи необходимо разбить логику на три составляющие:

  1. Блокировка редактирования ячеек в сохраненных строках. Попытка обходить строки и менять свойства колонок в цикле или событии ПриАктивизацииЯчейки приводит к лишним задержкам интерфейса. Оптимальный инструмент для визуальной блокировки ячеек на клиенте — Условное оформление формы.
  2. Запрет удаления сохраненных строк. Условное оформление не блокирует удаление строк клавишей Del или через контекстное меню. Для этого используется событие таблицы формы ПередУдалением.
  3. Серверная проверка. Клиентские ограничения защищают пользовательский интерфейс, но бизнес-логику необходимо дополнительно дублировать на сервере в модуле объекта.

Способ 1. Блокировка ячеек с помощью Условного оформления

В управляемых формах 1С для блокировки отдельных ячеек строки используется свойство условного оформления ТолькоПросмотр. Оно выполняется платформой на клиенте автоматически и не вызывает лишних обращений к серверу.

Для того чтобы отличить ранее записанную строку от только что добавленной, в типовых конфигурациях (ERP, КА, УТ) часто используется заполненный реквизит строки КлючСвязи или служебный флаг строки. Если документ уже записан и строка имеет сохраненный ключ связи, к ней применяются правила оформления.

Разберем настройку условного оформления программным способом в событии ПриСозданииНаСервере:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Создаем элемент условного оформления
    ЭлементОформления = УсловноеОформление.Элементы.Добавить();
    
    // Устанавливаем свойство "Только просмотр"
    ЗначениеСвойства = ЭлементОформления.Оформление.УстановитьЗначениеПараметра("ТолькоПросмотр", Истина);
    ЭлементОформления.Оформление.ЗадатьЗначениеПараметра("ТолькоПросмотр", Истина);
    
    // Указываем оформляемые поля (все колонки таблицы, кроме разрешенных)
    ОформляемоеПоле = ЭлементОформления.Поля.Элементы.Добавить();
    ОформляемоеПоле.Поле = Новый КомпоновкаДанныхПоле("ТоварыНоменклатура");
    
    ОформляемоеПоле = ЭлементОформления.Поля.Элементы.Добавить();
    ОформляемоеПоле.Поле = Новый КомпоновкаДанныхПоле("ТоварыКоличество");
    
    ОформляемоеПоле = ЭлементОформления.Поля.Элементы.Добавить();
    ОформляемоеПоле.Поле = Новый КомпоновкаДанныхПоле("ТоварыЦена");
    
    // Условие: если строка уже содержит ключ связи (записана)
    ЭлементОтбора = ЭлементОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
    ЭлементОтбора.ЛевоеЗначение = Новый КомпоновкаДанныхПоле("Объект.Товары.КлючСвязи");
    ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Заполнено;
    ЭлементОтбора.Использование = Истина;
    
КонецПроцедуры

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

Способ 2. Запрет удаления сохраненных строк

Чтобы не дать пользователю удалить ранее сохраненные строки табличной части, назначим обработчик событий ПередУдалением для таблицы Товары на форме.

Проанализируем пример кода клиентского обработчика:


&НаКлиенте
Процедура ТоварыПередУдалением(Элемент, Отказ)
    
    ТекущиеДанные = Элемент.ТекущиеДанные;
    Если ТекущиеДанные = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // Проверяем, является ли строка записанной (например, по заполнению КлючаСвязи)
    Если ЗначениеЗаполнено(ТекущиеДанные.КлючСвязи) Тогда
        Отказ = Истина;
        ПоказатьПредупреждение(, "Запрещено удалять ранее сохраненные строки документа!");
    КонецЕсли;
    
КонецПроцедуры

При попытке удаления строки клавишей Del или через командную панель платформа проверит заполненность идентификатора строки. Если строка была сохранена ранее, операция отменяется с выводом предупреждения пользователю.

Способ 3. Гарантированная защита на сервере в модуле объекта

Для предотвращения изменений в обход формы (например, при загрузках данных или вызове методов из других модулей) обязательно добавим контроль изменений в обработчик ПередЗаписью модуля объекта.

Рассмотрим порядок действий:

  1. Считываем из базы данных исходное состояние документа через Ссылка.ПолучитьОбъект() или с помощью считывания табличной части запросом.
  2. Сравниваем исходный состав строк с текущими данными в объекте.
  3. Если ранее существующая строка была удалена или в ней были изменены защищаемые реквизиты, устанавливаем Отказ = Истина.

Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    
    Если Отказ Или ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;
    
    Если Не ЭтоНовый() Тогда
        ТаблицаИзБД = Ссылка.Товары.Выгрузить();
        
        Для Каждого СтрокаИзБД Из ТаблицаИзБД Цикл
            НайденнаяСтрока = Товары.НайтиПоИдентификатору(СтрокаИзБД.НомерСтроки);
            
            Если НайденнаяСтрока = Неопределено Тогда
                Отказ = Истина;
                ВызватьИсключение "Нельзя удалять ранее сохраненные строки документа!";
            ИначеЕсли НайденнаяСтрока.Номенклатура <> СтрокаИзБД.Номенклатура Тогда
                Отказ = Истина;
                ВызватьИсключение "Нельзя изменять номенклатуру в сохраненных строках!";
            КонецЕсли;
        КонецЦикла;
    КонецЕсли;
    
КонецПроцедуры

Итоги

Сочетание условного оформления для ячеек, обработчика ПередУдалением на форме и контроля в событии ПередЗаписью объекта позволяет эффективно защитить данные от несанкционированного изменения без снижения скорости работы интерфейса.

← На главную