Как запретить редактирование реквизита в 1С после записи объекта?

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

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

Метод 1. Программная проверка в модуле объекта

Рассмотрим самый надежный способ, который работает на уровне базы данных. Даже если пользователь попытается изменить значение через групповую обработку или внешнюю обработку, система не даст этого сделать. Мы воспользуемся событием ПередЗаписью в модуле объекта справочника.

Проанализируем логику: нам нужно сравнить значение реквизита, которое пользователь пытается записать (в текущем объекте), с тем значением, которое уже хранится в базе данных (в ссылке). Если они различаются и объект не является новым, мы отменяем запись. Разберем по шагам реализацию этого кода:


Процедура ПередЗаписью(Отказ)
    
    // 1. Проверяем, не выполняется ли загрузка данных (обмен)
    // Это критически важно, чтобы не нарушить синхронизацию баз
    Если ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;

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

КонецПроцедуры

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

Метод 2. Визуальный запрет на уровне управляемой формы

Проверка при записи — это «последний рубеж», но с точки зрения интерфейса правильно будет вообще не давать пользователю возможности редактировать поле. Рассмотрим, как программно управлять доступностью элементов формы. Мы будем использовать событие ПриЧтенииНаСервере или ПриСозданииНаСервере.

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


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

Разберем различие между свойствами Доступность и ТолькоПросмотр. Если мы установим Доступность = Ложь, поле станет серым и «неживым» — из него нельзя будет даже скопировать текст. При ТолькоПросмотр = Истина пользователь может выделить значение или нажать на кнопку выбора, чтобы открыть карточку валюты, но не может изменить саму привязку в счете. Второй вариант считается более дружелюбным для интерфейса.

Метод 3. Интеллектуальная блокировка (проверка ссылок)

Иногда требования бизнеса мягче: «Запрещено менять валюту, только если по счету уже есть движения в документах». Если бухгалтер просто ошибся при создании и сразу заметил это, жесткая блокировка будет мешать. Проанализируем ситуацию и добавим проверку на наличие ссылок в базе данных с помощью метода НайтиСсылки().


&НаСервере
Функция ЕстьДвиженияПоСчету()
    
    МассивСсылок = Новый Массив;
    МассивСсылок.Добавить(Объект.Ссылка);
    
    ТаблицаСсылок = НайтиСсылки(МассивСсылок);
    
    // Если таблица не пустая, значит на этот счет уже кто-то ссылается (документы или другие справочники)
    Возврат ТаблицаСсылок.Количество() > 0;
    
КонецФункции

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

Метод 4. Использование БСП (Золотой стандарт)

Если вы работаете в современной конфигурации (УТ 11, БП 3.0, ERP), то самым правильным решением будет использование механизма «Запрет редактирования реквизитов объектов» из состава БСП. Вы наверняка видели в типовых решениях кнопку «Разрешить редактирование реквизитов» в меню «Еще».

Посмотрим на алгоритм подключения этого механизма:

  1. В модуле формы в процедуре ПриСозданииНаСервере необходимо вызвать инициализацию подсистемы.
  2. В модуле менеджера объекта нужно описать, какие именно реквизиты являются «ключевыми» и должны блокироваться.

Пример кода в модуле менеджера справочника СчетаОрганизаций:


Процедура ПриОпределенииОбъектовСЗапрещеннымиРеквизитами(СписокОбъектов) Экспорт
    СписокОбъектов.Вставить(Метаданные.Справочники.СчетаОрганизаций.Имя);
КонецПроцедуры

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

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

Метод 5. Ограничение через Роли (права доступа)

Проанализируем еще один вариант, не требующий написания кода. В конфигураторе можно настроить ограничения на уровне записей или полей. Если открыть конкретную роль (например, «Бухгалтер»), найти там справочник СчетаОрганизаций, можно снять галочку «Редактирование» для реквизита ВалютаСчета.

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

Резюме и рекомендации

Мы рассмотрели несколько способов решения задачи. Какой из них выбрать? Проанализируем критерии:

Помните, что лучший интерфейс — тот, который предотвращает ошибку пользователя еще до того, как она будет совершена. Комбинация блокировки на форме и контрольной проверки в модуле объекта является наиболее профессиональным подходом в разработке на 1С.

← На главную