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