Как отчет на СКД сделать внешней печатной формой документа

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

В практике разработки на платформе 1С:Предприятие 8.3 часто возникает задача превратить уже готовый отчет, построенный на системе компоновки данных (СКД), во внешнюю печатную форму. Это особенно актуально для типовых конфигураций (УНФ, УТ 11, БП 3.0, ERP), где важно сохранить типовую конфигурацию на поддержке, реализуя дополнительные требования через внешние обработки. Разберем подробно, как реализовать этот механизм, используя возможности Библиотеки стандартных подсистем (БСП).

Постановка задачи и выбор подхода

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

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

В данной статье мы подробно остановимся на первом варианте, так как он наиболее полно соответствует понятию «печатная форма».

Шаг 1. Подготовка структуры внешней обработки

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

Теперь перейдем в модуль объекта внешней обработки. Здесь нам необходимо реализовать обязательную функцию СведенияОВнешнейОбработке, чтобы система БСП «узнала» нашу печатную форму.


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

Процедура ДобавитьКоманду(ТаблицаКоманд, Представление, Идентификатор, Использование, ПоказыватьОповещение = Ложь, Модификатор = "")
    НоваяКоманда = ТаблицаКоманд.Добавить();
    НоваяКоманда.Представление = Представление;
    НоваяКоманда.Идентификатор = Идентификатор;
    НоваяКоманда.Использование = Использование;
    НоваяКоманда.ПоказыватьОповещение = ПоказыватьОповещение;
    НоваяКоманда.Модификатор = Модификатор;
КонецПроцедуры

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

Шаг 2. Реализация механизма печати

Когда пользователь нажимает кнопку в меню «Печать», БСП вызывает экспортную процедуру Печать в модуле объекта внешней обработки. Нам нужно проанализировать массив объектов (ссылок на документы) и для каждого сформировать результат компоновки.

Рассмотрим код процедуры Печать и вспомогательной функции формирования табличного документа:


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

Шаг 3. Программная инициализация СКД

Это самая важная часть задачи. Нам нужно вручную запустить «движок» СКД. Разберем по шагам, что делает функция СформироватьТабДокНаОсновеСКД:

  1. Получение схемы: Мы извлекаем макет ОсновнаяСхемаКомпоновкиДанных из текущей обработки.
  2. Установка настроек: Мы берем настройки по умолчанию и программно устанавливаем значение параметра (ссылку на документ).
  3. Компоновка макета: Используем КомпоновщикМакетаКомпоновкиДанных для генерации макета выполнения.
  4. Процессор компоновки: Выполняем запрос к базе данных.
  5. Вывод результата: Используем ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент для заполнения итогового документа.

Функция СформироватьТабДокНаОсновеСКД(МассивОбъектов, ОбъектыПечати)
    
    ТабДок = Новый ТабличныйДокумент;
    
    // 1. Получаем схему из макетов внешней обработки
    СхемаСКД = ЭтотОбъект.ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
    
    // 2. Получаем настройки по умолчанию
    Настройки = СхемаСКД.НастройкиПоУмолчанию;
    
    // Устанавливаем параметр "Ссылка" (имя параметра должно совпадать с именем в СКД)
    // МассивОбъектов[0] - берем первый документ, если печать одиночная
    ЗначениеПараметра = Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("СсылкаНаОбъект"));
    Если ЗначениеПараметра <> Неопределено Тогда
        ЗначениеПараметра.Значение = МассивОбъектов[0];
        ЗначениеПараметра.Использование = Истина;
    КонецЕсли;
    
    // 3. Подготавливаем макет компоновки
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаСКД, Настройки, ОбъектыПечати);
    
    // 4. Инициализируем процессор компоновки
    ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);
    
    // 5. Выводим результат в табличный документ
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(ТабДок);
    ПроцессорВывода.Вывести(ПроцессорКомпоновки);
    
    // Дополнительные настройки оформления
    ТабДок.ТолькоПросмотр = Истина;
    ТабДок.АвтоМасштаб = Истина;
    ТабДок.ОриентацияСтраницы = ОриентацияСтраницы.Ландшафт;
    
    Возврат ТабДок;
    
КонецФункции

Важные нюансы и советы

Проанализируем несколько критических моментов, которые могут возникнуть при работе с СКД во внешних печатных формах:

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

Множественная печать: В приведенном примере мы берем только первый объект из МассивОбъектов[0]. Если пользователь выделит в списке несколько документов и нажмет «Печать», сформируется отчет только по первому. Чтобы поддержать пакетную печать, вам следует либо передать весь массив в параметр типа СписокЗначений (если запрос СКД поддерживает условие В (&СсылкаНаОбъект)), либо организовать цикл в процедуре Печать, добавляя результаты в один ТабДок с разрывом страниц. В качестве готового шаблона для компоновки нескольких результатов в единый результирующий документ подойдёт пример вывода отчетов СКД в один табличный документ.

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

Выясним причину, почему иногда макет СКД не подтягивается. Убедитесь, что имя макета в коде ЭтотОбъект.ПолучитьМакет("Имя") в точности совпадает с именем, заданным в дереве объектов внешней обработки. Регистр символов в данном случае имеет значение.

Таким образом, мы рассмотрели полный цикл создания внешней печатной формы на базе СКД. Этот метод позволяет использовать всю мощь системы компоновки данных (группировки, итоги, условное оформление) без необходимости вручную рисовать сложные макеты печатных форм MXL.

← На главную