Разработка внешних печатных форм (ВПФ) для современных конфигураций на базе Библиотеки стандартных подсистем (БСП), таких как «Бухгалтерия предприятия 3.0», имеет ряд нюансов. Часто разработчики сталкиваются с ситуацией, когда обработка идеально работает через меню «Файл — Открыть», но после регистрации в справочнике «Дополнительные отчеты и обработки» при попытке печати из документа возникает ошибка: «Печатная форма недоступна» или «В обработчике печати не был сформирован табличный документ для: ...».
Проанализируем причины этой проблемы и разберем по шагам, как правильно настроить модуль объекта внешней обработки, чтобы избежать подобных ошибок.
Одной из самых коварных ошибок является расхождение между Идентификатором, который мы указываем при регистрации печатной формы, и строковым значением, которое мы проверяем в процедуре Печать. Если система БСП не находит совпадений, она пропускает блок формирования документа, в результате чего коллекция печатных форм остается пустой.
Рассмотрим структуру функции регистрации. Обратим внимание на колонку Идентификатор:
Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = Новый Структура;
ПараметрыРегистрации.Вставить("Вид", "ПечатнаяФорма");
МассивНазначений = Новый Массив;
МассивНазначений.Добавить("Документ.Доверенность");
ПараметрыРегистрации.Вставить("Назначение", МассивНазначений);
ПараметрыРегистрации.Вставить("Наименование", "Доверенность (внешняя)");
ПараметрыРегистрации.Вставить("БезопасныйРежим", Ложь);
ПараметрыРегистрации.Вставить("Версия", "1.0");
Команды = ПолучитьТаблицуКоманд();
// ВАЖНО: Третий параметр — это Идентификатор "Доверенность_М2"
ДобавитьКоманду(Команды, "Доверенность М-2 (внешняя)", "Доверенность_М2", "ВызовСерверногоМетода", Ложь, "ПечатьMXL");
ПараметрыРегистрации.Вставить("Команды", Команды);
Возврат ПараметрыРегистрации;
КонецФункции
Теперь выясним, как эта команда обрабатывается в процедуре Печать. Проанализируем типичную ошибку: если в проверке НужноПечататьМакет указано другое имя, код внутри условия никогда не выполнится.
Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
// Идентификатор в кавычках ДОЛЖЕН совпадать с тем, что в СведенияОВнешнейОбработке
Если УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, "Доверенность_М2") Тогда
ТабДокумент = СформироватьПечатнуюФорму(МассивОбъектов, ОбъектыПечати);
УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(
КоллекцияПечатныхФорм,
"Доверенность_М2",
"Доверенность М-2",
ТабДокумент);
КонецЕсли;
КонецПроцедуры
Когда мы тестируем печатную форму через форму обработки (через «Файл — Открыть»), мы часто передаем в функцию формирования одну конкретную ссылку. Однако механизм ВПФ в БСП всегда передает МассивОбъектов, даже если пользователь нажал кнопку печати в одном конкретном документе.
Посмотрим на распространенную ошибку в тексте запроса и его параметрах. Программисты часто забывают заменить условие равенства на условие вхождения в список.
Неправильно:
ТекстЗапроса = "ВЫБРАТЬ ... ГДЕ Документ.Ссылка = &Ссылка";
Запрос.УстановитьПараметр("Ссылка", МассивОбъектов[0]); // Ошибка, если массив пустой или имеет другую структуру
Правильно:
ТекстЗапроса = "ВЫБРАТЬ ... ГДЕ Документ.Ссылка В (&МассивОбъектов)";
Запрос.УстановитьПараметр("МассивОбъектов", МассивОбъектов); // Передаем массив целиком
Использование оператора В (&МассивОбъектов) — это стандарт разработки для БСП. Это позволяет вашей печатной форме корректно работать не только из формы документа, но и при групповой печати из списка документов.
В управляемом приложении, когда обработка запускается как внешняя, у нее нет жесткого контекста ЭтотОбъект при вызове методов получения макета, если вы находитесь в модуле объекта и вызываете его некорректно. Рассмотрим, как правильно получать макет во внешней печатной форме.
В функции формирования печатной формы используйте метод ПолучитьМакет непосредственно:
Функция СформироватьПечатнуюФорму(МассивОбъектов, ОбъектыПечати)
// Получаем макет, принадлежащий данной внешней обработке
Макет = ПолучитьМакет("ПФ_MXL_M2");
ТабДокумент = Новый ТабличныйДокумент;
// Установка параметров печати помогает системе запомнить настройки принтера
ТабДокумент.ИмяПараметровПечати = "ПАРАМЕТРЫ_ПЕЧАТИ_Доверенность_М2";
// ... дальнейшая логика заполнения ...
Возврат ТабДокумент;
КонецФункции
При регистрации ВПФ в поле БезопасныйРежим часто устанавливают значение Истина. В этом режиме внешняя обработка ограничена в правах: она не может вызывать методы некоторых общих модулей (с суффиксом ВызовСервера), работать с файловой системой или использовать привилегированный режим.
Если ваша печатная форма использует функции типа ОбщегоНазначенияБПВызовСервера.ДанныеФизЛица или ОтветственныеЛицаБП.ОтветственныеЛица, и при этом включен безопасный режим, выполнение может прерваться с ошибкой без внятного описания.
Рекомендация: Если вы доверяете коду печатной формы, устанавливайте ПараметрыРегистрации.Вставить("БезопасныйРежим", Ложь);. Также внутри кода формирования печатной формы полезно использовать УстановитьПривилегированныйРежим(Истина), чтобы данные (например, паспортные данные сотрудников или зарплатные сведения) считывались даже у пользователей с ограниченными правами.
Сведем все вышесказанное в единый шаблон, который можно использовать как основу для любой внешней печатной формы в «1С:Бухгалтерия 3.0».
Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = Новый Структура;
ПараметрыРегистрации.Вставить("Вид", "ПечатнаяФорма");
МассивНазначений = Новый Массив;
МассивНазначений.Добавить("Документ.Доверенность");
ПараметрыРегистрации.Вставить("Назначение", МассивНазначений);
ПараметрыРегистрации.Вставить("Наименование", "Доверенность М-2 (внешняя)");
ПараметрыРегистрации.Вставить("Версия", "1.1");
ПараметрыРегистрации.Вставить("БезопасныйРежим", Ложь);
ТаблицаКоманд = Новый ТаблицаЗначений;
ТаблицаКоманд.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка"));
ТаблицаКоманд.Колонки.Добавить("Идентификатор", Новый ОписаниеТипов("Строка"));
ТаблицаКоманд.Колонки.Добавить("Использование", Новый ОписаниеТипов("Строка"));
ТаблицаКоманд.Колонки.Добавить("ПоказыватьОповещение", Новый ОписаниеТипов("Булево"));
ТаблицаКоманд.Колонки.Добавить("Модификатор", Новый ОписаниеТипов("Строка"));
НоваяКоманда = ТаблицаКоманд.Добавить();
НоваяКоманда.Представление = "Доверенность М-2 (внешняя)";
НоваяКоманда.Идентификатор = "ПФ_MXL_M2"; // Это ключ связи
НоваяКоманда.Использование = "ВызовСерверногоМетода";
НоваяКоманда.ПоказыватьОповещение = Ложь;
НоваяКоманда.Модификатор = "ПечатьMXL";
ПараметрыРегистрации.Вставить("Команды", ТаблицаКоманд);
Возврат ПараметрыРегистрации;
КонецФункции
Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
Если УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, "ПФ_MXL_M2") Тогда
ТабличныйДокумент = СформироватьПечатнуюФорму(МассивОбъектов, ОбъектыПечати);
УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(
КоллекцияПечатныхФорм,
"ПФ_MXL_M2",
"Доверенность М-2",
ТабличныйДокумент);
КонецЕсли;
КонецПроцедуры
Функция СформироватьПечатнуюФорму(МассивОбъектов, ОбъектыПечати)
УстановитьПривилегированныйРежим(Истина);
ТабДокумент = Новый ТабличныйДокумент;
Макет = ПолучитьМакет("ПФ_MXL_M2");
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Доверенность.Ссылка КАК Ссылка,
| Доверенность.Номер КАК Номер,
| Доверенность.Дата КАК Дата
|ИЗ
| Документ.Доверенность КАК Доверенность
|ГДЕ
| Доверенность.Ссылка В(&МассивОбъектов)";
Запрос.УстановитьПараметр("МассивОбъектов", МассивОбъектов);
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
// Здесь логика вывода областей макета
ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
ОбластьШапка.Параметры.Заполнить(Выборка);
ТабДокумент.Вывести(ОбластьШапка);
// УправлениеПечатью.ЗадатьОбластьПечатиДокумента позволяет корректно
// разбивать документы при печати комплекта
УправлениеПечатью.ЗадатьОбластьПечатиДокумента(ТабДокумент,
ТабДокумент.ВысотаТаблицы, ОбъектыПечати, Выборка.Ссылка);
КонецЦикла;
Возврат ТабДокумент;
КонецФункции
Чтобы ваша внешняя печатная форма работала стабильно, придерживайтесь следующих правил:
СведенияОВнешнейОбработке должна быть идентична строке в НужноПечататьМакет и ВывестиТабличныйДокументВКоллекцию.В (&МассивОбъектов) в запросах.Печать в модуле объекта обязательно должна иметь ключевое слово Экспорт.Соблюдение этих простых принципов позволит вам создавать надежные ВПФ, которые не будут "падать" после подключения к информационной базе.