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

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

В процессе разработки интерфейсов на управляемых формах 1С часто возникает задача: направить внимание пользователя исключительно на новую или скопированную строку табличной части, заблокировав при этом возможность изменения уже существующих данных. Это особенно актуально в документах с большим объемом информации, где случайное изменение старой строки может привести к учетным ошибкам.

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

Способ 1. Использование Условного оформления (рекомендуемый подход)

Наиболее технологичным и визуально понятным способом в управляемом приложении является использование механизма Условного оформления. Этот метод позволяет динамически изменять доступность ячеек на уровне платформы, не прибегая к постоянным серверным вызовам.

Разберем алгоритм реализации по шагам:

  1. Добавление служебного реквизита. В состав табличной части (или как реквизит формы, связанный со строкой) добавим невидимое для пользователя поле РазрешитьРедактирование с типом Булево.
  2. Настройка правил оформления. В свойствах формы перейдем в закладку «Условное оформление» и создадим новое правило:
    • Оформление: установим свойство ТолькоПросмотр в значение Истина.
    • Условие: Объект.Товары.РазрешитьРедактирование Равно Ложь.
    • Оформляемые поля: выберем все колонки табличной части, которые нужно защитить.

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

В модуле формы опишем следующие процедуры:


&НаКлиенте
Процедура ТоварыПриНачалеРедактирования(Элемент, НоваяСтрока, Копирование)
    
    // Если это новая строка (добавленная или скопированная)
    Если НоваяСтрока Тогда
        ТекущиеДанные = Элементы.Товары.ТекущиеДанные;
        Если ТекущиеДанные <> Неопределено Тогда
            ТекущиеДанные.РазрешитьРедактирование = Истина;
        КонецЕсли;
    КонецЕсли;
    
КонецПроцедуры

&НаКлиенте
Процедура ТоварыПередОкончаниемРедактирования(Элемент, НоваяСтрока, ОтменаРедактирования, Отказ)
    
    // По окончании редактирования всегда сбрасываем флаг, чтобы строка стала недоступной
    Если Не ОтменаРедактирования Тогда
        ТекущиеДанные = Элементы.Товары.ТекущиеДанные;
        Если ТекущиеДанные <> Неопределено Тогда
            ТекущиеДанные.РазрешитьРедактирование = Ложь;
        КонецЕсли;
    КонецЕсли;
    
КонецПроцедуры

Важный нюанс: при таком подходе уже записанные строки всегда будут иметь РазрешитьРедактирование = Ложь, что автоматически сделает их недоступными для изменения пользователем.

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

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

Рассмотрим ситуацию: как нам понять, что строка является «старой»? Самый простой способ — проверить, заполнена ли она уже в базе или имеет ли она уникальный идентификатор, присвоенный ранее.


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

Способ 3. Управление через модальные окна и асинхронные вызовы

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

Проанализируем сценарий, когда при копировании строки мы очищаем ключевые поля и предлагаем ввести их заново:


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

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


&НаКлиенте
Процедура ЗапроситьКоличество(Результат, ДополнительныеПараметры) Экспорт
    Если Результат <> Неопределено Тогда
        ТекущиеДанные = Элементы.Товары.ТекущиеДанные;
        Если ТекущиеДанные <> Неопределено Тогда
            ТекущиеДанные.Количество = Результат;
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ТоварыПриНачалеРедактирования(Элемент, НоваяСтрока, Копирование)
    Если НоваяСтрока Тогда
        Оповещение = Новый ОписаниеОповещения("ЗапроситьКоличество", ЭтотОбъект);
        ПоказатьВводЗначения(Оповещение, 0, "Введите количество для новой строки");
    КонецЕсли;
КонецПроцедуры

Сравнение подходов и важные рекомендации

Выясним причину, почему разработчики часто предпочитают Условное оформление (Способ 1). Дело в том, что оно работает на уровне отображения данных и практически не создает нагрузки на сервер при интерактивных действиях пользователя. Использование Отказ = Истина в событиях (Способ 2) работает жестче, но иногда может раздражать пользователя, если он просто хотел выделить ячейку для копирования текста, а не для правки.

Основные советы при реализации:

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

← На главную