Как вывести данные из связанных справочников в печатную форму 1С?

Программист 1С v8.3 (Обычные формы) Сфера услуг, туризм и социальный сектор
← На главную

При разработке печатных форм в 1С часто возникает задача: вывести данные, которых нет напрямую в текущем документе, но которые доступны через цепочку связей в справочниках. Например, в документе Медицинская карта есть ссылка на студента, у студента указана группа, а у группы есть вышестоящий элемент — факультет. Рассмотрим, как правильно «дотянуться» до этих данных и вывести их в печатный документ.

Постановка задачи и анализ ситуации

Представим ситуацию: имеется документ МедицинскиеКарты. В его реквизитах есть поле ФИОСтудента (ссылка на справочник Студенты). В справочнике Студенты есть реквизит УчебнаяГруппа, а структура справочника групп такова, что факультет является либо родителем группы, либо отдельным реквизитом. Нам необходимо вывести название факультета в шапку печатной формы.

Типичная ошибка начинающего разработчика — попытка обратиться к данным напрямую в коде формирования области макета, используя конструкцию вида Объект.Студент.Группа.Родитель. Проанализируем, почему это часто приводит к ошибке «Переменная не определена» или «Поле объекта не обнаружено».

Разбор типичной ошибки

В типовой процедуре Печать, созданной конструктором, данные обычно выбираются с помощью запроса. Рассмотрим фрагмент стандартного кода:


Процедура Печать(ТабДок, Ссылка) Экспорт
    Макет = Документы.МедицинскиеКарты.ПолучитьМакет("Печать");
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   МедицинскиеКарты.ФИОСтудента,
        |   МедицинскиеКарты.УчебнаяГруппа
        |ИЗ
        |   Документ.МедицинскиеКарты КАК МедицинскиеКарты
        |ГДЕ
        |   МедицинскиеКарты.Ссылка В (&Ссылка)";
    
    Запрос.Параметры.Вставить("Ссылка", Ссылка);
    Выборка = Запрос.Выполнить.Выбрать();
    // ... получение областей макета ...
КонецПроцедуры

Когда мы пытаемся написать внутри цикла обхода выборки код Шапка.Параметры.Факультет = ФИОСтудента.УчебнаяГруппа.Родитель;, система выдает ошибку. Это происходит потому, что ФИОСтудента — это не переменная в контексте модуля, а поле из результата запроса. К нему нужно обращаться через переменную Выборка (например, Выборка.ФИОСтудента), но даже в этом случае мы получим лишь ссылку на студента, а не его группу или факультет, если они не были извлечены запросом.

Решение №1: Изменение текста запроса (Оптимальный способ)

Самый правильный и производительный способ — получить все необходимые данные сразу в запросе. В языке запросов 1С реализован механизм «разыменования» ссылочных полей через точку. Проанализируем, как изменить текст запроса, чтобы получить название факультета.

Нам нужно добавить в секцию ВЫБРАТЬ путь через точку от основного объекта:


Запрос.Текст = 
    "ВЫБРАТЬ
    |   МедицинскиеКарты.ФИОСтудента,
    |   МедицинскиеКарты.ФИОСтудента.УчебнаяГруппа.Родитель КАК Факультет,
    |   МедицинскиеКарты.Дата,
    |   МедицинскиеКарты.Номер
    |ИЗ
    |   Документ.МедицинскиеКарты КАК МедицинскиеКарты
    |ГДЕ
    |   МедицинскиеКарты.Ссылка В (&Ссылка)";

В этом примере мы создали псевдоним Факультет. Теперь это поле доступно в выборке. Далее в коде формирования печатной формы нам достаточно заполнить параметры области макета:


Пока Выборка.Следующий() Цикл
    Шапка = Макет.ПолучитьОбласть("Шапка");
    // Заполняем все параметры, имена которых совпадают с именами полей запроса
    Шапка.Параметры.Заполнить(Выборка); 
    
    // Если имя параметра в макете отличается или нужна доп. обработка:
    // Шапка.Параметры.Факультет = Выборка.Факультет;
    
    ТабДок.Вывести(Шапка);
КонецЦикла;

Решение №2: Получение данных через ссылку (Если запрос нельзя менять)

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

  1. Убедимся, что в макете (Табличном документе) в нужной ячейке свойство Заполнение установлено в значение Параметр, а имя параметра — Факультет.
  2. В коде после получения области, но до ее вывода в табличный документ, пропишем обращение к данным.

Шапка = Макет.ПолучитьОбласть("Шапка");
Шапка.Параметры.Заполнить(Выборка); // Заполняем стандартные поля

// Получаем данные через переданную в процедуру ссылку
СтудентСсылка = Выборка.ФИОСтудента;
Если ЗначениеЗаполнено(СтудентСсылка) Тогда
    // Цепочка получения данных
    Группа = СтудентСсылка.УчебнаяГруппа;
    Если ЗначениеЗаполнено(Группа) Тогда
        Шапка.Параметры.Факультет = Строка(Группа.Родитель);
    КонецЕсли;
КонецЕсли;

ТабДок.Вывести(Шапка);

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

Дополнительные рекомендации по работе с данными

Выясним причины возможных проблем при использовании данных «через точку» и как их избежать:

1. Использование ПРЕДСТАВЛЕНИЯ в запросе. Чтобы в печатную форму сразу попадала строка с названием (наименованием) объекта, а не сама ссылка, в запросе полезно использовать функцию ПРЕДСТАВЛЕНИЕ. Это особенно актуально, если у объекта настроено сложное представление (например, Фамилия + Инициалы).


|   ПРЕДСТАВЛЕНИЕ(МедицинскиеКарты.ФИОСтудента.УчебнаяГруппа.Родитель) КАК ФакультетНаименование

2. Обработка пустых значений. Если у студента не заполнена группа, то УчебнаяГруппа.Родитель вернет NULL в запросе. Чтобы в печатной форме не было пустого места или странных символов, используйте ЕСТЬNULL:


|   ЕСТЬNULL(ПРЕДСТАВЛЕНИЕ(МедицинскиеКарты.ФИОСтудента.УчебнаяГруппа.Родитель), "Факультет не определен") КАК Факультет

3. Проверка иерархии. Если вы обращаетесь к .Родитель, убедитесь, что в справочнике «Учебные группы» иерархия построена именно так, что факультеты являются группами (папками). Если же «Факультет» — это отдельный реквизит в карточке группы, то обращаться нужно по имени этого реквизита: Студент.УчебнаяГруппа.Факультет.

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

← На главную