Как устранить ошибку «отсутствие отображения типов для управляемой формы» в ЗУП 3.0 при работе с документом Табель

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

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

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

Выясним причину возникновения ошибки

Для начала проанализируем ситуацию с точки зрения архитектуры платформы. Объект типа УправляемаяФорма является сугубо клиентским объектом. Хотя у него есть «проекция» на стороне сервера, платформа 1С не поддерживает сериализацию этого типа. Это означает, что форму невозможно превратить в поток байтов и передать через границу «Клиент — Сервер».

Когда вы в своей обработке выполняете код:


ФормаДокумента = ПолучитьФорму("Документ.ТабельУчетаРабочегоВремени.Форма.ФормаДокумента", Новый Структура("Ключ", СсылкаНаДокумент));
// Попытка передать форму в серверный общий модуль
ОбщийМодульЗУП.ВыполнитьДействиеСФормой(ФормаДокумента);

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

Вариант решения №1: Использование «Структуры-заменителя» (Mock-объект)

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

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

  1. Анализ типового кода: Откройте процедуру общего модуля, которую вы хотите вызвать. Посмотрите, какие свойства параметра Форма она использует. Например, вы видите обращения: ПараметрФорма.Объект, ПараметрФорма.ТолькоПросмотр или ПараметрФорма.ИмяПараметра.
  2. Создание структуры: В своей обработке перед вызовом процедуры сформируйте структуру с аналогичными ключами.

Пример реализации в коде:


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

    // Теперь вызываем типовой модуль
    ТиповойОбщийМодульЗУП.ОбработатьДанныеФормы(ДанныеФормыИмитация);
    
КонецПроцедуры

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

Вариант решения №2: Перенос логики на работу с объектом

Проанализируем ситуацию глубже: документ «Табель учета рабочего времени» в ЗУП 3.0 крайне сложен. Его экранная форма содержит множество вспомогательных данных, которые не хранятся в базе данных напрямую, а рассчитываются «на лету». Однако, практически всегда у типовой процедуры, принимающей форму, есть альтернатива, работающая с ДокументОбъект или набором ссылок.

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

Работа с ДокументОбъект на сервере — это «чистый» путь, который исключает любые ошибки отображения типов и делает вашу обработку более стабильной при обновлениях конфигурации.

Вариант решения №3: Работа через ДанныеФормыСтруктура

Если типовой код слишком жестко завязан на контекст управляемой формы, и обычная структура не помогает, можно использовать преобразование объекта в ДанныеФормыСтруктура. Этот тип данных максимально близок к тому, что видит форма на сервере.

Разберем, как это сделать программно без открытия самой формы:


// Получаем объект документа
ОбъектДокумента = СсылкаНаОбъект.ПолучитьОбъект();

// Преобразуем его в данные формы (имитируем реквизит "Объект")
ДанныеФормы = Новый Структура;
ДанныеОбъекта = ДанныеФормыВЗначение(ОбъектДокумента, Тип("ДанныеФормыСтруктура")); 
// Ошибка! Наоборот:
ЗначениеВДанныеФормы(ОбъектДокумента, ДанныеОбъекта);

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

// Вызываем процедуру
ТиповойМодуль.СервернаяПроцедура(ЛожнаяФорма);

Особенности документа «Табель» в ЗУП 3.0

При работе конкретно с Табелем нужно учитывать, что форма этого документа инициализирует множество коллекций в обработчике ПриСозданииНаСервере. Если вы просто программно получили форму через ПолучитьФорму(), но не открыли ее, эти коллекции будут пустыми.

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

Резюме

Подведем итоги нашего анализа. Ошибка «отсутствие отображения типов» — это сигнал о том, что вы пытаетесь передать интерфейсный объект туда, где должны быть данные. Для решения проблемы:

  1. Используйте Структуру с набором свойств, идентичным реквизитам формы.
  2. Изучите Модуль менеджера документа на предмет наличия процедур, работающих с объектом напрямую.
  3. Избегайте использования ПолучитьФорму() для целей передачи параметров в серверные процедуры общих модулей.

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

← На главную