Как правильно разработать внешний отчет без СКД и избежать архитектурных ошибок в 1С

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

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

Разберем причину: разница между контекстом формы и объекта

Для начала проанализируем, почему в управляемом приложении существует такое строгое разделение. В обычных формах (1С 8.2 и ранее) форма была частью объекта, и вы имели прямой доступ ко всем его методам через ключевое слово ЭтотОбъект. В управляемом приложении всё изменилось.

Рассмотрим основные сущности:

  1. ДанныеФормыСтруктура (Объект): Когда вы открываете форму отчета, переменная Объект в модуле формы — это не сам отчет, а лишь его «легкая» проекция. Она содержит значения реквизитов (строки, числа, даты), чтобы их можно было быстро передавать между клиентом и сервером. У этой структуры нет методов для работы с метаданными, таких как ПолучитьМакет() или ВыполнитьЗапрос().
  2. ОтчетОбъект / ОбработкаОбъект: Это полноценный программный объект на стороне сервера. Только он обладает «знанием» о своих макетах, модулях и других свойствах метаданных.

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

Пошаговый алгоритм создания внешнего отчета

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

Шаг 1. Подготовка модуля объекта.

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


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

Шаг 2. Вызов из модуля формы.

Теперь выясним, как правильно связать форму и объект. В модуле формы нам понадобится серверная процедура, которая выполнит преобразование.


// В модуле формы
&НаКлиенте
Процедура Сформировать(Команда)
    // Вызываем серверный метод для получения документа
    ТабличныйДокумент = СформироватьНаСервере();
    
    // Выводим результат пользователю
    ТабличныйДокумент.Показать("Ваш отчет");
КонецПроцедуры

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

Проанализируем альтернативные способы

Рассмотрим ситуацию, если вы принципиально не хотите использовать РеквизитФормыВЗначение. Можно ли обойтись без него? Да, но это часто приводит к менее удачным решениям.

Вариант А: Перенос кода в модуль формы.

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

Вариант Б: Использование менеджера.

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

Оптимизация производительности и отладка

Выясним, почему некоторые разработчики боятся метода РеквизитФормыВЗначение. Основной аргумент — затраты времени на создание объекта. Действительно, если на форме сотни реквизитов и огромные табличные части, сериализация может занять время.

Посмотрим на способы оптимизации:

Итоги и рекомендации

Подводя итог нашему анализу, можно уверенно сказать: использование РеквизитФормыВЗначение("Объект") во внешних отчетах — это золотой стандарт 1С. Именно так написаны тысячи процедур в типовых конфигурациях (ERP, УТ 11, БП 3.0).

Основные выводы:

  1. Модуль объекта — идеальное место для бизнес-логики и формирования данных.
  2. Модуль формы — отвечает только за интерфейс и взаимодействие с пользователем.
  3. Преобразование контекста — необходимый этап для доступа к методам метаданных (макетам).

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

← На главную