Как программно установить ТолькоПросмотр для дополнительных реквизитов в 1С:ERP и почему оно сбрасывается?

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

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

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

Выясним причину: почему ТолькоПросмотр сбрасывается?

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

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

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

Решение 1: Вызов собственного кода после обновления элементов БСП

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

Проанализируем пример реализации такого подхода. Нам необходимо переопределить поведение формы после вызова стандартной процедуры БСП ОбновитьЭлементыДополнительныхРеквизитов:


&НаКлиенте
Процедура ПослеПереходаМеждуСтраницами()
    
    // Сначала даем отработать стандартному механизму обновления БСП
    ОбновитьЭлементыДополнительныхРеквизитов();
    
    // Затем вызываем нашу процедуру корректировки свойств
    УстановитьТолькоПросмотрДляСпецифическихРеквизитов();
    
КонецПроцедуры

&НаКлиенте
Процедура УстановитьТолькоПросмотрДляСпецифическихРеквизитов()
    
    // Получаем имя элемента формы с помощью функций БСП или общего модуля
    ПолеДопРеквизита = АДАПТ_РаботаСДопРекв.ПолучитьПолеДополнительногоРеквизитаНаФорме(ЭтаФорма, "КонтрагентСкат_id");
    
    Если ПолеДопРеквизита <> Неопределено Тогда
        ИмяЭлемента = ПолеДопРеквизита.ИмяРеквизитаЗначение;
        Если Элементы.Найти(ИмяЭлемента) <> Неопределено Тогда
            // Принудительно выставляем признак "ТолькоПросмотр"
            Элементы[ИмяЭлемента].ТолькоПросмотр = Истина;
        КонецЕсли;
    КонецЕсли;
    
КонецПроцедуры

Преимущества: Способ относительно прост в реализации и быстро решает проблему «здесь и сейчас».

Минусы: Метод неустойчив к обновлениям конфигурации. При изменении логики БСП или названий процедур в новых версиях ERP наш вызов может перестать работать или потребует повторной адаптации кода.

Решение 2: Блокировка через родительскую группу (самый простой способ)

Вместо того чтобы искать конкретный динамический элемент и пытаться изменить его свойства, мы можем управлять свойствами **родительской группы**, внутри которой БСП размещает эти динамические поля. Обычно на форме присутствует предопределенная группа контейнера (например, ГруппаДополнительныеРеквизиты).

Платформа 1С устроена так, что свойства доступности и просмотра элементов наследуются от их родительских элементов. Если мы заблокируем родительский контейнер, все динамические элементы внутри него унаследуют это поведение автоматически. БСП при этом не перезаписывает свойства самой родительской группы.

Посмотрим на пример кода:


&НаКлиенте или &НаСервере
Процедура ЗаблокироватьГруппуДополнительныхСвойств()
    
    ИмяГруппы = "ГруппаДополнительныеРеквизиты";
    Если Элементы.Найти(ИмяГруппы) <> Неопределено Тогда
        // Блокируем всю группу целиком
        Элементы[ИмяГруппы].ТолькоПросмотр = Истина;
    КонецЕсли;
    
КонецПроцедуры

Если вам требуется заблокировать только часть дополнительных реквизитов, вы можете программно создать подчиненную группу внутри стандартной группы БСП, перенести в нее требуемые элементы и установить свойство ТолькоПросмотр = Истина именно для этой подчиненной группы.

Решение 3: Использование программного Условного оформления (УО)

Механизм Условного оформления формы выполняется платформой на самом последнем этапе визуализации интерфейса. Настройки условного оформления имеют абсолютный приоритет над любыми изменениями свойств элементов, сделанными в коде модулей или процедурах БСП.

Давайте разберем по шагам, как программно добавить правило условного оформления для конкретного дополнительного реквизита на форме:


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

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

Решение 4: Модификация служебной таблицы описания свойств БСП

БСП не просто создает элементы на форме случайным образом. Библиотека хранит метаданные динамических реквизитов в специальных служебных коллекциях формы, таких как Свойства_ОписаниеДополнительныхРеквизитов. Эта коллекция представляет собой таблицу значений, содержащую информацию о доступности, видимости и условиях работы каждого реквизита.

Вместо прямого изменения элемента формы мы можем найти нужную строку в этой таблице и переопределить параметры доступности там. БСП при очередной генерации интерфейса считает наши данные из этой таблицы и сама применит нужные свойства к элементам формы.

Посмотрим на пример программной реализации на сервере:


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

Решение 5: Настройка условий доступности в пользовательском режиме (без кода)

Современные версии БСП позволяют решать подобные задачи вообще без программирования и изменения конфигурации. Мы можем настроить логику доступности реквизита непосредственно в режиме 1С:Предприятие.

Разберем по шагам, как это сделать:

  1. Перейдите в раздел НСИ и администрирование -> Администрирование -> Общие настройки -> Дополнительные реквизиты и сведения.
  2. Найдите необходимый набор свойств (например, свойства справочника Партнеры) и откройте карточку нужного дополнительного реквизита.
  3. В открывшейся форме настройки свойства обратите внимание на гиперссылку «Доступен» (по умолчанию там установлено значение «Всегда»).
  4. Нажмите на эту ссылку и в открывшемся окне настройте формулу зависимости или условие (например, «Доступен, только если заполнено поле Организация»).
  5. Сохраните изменения.

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

Резюме

Мы проанализировали проблему сброса свойства ТолькоПросмотр для дополнительных реквизитов БСП и изучили различные подходы к ее решению. Для простых задач отлично подойдет блокировка через родительскую группу или использование программного условного оформления. Если вы хотите использовать потенциал БСП на максимум — настраивайте доступность реквизитов интерактивно в режиме 1С:Предприятие либо управляйте служебными таблицами описания свойств БСП на сервере.

← На главную