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