Как настроить печать с нуля на БСП и исправить ошибку «АдресТаблицыКоманд»?

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

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

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

Выясняем причину ошибки «АдресТаблицыКоманд»

При попытке запустить форму документа с кодом интеграции БСП разработчики часто сталкиваются с системным сбоем в общем модуле ПодключаемыеКомандыКлиент:


{ОбщийМодуль.ПодключаемыеКомандыКлиент.Модуль(20)}: Значение не является значением объектного типа (АдресТаблицыКоманд)
    АдресНастроек = Форма.ПараметрыПодключаемыхКоманд.АдресТаблицыКоманд;

Проанализируем ситуацию. Механизм подключаемых команд БСП работает следующим образом: при создании формы на сервере вызывается метод ПодключаемыеКоманды.ПриСозданииНаСервере(ЭтотОбъект). Система динамически опрашивает менеджеры объектов, собирает доступные команды печати, заполнения или отчетов, формирует служебную таблицу команд и помещает ее во временное хранилище. Адрес этого хранилища записывается в структуру внутри реквизита формы ПараметрыПодключаемыхКоманд.

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

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

Пошаговая настройка управляемой формы документа

Рассмотрим, какие именно элементы и обработчики должны присутствовать в модуле управляемой формы документа для корректной работы печати БСП.

Для начала настроим саму форму в конфигураторе:

  1. Добавим реквизит формы ПараметрыПодключаемыхКоманд с типом данных Произвольный.
  2. На командную панель формы добавим группу кнопок. Назовем ее ПодменюПечать. Установим для нее тип Группа - Подменю. Рекомендуется настроить отображение как «Картинка и текст» и выбрать стандартную пиктограмму печати. БСП автоматически найдет эту группу по имени и заполнит ее доступными командами печати при открытии формы.

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


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // СтандартныеПодсистемы.ПодключаемыеКоманды
    ПодключаемыеКоманды.ПриСозданииНаСервере(ЭтотОбъект);
    // Конец СтандартныеПодсистемы.ПодключаемыеКоманды
    
КонецПроцедуры

&НаСервере
Процедура ПриЧтенииНаСервере(ТекущийОбъект)
    
    // СтандартныеПодсистемы.ПодключаемыеКоманды
    ПодключаемыеКомандыКлиентСервер.ОбновитьКоманды(ЭтотОбъект, Объект);
    // Конец СтандартныеПодсистемы.ПодключаемыеКоманды
    
КонецПроцедуры

&НаКлиенте
Процедура ПриОткрытии(Отказ)
    
    // СтандартныеПодсистемы.ПодключаемыеКоманды
    ПодключаемыеКомандыКлиент.НачатьОбновлениеКоманд(ЭтотОбъект);
    // Конец СтандартныеПодсистемы.ПодключаемыеКоманды
    
КонецПроцедуры

// СтандартныеПодсистемы.ПодключаемыеКоманды

&НаКлиенте
Процедура Подключаемый_ВыполнитьКоманду(Команда)
    
    ПодключаемыеКомандыКлиент.ВыполнитьКоманду(ЭтотОбъект, Команда, Объект);
    
КонецПроцедуры

&НаСервере
Процедура Подключаемый_ВыполнитьКомандуНаСервере(Контекст, Результат)
    
    ПодключаемыеКоманды.ВыполнитьКоманду(ЭтотОбъект, Контекст, Объект, Результат);
    
КонецПроцедуры

&НаКлиенте
Процедура Подключаемый_ОбновитьКоманды()
    
    ПодключаемыеКомандыКлиентСервер.ОбновитьКоманды(ЭтотОбъект, Объект);
    
КонецПроцедуры

// Конец СтандартныеПодсистемы.ПодключаемыеКоманды

Обратите внимание, что все обработчики с префиксом Подключаемый_ должны быть явно назначены в свойствах соответствующих элементов формы или событий (например, событие нажатия для динамически создаваемых кнопок автоматически перенаправляется на Подключаемый_ВыполнитьКоманду через механизмы БСП).

Программный интерфейс модуля менеджера документа

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

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


#Область ПрограммныйИнтерфейс

// Заполняет список команд печати.
// 
// Параметры:
//   КомандыПечати – ТаблицаЗначений – состав полей см. в функции УправлениеПечатью.СоздатьКоллекциюКомандПечати.
//
Процедура ДобавитьКомандыПечати(КомандыПечати) Экспорт
    
    // Регистрация печатной формы "Путевой лист"
    КомандаПечати = КомандыПечати.Добавить();
    КомандаПечати.МенеджерПечати = "Документ.ПутевойЛист";
    КомандаПечати.Идентификатор  = "ПФ_ПутевойЛист";
    КомандаПечати.Представление  = НСтр("ru = 'Путевой лист (легковой)'");
    КомандаПечати.ПроверкаПроведенияПередПечатью = Истина;
    КомандаПечати.СписокФорм     = "ФормаСписка,ФормаДокумента";
    
КонецПроцедуры

Теперь проанализируем процедуру Печать. Ее задача — определить, какие именно макеты запросил пользователь (ведь в БСП можно выбрать несколько печатных форм одновременно), сформировать табличные документы и передать их обратно в систему.


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

Разбор критических ошибок при формировании табличного документа

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


// Пример кода С ОШИБКАМИ (так делать НЕ надо)
Функция ПечатьПутевогоЛиста(МассивОбъектов, ОбъектыПечати)
    Ссылка = МассивОбъектов[0]; // Ошибка №1: жесткая привязка к первому элементу массива
    ...
    Макет = Документы.ПутевойЛист.ПолучитьМакет("ПФ_ПутевойЛист");
    ОбластьШапка = Макет.ПолучитьОбласть("ОбластьШапка");
    ЗаполнитьЗначенияСвойств(ОбластьШапка.Параметры, ОбъектыПечати); // Ошибка №2: ОбъектыПечати пуст!
    ...
КонецФункции

Выясним причины этих ошибок и разберем, как написать код правильно:

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


Функция СформироватьПечатнуюФормуПутевогоЛиста(МассивОбъектов, ОбъектыПечати)
    
    ТабДокумент = Новый ТабличныйДокумент;
    ТабДокумент.КлючПараметровПечати = "ПараметрыПечати_ПутевойЛист";    
    ТабДокумент.АвтоМасштаб = Истина;
    
    Макет = Документы.ПутевойЛист.ПолучитьМакет("ПФ_ПутевойЛист");
    
    // Получаем данные для печати одним запросом ко всей выборке объектов
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   ПутевойЛист.Ссылка КАК Ссылка,
        |   ПутевойЛист.Номер КАК Номер,
        |   ПутевойЛист.Дата КАК Дата,
        |   ПутевойЛист.Организация КАК Организация,
        |   ПутевойЛист.Водитель КАК Водитель
        |ИЗ
        |   Документ.ПутевойЛист КАК ПутевойЛист
        |ГДЕ
        |   ПутевойЛист.Ссылка В(&МассивОбъектов)";
    
    Запрос.УстановитьПараметр("МассивОбъектов", МассивОбъектов);
    Выборка = Запрос.Выполнить().Выбрать();
    
    ПервыйДокумент = Истина;
    
    Пока Выборка.Следующий() Цикл
        
        // Разделяем документы при печати на новые страницы
        Если Не ПервыйДокумент Тогда
            ТабДокумент.ВывестиГоризонтальныйРазделительСтраниц();
        КонецЕсли;
        ПервыйДокумент = Ложь;
        
        // Запоминаем начальную строку для текущего документа
        НомерСтрокиНачало = ТабДокумент.ВысотаТаблицы + 1;
        
        // Выводим шапку
        ОбластьШапка = Макет.ПолучитьОбласть("ОбластьШапка");
        ОбластьШапка.Параметры.Заполнить(Выборка);
        ТабДокумент.Вывести(ОбластьШапка);
        
        // Выводим организацию
        ОбластьОрганизация = Макет.ПолучитьОбласть("ОбластьОрганизация");
        ОбластьОрганизация.Параметры.Заполнить(Выборка);
        ТабДокумент.Вывести(ОбластьОрганизация);
        
        // Ассоциируем выведенную область с конкретным объектом для механизмов БСП
        // (это нужно для корректной отправки по почте, сохранения файлов и разбиения по копиям)
        УправлениеПечатью.ЗадатьОбластьПечатиДокумента(
            ТабДокумент, 
            НомерСтрокиНачало, 
            ОбъектыПечати, 
            Выборка.Ссылка
        );
        
    КонецЦикла;
    
    Возврат ТабДокумент;
    
КонецФункции

Регистрация документа в переопределяемом модуле

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

Перейдем в общий модуль УправлениеПечатьюПереопределяемый и найдем процедуру ПриОпределенииОбъектовСКомандамиПечати. Добавим туда наш новый документ:


// Определяет объекты метаданных, в менеджерах которых настроены команды печати.
//
// Параметры:
//   СписокОбъектов - Массив - объекты метаданных с командами печати.
//
Процедура ПриОпределенииОбъектовСКомандамиПечати(СписокОбъектов) Экспорт
    
    СписокОбъектов.Добавить(Метаданные.Документы.ПутевойЛист);
    
КонецПроцедуры

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

Автоматическая поддержка Внешних печатных форм (ВПФ)

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

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

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

← На главную