Как программно изменить форму документа и исправить ошибку "unknown form id" в 1С?

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

В разработке на платформе 1С часто возникает задача динамически определять, какую форму документа должен увидеть пользователь. Например, в зависимости от роли пользователя, ему может потребоваться либо полная форма со всеми реквизитами, либо упрощенная. Стандартный механизм для решения этой задачи — использование обработчика события ОбработкаПолученияФормы в модуле менеджера объекта.

Однако при реализации этого механизма можно столкнуться с ошибкой "unknown form id", которая возникает в момент открытия документа. Разберем, почему она появляется и как ее исправить на примере реальной ситуации.

Анализ проблемы: почему возникает ошибка?

Представим, что стоит задача: для документа "Лид" открывать специальную форму ФормаДокументаДляМенеджера. Для этого в модуле менеджера документа Лид мы пишем следующий код:


Процедура ОбработкаПолученияФормы(ВидФормы, Параметры, ВыбраннаяФорма, ДополнительнаяИнформация, СтандартнаяОбработка)
    Если ВидФормы = "ФормаОбъекта" Тогда
        // Казалось бы, все верно: указываем полный путь к форме
        ВыбраннаяФорма = "Документы.Лид.Форма.ФормаДокументаДляМенеджера"; 
        СтандартнаяОбработка = Ложь;
    КонецЕсли;
КонецПроцедуры

На первый взгляд, код выглядит правильным. Мы перехватываем событие получения основной формы объекта (ВидФормы = "ФормаОбъекта"), присваиваем параметру ВыбраннаяФорма строку с полным именем нужной нам формы и отменяем стандартную обработку (СтандартнаяОбработка = Ложь), чтобы платформа использовала именно нашу форму.

Но при попытке открыть документ система выдает ошибку "unknown form id". Это означает, что платформа не смогла найти форму по указанному нами строковому идентификатору.

Важный момент: Обработчик ОбработкаПолученияФормы выполняется на сервере. Поэтому попытки использовать в нем клиентские методы, такие как ПолучитьФорму() или ОткрытьФорму(), приведут к ошибке, так как эти методы недоступны в серверном контексте.

Выясним причину ошибки "unknown form id". Чаще всего она кроется в банальной опечатке.

Решение 1: Внимательная проверка имени формы

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

Проанализируем строку из примера: "Документы.Лид.Форма.ФормаДокументаДляМенеджера".

Стандартный синтаксис для полного имени формы объекта следующий:

<Имя коллекции объектов в единственном числе>.<Имя объекта>.Форма.<Имя формы>

Ключевой момент здесь — "в единственном числе". Для документов это будет "Документ", для справочников — "Справочник" и так далее.

В нашем коде используется "Документы" во множественном числе, что и является ошибкой. Исправим ее:


Процедура ОбработкаПолученияФормы(ВидФормы, Параметры, ВыбраннаяФорма, ДополнительнаяИнформация, СтандартнаяОбработка)
    Если ВидФормы = "ФормаОбъекта" Тогда
        // Исправляем "Документы" на "Документ"
        ВыбраннаяФорма = "Документ.Лид.Форма.ФормаДокументаДляМенеджера"; 
        СтандартнаяОбработка = Ложь;
    КонецЕсли;
КонецПроцедуры

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

Решение 2: Использование объекта `Метаданные` для надежности

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

Этот подход имеет несколько преимуществ:

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

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


Процедура ОбработкаПолученияФормы(ВидФормы, Параметры, ВыбраннаяФорма, ДополнительнаяИнформация, СтандартнаяОбработка)
    Если ВидФормы = "ФормаОбъекта" Тогда
        // Получаем полное имя формы через объект Метаданные
        // Этот способ надежен и защищен от опечаток
        ВыбраннаяФорма = Метаданные.Документы.Лид.Формы.ФормаДокументаДляМенеджера.ПолноеИмя();
        СтандартнаяОбработка = Ложь;
    КонецЕсли;
КонецПроцедуры

Теперь код не только работает корректно, но и соответствует лучшим практикам разработки на 1С.

Практический пример: назначение формы в зависимости от роли пользователя

Давайте объединим все полученные знания и решим исходную задачу — открывать специальную форму только для пользователей с определенной ролью. Например, для роли "Менеджер".

Для проверки наличия роли у текущего пользователя используется функция РольДоступна("ИмяРоли").


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

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

← На главную