Создание внешней печатной формы для управляемого приложения в 1С 8.3

Рассмотрим написание простейшей внешней печатной формы в 1С 8.3 для управляемого приложения на примере конфигураций Бухгалтерия 3.0 и Управление торговлей 11 (данная печатная форма будет работать в обоих этих конфигурациях).

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

Создание внешней обработки

В конфигураторе 1C Предприятия 8 создаем внешнюю обработку (Файл->Новый->Внешняя обработка), задаем имя, добавляем реквизит Документ с типом ДокументСсылка.РеализацияТоваровУслуг, он не является обязательным для работы печатной формы, но пригодится нам для ее регистрации в базе.

создание пустой обработки в 1С 8.3

Создание макета печатной формы

Добавляем новый макет, тип макета оставляем Табличный документ. На макете создаем три области: Шапка, Данные и Подвал. Сделать это можно выделив нужное количество строк и нажав меню Таблица->Имена->Назначить имя (Ctrl+Shift+N).

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

В области Данные создадим параметры для вывода строк табличной части(Номенклатура, цена и т.д.), а в области Подвал для итогов по количеству и сумме.

создание параметра на макете

Программирование

Зайдем в модуль объекта печатной формы Действия->Открыть модуль объекта.

создание реквизита

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

Рассмотрим содержание функции СведенияОВнешнейОбработке(). Для начала создадим ее в модуле:

Функция СведенияОВнешнейОбработке() Экспорт

КонецФункции

Создадим структуру ПараметрыРегистрации в которой и будут храниться все данные необходимые для регистрации.

ПараметрыРегистрации = Новый Структура;

Создадим массив МассивНазначений в котором будут храниться наименования документов и справочников из которых будет производиться печать.

МассивНазначений = Новый Массив;

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

Функция УказатьНаименованиеВнешнейПечатнойФормы()

    Наименование = ЭтотОбъект.Метаданные().Представление();
    Возврат Наименование;

КонецФункции

А теперь заполним переменную.

Наименование = УказатьНаименованиеВнешнейПечатнойФормы();

Заполним МассивНазначений используя реквизит внешней обработки Документ. Также вынесем получение элемента массива в отдельную функцию.

Функция ПолучитьМетаданныеДокументаПечати()

    ПолноеИмя = Документ.Метаданные().ПолноеИмя();
    Возврат ПолноеИмя;

КонецФункции

А теперь добавим полученные данные в массив.

МассивНазначений.Добавить(ПолучитьМетаданныеДокументаПечати());

Конечно этот метод не является правильным для случая, когда у вас несколько назначений, но для одного вполне годится.

Приступим к заполнению структуры ПараметрыРегистрации.

Вид внешней обработки, может быть: ЗаполнениеОбъекта, ДополнительныйОтчет, СозданиеСвязанныхОбъектов, ПечатнаяФорма и т.д.

ПараметрыРегистрации.Вставить("Вид", "ПечатнаяФорма");

Назначение заполним уже полученным массивом:

ПараметрыРегистрации.Вставить("Назначение", МассивНазначений);

Наименование из уже заполненной переменной:

ПараметрыРегистрации.Вставить("Наименование", Наименование);

Номер версии можно поставить любой по желанию:

ПараметрыРегистрации.Вставить("Версия", "1.1");

Безопасный режим не даст печатной форме вносить изменения в базу данных. Но она у нас вполне безобидна =), поэтому ставим значение Ложь.

ПараметрыРегистрации.Вставить("БезопасныйРежим", Ложь);

В поле Информация вносим описание печатной формы для пользователя. Запишем туда Наименование.

ПараметрыРегистрации.Вставить("Информация", Наименование);

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

Функция ПолучитьТаблицуКоманд()

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

    Возврат Команды;
КонецФункции

Вызовем сознанную функцию.

ТаблицаКоманд = ПолучитьТаблицуКоманд();

Добавим команду печати, вынеся этот процесс в отдельную функцию:

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

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

КонецФункции

Параметры функции ДобавитьКоманду:

  • ТаблицаКоманд — созданная в предыдущей функции Таблица значений с типовым набором полей;
  • Представление — передадим в параметр Наименование печатной формы;
  • Идентификатор — передадим в параметр полное наименование внешней обработки. Вынесем процесс получения в отдельную функцию:
    Функция УказатьНаименованиеКомандыПечати()
        Наименование = ЭтотОбъект.Метаданные().ПолноеИмя();
        Возврат Наименование;
    КонецФункции
    
  • Использование * — здесь возможны два значения:
    • ВызовСерверногоМетода — если обязательная функция Печать() будет находиться в модуле объекта печатной формы и выполняться на стороне сервера(в нашем примере будем использовать именно это значение);
    • ВызовКлиентскогоМетода — если обязательная функция Печать() будет находиться в модуле основной формы внешней обработки и выполняться на стороне клиента;
  • ПоказыватьОповещение — параметр отвечает за вывод оповещения о печати;
  • Модификатор — для печатных форм используется значение ПечатьMXL.

Вызов функции выглядит так:

ДобавитьКоманду(ТаблицаКоманд, Наименование, УказатьНаименованиеКомандыПечати(), "ВызовСерверногоМетода", Истина, "ПечатьMXL");

Осталось передать заполненную таблицу команд в ПараметрыРегистрации:

ПараметрыРегистрации.Вставить("Команды", ТаблицаКоманд);

И возвратить их из функции:

Возврат ПараметрыРегистрации;

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

Функция СведенияОВнешнейОбработке() Экспорт

    ПараметрыРегистрации = Новый Структура;
    МассивНазначений = Новый Массив;

    Наименование = УказатьНаименованиеВнешнейПечатнойФормы();

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

    ТаблицаКоманд = ПолучитьТаблицуКоманд();
    ДобавитьКоманду(ТаблицаКоманд, Наименование, УказатьНаименованиеКомандыПечати(), "ВызовСерверногоМетода", Истина, "ПечатьMXL");

    ПараметрыРегистрации.Вставить("Команды", ТаблицаКоманд);

    Возврат ПараметрыРегистрации;

КонецФункции

Функция ПолучитьТаблицуКоманд()

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

    Возврат Команды;
КонецФункции

Функция УказатьНаименованиеВнешнейПечатнойФормы()

    Наименование = ЭтотОбъект.Метаданные().Представление();
    Возврат Наименование;

КонецФункции

Функция УказатьНаименованиеКомандыПечати()

    Наименование = ЭтотОбъект.Метаданные().ПолноеИмя();
    Возврат Наименование;

КонецФункции

Функция ПолучитьМетаданныеДокументаПечати()

    ПолноеИмя = Документ.Метаданные().ПолноеИмя();
    Возврат ПолноеИмя;

КонецФункции

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

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

КонецФункции

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

Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт

КонецПроцедуры
  • МассивОбъектов — массив содержащий ссылки на печатаемые документы или справочники(аналог СсылкаНаОбъект в обычном приложении);
  • КоллекцияПечатныхФорм — таблица значений содержащая сформированные табличные документы;
  • ОбъектыПечати — строковой параметр, в котором передаются имена макетов печатных форм перечисленные через запятую;
  • ПараметрыВывода – параметры вывода табличных документов на печать.

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

Функция ПечатьФормы(МассивОбъектов)

КонецФункции

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

ТабДок = новый ТабличныйДокумент;

Макет = ПолучитьМакет("Макет");

ОбластьШапки   = Макет.ПолучитьОбласть("Шапка");
ОбластьДанные  = Макет.ПолучитьОбласть("Данные");
ОбластьПодвал  = Макет.ПолучитьОбласть("Подвал");

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

Запрос = новый запрос;
Запрос.УстановитьПараметр("МассивОбъектов",МассивОбъектов);
Запрос.Текст = "ВЫБРАТЬ
|   РеализацияТоваровУслугТовары.Номенклатура,
|   РеализацияТоваровУслугТовары.Сумма,
|   РеализацияТоваровУслугТовары.Цена,
|   РеализацияТоваровУслугТовары.Количество,
|   РеализацияТоваровУслугТовары.Ссылка
|ИЗ
|   Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
|ГДЕ
|   РеализацияТоваровУслугТовары.Ссылка В(&МассивОбъектов)";

В параметр запроса передаем МассивОбъектов, что бы указать в условии ГДЕ, что нам нужны данные только тех документов из которых выводим печатную форму. Чтобы получить выборку запроса, сначала выполняем его, а затем выгружаем.

ОбщаяВыборка = Запрос.Выполнить().Выгрузить();

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

Для Каждого СсылкаНаОбъект из МассивОбъектов Цикл

КонецЦикла;

В данном цикле начнем формирование печатных форм каждого из документов.

Заполним параметры шапки и выведем ее в табличный документ.

ОбластьШапки.Параметры.ТекстЗаголовка = "Печатная форма "+СсылкаНаОбъект.Номер;
ОбластьШапки.Параметры.Организация = СсылкаНаОбъект.Организация;

ТабДок.Вывести(ОбластьШапки);

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

Отбор = Новый Структура;
Отбор.Вставить("Ссылка",СсылкаНаОбъект);

Теперь отберем нужные строки используя метод НайтиСтроки(<Структура отбора>) и получим выборку по документу.

Выборка = ОбщаяВыборка.НайтиСтроки(Отбор);

Далее в цикле заполняем параметры области Данные для каждой строки выборки документа и выводим их в табличный документ. Также в цикле считаем итоговые значения количества и суммы. Заполнять каждый параметр в отдельности мы не будем, а используем процедуру ЗаполнитьЗначенияСвойств((<Приемник>, <Источник>) из глобального контекста, она копирует значения свойств <Источника> в свойства <Приемника>. Сопоставление производится по именам свойств. Подробнее об этом можно прочитать в синтаксис-помощнике 1С Предприятия 8.

ИтогоСумма      = 0;
ИтогоКоличество = 0;

Для Каждого Стр из Выборка Цикл
    ЗаполнитьЗначенияСвойств(ОбластьДанные.Параметры,Стр);

    ИтогоСумма = ИтогоСумма + Стр.Сумма;
    ИтогоКоличество = ИтогоКоличество + Стр.Количество;

    ТабДок.Вывести(ОбластьДанные);
КонецЦикла;

Заполним и выведем область Подвал.

ОбластьПодвал.Параметры.ИтогоКоличество = ИтогоКоличество;
ОбластьПодвал.Параметры.ИтогоСумма      = ИтогоСумма;

ТабДок.Вывести(ОбластьПодвал);

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

ТабДок.ВывестиГоризонтальныйРазделительСтраниц();

Возвращаем заполненный табличный документ из функции ПечатьФормы.

Возврат ТабДок;

Код функции ПечатьФормы целиком:

Функция ПечатьФормы(МассивОбъектов) Экспорт
    ТабДок = новый ТабличныйДокумент;

    Макет = ПолучитьМакет("Макет");

    ОбластьШапки   = Макет.ПолучитьОбласть("Шапка");
    ОбластьДанные  = Макет.ПолучитьОбласть("Данные");
    ОбластьПодвал  = Макет.ПолучитьОбласть("Подвал");

    Запрос = новый запрос;
    Запрос.УстановитьПараметр("МассивОбъектов",МассивОбъектов);
    Запрос.Текст = "ВЫБРАТЬ
    |   РеализацияТоваровУслугТовары.Номенклатура,
    |   РеализацияТоваровУслугТовары.Сумма,
    |   РеализацияТоваровУслугТовары.Цена,
    |   РеализацияТоваровУслугТовары.Количество,
    |   РеализацияТоваровУслугТовары.Ссылка
    |ИЗ
    |   Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
    |ГДЕ
    |   РеализацияТоваровУслугТовары.Ссылка В(&МассивОбъектов)";

    ОбщаяВыборка = Запрос.Выполнить().Выгрузить();

    Для Каждого СсылкаНаОбъект из МассивОбъектов Цикл

        ОбластьШапки.Параметры.ТекстЗаголовка = "Печатная форма "+СсылкаНаОбъект.Номер;
        ОбластьШапки.Параметры.Организация = СсылкаНаОбъект.Организация;

        ТабДок.Вывести(ОбластьШапки);

        Отбор = Новый Структура;
        Отбор.Вставить("Ссылка",СсылкаНаОбъект);

        Выборка = ОбщаяВыборка.НайтиСтроки(Отбор);

        ИтогоСумма      = 0;
        ИтогоКоличество = 0;

        Для Каждого Стр из Выборка Цикл
            ЗаполнитьЗначенияСвойств(ОбластьДанные.Параметры,Стр);

            ИтогоСумма = ИтогоСумма + Стр.Сумма;
            ИтогоКоличество = ИтогоКоличество + Стр.Количество;

            ТабДок.Вывести(ОбластьДанные);
        КонецЦикла;

        ОбластьПодвал.Параметры.ИтогоКоличество = ИтогоКоличество;
        ОбластьПодвал.Параметры.ИтогоСумма      = ИтогоСумма;

        ТабДок.Вывести(ОбластьПодвал);

        ТабДок.ВывестиГоризонтальныйРазделительСтраниц();
    КонецЦикла;

    возврат ТабДок;
КонецФункции

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

  • КоллекцияПечатныхФорм — таблица значений содержащая сформированные табличные документы;;
  • ИмяМакета — наименование команды печати;
  • СинонимМакета — наименование печатной формы;
  • ТабличныйДокумент — заполненный табличный документ.

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

Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт

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

КонецПроцедуры

Обратите внимание, что для заполнения параметра ТабличныйДокумент вызывается функция ПечатьФормы, которая описана выше.

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

Продолжение следует…

Смотрите видео по созданию внешней печатной формы для управляемого приложения: