Почему при программном изменении доступности кнопок формы блокируются кнопки «Провести» и «Связанные документы», и как это исправить?

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

При разработке в среде 1С:Предприятие 8.3 на управляемых формах программисты часто сталкиваются с задачей ограничить права пользователя на редактирование документа. Распространенный подход — обойти все элементы формы в цикле и установить для них свойство Доступность в значение Ложь. Однако здесь разработчиков подстерегают неприятные сюрпризы.

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

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

Причина 1. Почему кнопки «Связанные документы» нет в Конфигураторе?

Ответ кроется в механизмах взаимодействия платформы с БСП (Библиотекой стандартных подсистем). Кнопка «Связанные документы» (в некоторых конфигурациях она называется «Структура подчиненности») создается и выводится на форму динамически на стороне сервера в момент открытия документа.

Давайте разберем этот процесс по шагам:

  1. При открытии формы документа в процедуре ПриСозданииНаСервере вызывается специализированный метод БСП: ПодключаемыеКоманды.ПриСозданииНаСервере(ЭтотОбъект).
  2. Этот метод анализирует метаданные конфигурации и проверяет, включен ли данный документ в критерий отбора «СвязанныеДокументы».
  3. Если документ удовлетворяет условиям, БСП программно генерирует на форме элемент типа КнопкаФормы и помещает его в командную панель.

Поскольку эта кнопка создается динамически «на лету» в режиме предприятия, в Конфигураторе в дереве элементов формы вы ее не увидите. Однако в коллекции ЭтаФорма.Элементы в режиме отладки эта кнопка физически существует наравне со всеми остальными кнопками.

Причина 2. Почему кнопка «Провести» заблокировалась, а «Провести и закрыть» осталась активной?

Такое поведение объясняется особенностями построения иерархии (дерева элементов) управляемой формы и логикой платформы 1С:

Кроме того, важно помнить: стандартные команды и кнопки (такие как «Записать», «Провести», «Провести и закрыть») при включенном свойстве командной панели Автозаполнение генерируются платформой автоматически в виде элементов типа КнопкаФормы и имеют строго определенные системные имена (например, ФормаПровести, ФормаЗаписать). Они всегда присутствуют в коллекции Элементы.


Способ 1. Фильтрация элементов по именам (Черный и Белый списки)

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

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


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

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

Способ 2. Использование настройки «Состав команд» в Конфигураторе

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

Выполним следующие шаги:

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

Платформа автоматически исключит эти кнопки из командной панели при отрисовке интерфейса у пользователя.

Способ 3. Использование стандартного свойства «ТолькоПросмотр»

В подавляющем большинстве случаев разработчики начинают отключать доступность кнопок командной панели вручную только ради одной цели — запретить пользователю редактировать документ, который уже закрыт для редактирования (например, проведен в закрытом периоде или заблокирован бизнес-процессом).

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

Проанализируем пример кода:


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

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

← На главную