Как напечатать текущую строку табличной части документа во внешней печатной форме в 1С?

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

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

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

В чем заключается проблема передачи контекста строки

Проанализируем архитектуру клиент-серверного взаимодействия в управляемом приложении:

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

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

Способ 1. Использование команды «ВызовКлиентскогоМетода» и поиск формы по ссылке

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

Разберем регистрацию команды в модуле объекта внешней обработки в функции СведенияОВнешнейОбработке():


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

Теперь в модуле формы внешней обработки или общем клиентском модуле обработаем выполнение команды. На клиенте мы можем получить существующий экземпляр открытой формы документа по ссылке через метод ПолучитьФорму():


&НаКлиенте
Процедура Печать(ИдентификаторКоманды, ОбъектыНазначения) Экспорт
    
    СсылкаНаДокумент = ОбъектыНазначения[0];
    
    // Получаем открытую форму документа по переданной ссылке
    ПараметрыФормы = Новый Структура("Ключ", СсылкаНаДокумент);
    ФормаДокумента = ПолучитьФорму("Документ.СборкаТоваров.ФормаОбъекта", ПараметрыФормы);
    
    // Проверяем наличие активной строки в табличной части
    ЭлементТаблицы = ФормаДокумента.Элементы.Сотрудники;
    ТекущиеДанныеСтроки = ЭлементТаблицы.ТекущиеДанные;
    
    Если ТекущиеДанныеСтроки = Неопределено Тогда
        ПоказатьПредупреждение(, "Не выбрана строка для печати!");
        Возврат;
    КонецЕсли;
    
    НомерСтроки = ТекущиеДанныеСтроки.НомерСтроки;
    
    // Передаем полученный номер строки в серверную процедуру формирования табличного документа
    СформироватьИПоказатьПечатнуюФорму(СсылкаНаДокумент, НомерСтроки);
    
КонецПроцедуры

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

Способ 2. Регистрация команды с открытием формы обработки

Если требуется предоставить пользователю возможность предварительно настроить параметры печати или уточнить выбор строки, можно использовать тип команды ТипКомандыОткрытиеФормы().

Посмотрим на пример регистрации команды:


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

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


&НаКлиенте
Процедура ПриОткрытии(Отказ)
    
    Если Параметры.Свойство("ОбъектыНазначения") И Параметры.ОбъектыНазначения.Количество() > 0 Тогда
        СсылкаНаОбъект = Параметры.ОбъектыНазначения[0];
        Форма = ПолучитьФорму("Документ.СборкаТоваров.ФормаОбъекта", Новый Структура("Ключ", СсылкаНаОбъект));
        
        Если Форма.Элементы.Сотрудники.ТекущиеДанные <> Неопределено Тогда
            ИдентификаторСтроки = Форма.Элементы.Сотрудники.ТекущиеДанные.НомерСтроки;
        КонецЕсли;
    КонецЕсли;
    
КонецПроцедуры

Ограничения и альтернативные подходы

Проанализируем нюансы работы данных методов в различных ситуациях:

  1. Печать из формы списка: Если внешняя печатная форма вызывается из списка или журнала документов, форма самого документа физически не открыта на клиенте. Метод ПолучитьФорму() откроет новый экземпляр или вернет форму по умолчанию, где ТекущиеДанные табличной части будут пустыми. Поэтому для печати из списков рекомендуется открывать диалоговую форму внешней обработки со списком строк для ручного выбора.
  2. Поиск через коллекцию открытых окон: Если в системе может быть открыто несколько окон или метод ПолучитьФорму() не возвращает нужный контекст, можно обойти открытые окна через клиентский метод ПолучитьОкна() и найти окно нужного документа по соответствию ссылки.
  3. Использование расширения конфигурации: Если конфигурация допускает использование расширений, альтернативным решением является добавление команды непосредственно в командную панель табличной части документа. В контексте обработчика команды формы табличной части свойство Элементы.ИмяТаблицы.ТекущиеДанные доступно напрямую без необходимости поиска формы.
← На главную