При разработке внешних печатных форм (ВПФ) в среде 1С:Предприятие 8.2 (особенно в режиме толстого клиента) разработчики часто сталкиваются с задачей: напечатать данные не по всему документу, а только по той строке табличной части, на которой в данный момент установлен курсор пользователя. Стандартный механизм подключения ВПФ передает в обработку только ссылку на объект (СсылкаНаОбъект), что создает определенные трудности, так как ссылка — это данные в базе, а положение курсора — это состояние интерфейса (формы). Разберем по шагам, как решить эту задачу.
Рассмотрим типичную ошибку начинающего разработчика. Попытка обратиться к текущей строке напрямую через ссылку, например, СсылкаНаОбъект.МалоценныеАктивы.ТекущаяСтрока, неизменно приведет к ошибке «Поле объекта не обнаружено (ТекущаяСтрока)». Проанализируем причину: объект типа ДокументОбъект или ДокументСсылка содержит коллекции данных (табличные части), но у этих коллекций нет понятия «курсор». Понятие курсора существует только у визуального элемента управления ТабличноеПоле, который расположен на форме.
Следовательно, чтобы узнать, где стоит «маркер», нам нужно добраться до экземпляра формы, которая открыта у пользователя в данный момент.
В толстом клиенте 1С 8.2 (и 8.3 на обычных формах) существует важная особенность работы метода ПолучитьФорму(). Если форма документа с конкретной ссылкой уже открыта на экране, то повторный вызов этого метода с указанием той же ссылки вернет не новое окно, а ссылку на уже существующее и открытое окно документа. Это наш ключ к решению.
Рассмотрим пример кода, который можно разместить в модуле внешней печатной формы в процедуре Печать():
// Получаем форму документа, из которого запущена печать
ФормаДокумента = СсылкаНаОбъект.ПолучитьФорму("ФормаДокумента");
// Проверяем, открыта ли форма в данный момент
Если ФормаДокумента.Открыта() Тогда
// Обращаемся к элементу формы (табличному полю), связанному с табличной частью
ЭлементТЧ = ФормаДокумента.ЭлементыФормы.МалоценныеАктивы;
// Получаем текущую строку, на которой стоит курсор
ТекущаяСтрока = ЭлементТЧ.ТекущаяСтрока;
Если ТекущаяСтрока <> Неопределено Тогда
// Теперь у нас есть данные конкретной строки, и мы можем использовать их для печати
Сообщить("Выбрана номенклатура: " + ТекущаяСтрока.Номенклатура);
// Далее идет логика формирования табличного документа только по этой строке
Иначе
Предупреждение("Не выбрана строка в табличной части!");
КонецЕсли;
Иначе
// Если форма не открыта (печать из списка), мы не сможем определить курсор
Предупреждение("Для печати конкретной строки форма документа должна быть открыта.");
КонецЕсли;
Если ваша внешняя печатная форма имеет свою собственную форму (например, диалоговое окно для выбора параметров печати), мы можем воспользоваться свойством ВладелецФормы. Когда печатная форма вызывается из документа, владельцем ее формы часто становится именно форма этого документа.
Посмотрим на алгоритм действий:
ЭтаФорма.ВладелецФормы.ЭлементыФормы владельца.Этот метод более специфичен и зависит от того, как именно реализован вызов печати в конфигурации, но он позволяет избежать лишних вызовов ПолучитьФорму().
Если бизнес-логика требует частого взаимодействия с конкретными строками, иногда эффективнее использовать механизм «Внешних обработок заполнения табличных частей» вместо обычных печатных форм. В толстом клиенте при вызове такой обработки в процедуру Инициализировать первым параметром передается ОбъектВладелец.
Выясним преимущество этого метода: ОбъектВладелец в данном контексте — это и есть форма документа (или табличное поле). Это дает прямой и легальный доступ к текущему состоянию интерфейса без «хаков» с поиском окон. Вы можете добавить кнопку «Печать строки» прямо в меню заполнения ТЧ.
При реализации данного функционала необходимо учитывать следующие моменты:
ПолучитьФорму() не поможет определить строку, так как визуального «курсора» в табличной части просто не существует. Программа должна адекватно обрабатывать такие ситуации (например, печатать весь документ целиком).ТекущаяСтрока возвращает объект типа СтрокаТабличнойЧасти. Если вам нужно получить индекс (номер) строки, используйте метод Индекс() самой табличной части: СсылкаНаОбъект.МалоценныеАктивы.Индекс(ТекущаяСтрока).ТекущаяСтрока на форме могут быть еще не записаны в базу данных. Если пользователь изменил количество в строке и сразу нажал печать (не записав документ), СсылкаНаОбъект из базы может содержать старые данные, в то время как ТекущаяСтрока из ЭлементыФормы будет содержать актуальные измененные данные.Таким образом, для решения задачи во внешней печатной форме наиболее надежным способом в толстом клиенте является обращение к элементам формы через ПолучитьФорму(). Это позволяет «подсмотреть» за действиями пользователя и вывести на печать именно ту номенклатуру или услугу, которая выделена в интерфейсе.