Как получить доступ к комментарию и метаданным внешней обработки в управляемых формах 1С 8.3?

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

Переход со старых конфигураций 1С версии 8.2 (работавших на обычных формах, таких как ЗИКБУ 1.0) на современные решения версии 8.3 (на платформе управляемых форм, например, ЗКГУ 3.1 или ЗУП 3.1) часто преподносит разработчикам сюрпризы. Одним из таких классических затруднений является «исчезновение» привычных свойств и ключевых слов в контексте модуля формы.

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

Разберем причину: почему ЭтотОбъект больше не работает в управляемой форме?

Давайте проанализируем, почему в обычных формах (ОФ) конструкция ЭтотОбъект.Метаданные().Комментарий отрабатывала без ошибок, а в управляемых формах (УФ) она вызывает сбой компиляции или выполнения. Дело в кардинальном изменении архитектуры взаимодействия клиента и сервера.

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

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

---

Решение №1: Использование функции РеквизитФормыВЗначение на сервере

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

Для преобразования легких данных формы в полноценный прикладной объект используется стандартная функция платформы РеквизитФормыВЗначение(). Рассмотрим по шагам, как реализовать этот алгоритм в обработчике создания формы:


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

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

---

Решение №2: Вынос логики в модуль объекта внешней обработки

Существует и альтернативный архитектурный подход. В управляемом приложении модуль управляемой формы и модуль объекта строго разделены. Внутри модуля объекта внешней обработки контекст остается прежним — там ключевое слово ЭтотОбъект по-прежнему ссылается на прикладной объект ВнешняяОбработкаОбъект.

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

В модуле объекта нашей внешней обработки пишем следующий код:


Функция ПолучитьВерсиюИКомментарий() Экспорт
	
	// Здесь ЭтотОбъект работает так же, как и в 8.2, поскольку это контекст модуля объекта
	Возврат ЭтотОбъект.Метаданные().Комментарий;
	
КонецФункции

Теперь в модуле управляемой формы мы можем обратиться к этой функции. Однако напрямую вызвать метод модуля объекта из формы нельзя — нам все равно потребуется промежуточное преобразование контекста на сервере:


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

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

---

Почему не работает конструкция Обработки.ИмяОбработки.Создать()?

В процессе обсуждения на форумах часто предлагают использовать конструкцию вида Обработки.ИмяОбработки.Создать().Метаданные().Комментарий. Давайте выясним, почему этот вариант не подходит для интерактивно запускаемых файлов.

Данный метод предназначен исключительно для работы с обработками, которые интегрированы непосредственно в состав метаданных конфигурации (в дереве метаданных в конфигураторе). Если вы запускаете внешнюю обработку как отдельный файл через меню Файл -> Открыть, конфигурация ничего не знает о её внутреннем имени в своей структуре. Попытка вызвать этот метод для внешнего файла приведет к ошибке выполнения «Индекс находится за пределами диапазона» или к обращению к совершенно другой обработке, если имена совпадут.

---

Полезный лайфхак: Получение имени запущенного файла

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

Для этого у объекта ВнешняяОбработкаОбъект есть замечательное стандартное свойство — ИспользуемоеИмяФайла. Давайте модернизируем наш серверный код:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	
	ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
	
	// Получаем путь к файлу
	ПолныйПутьКФайлу = ОбработкаОбъект.ИспользуемоеИмяФайла;
	
	// Отрежем путь, оставив только имя файла для лаконичности заголовка
	ФайлНаДиске = Новый Файл(ПолныйПутьКФайлу);
	ИмяФайла = ФайлНаДиске.Имя;
	
	КомментарийМетаданных = ОбработкаОбъект.Метаданные().Комментарий;
	
	// Формируем красивый и информативный заголовок
	ЭтаФорма.Заголовок = СтрШаблон("%1 (Файл: %2) | %3", 
		ЭтаФорма.Заголовок, 
		ИмяФайла, 
		КомментарийМетаданных);
		
КонецПроцедуры

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

---

Интеграция с БСП (ЗКГУ 3.1 / ЗУП 3.1): Динамическая регистрация

Поскольку современные конфигурации (включая ЗКГУ 3.1) построены на базе БСП (Библиотеки стандартных подсистем), внешние обработки крайне рекомендуется регистрировать в справочнике «Дополнительные отчеты и обработки».

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


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

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

← На главную