Почему не выводятся данные в шапку печатной формы 1С и как правильно работать с выборкой запроса?

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

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

Разбор основной ошибки: позиционирование курсора

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


РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();

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

Выясним причину, по которой этот код не работает. Метод Выбрать() возвращает объект ВыборкаИзРезультатаЗапроса, но в этот момент «курсор» (указатель на текущую запись) находится перед первой записью. Чтобы получить доступ к данным, необходимо переместить курсор на первую строку. Это делается с помощью метода Следующий().

Решение 1: Использование метода Следующий() и Сбросить()

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


РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();

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

Однако возникает следующая задача: после того как мы заполнили шапку, нам нужно вывести строки табличной части (детальные записи). Но курсор уже стоит на первой строке, и если мы начнем цикл Пока Выборка.Следующий() Цикл, то пропустим первую запись или получим некорректный обход.

Здесь на помощь приходит метод Сбросить(). Он возвращает указатель выборки в исходное состояние (перед первой записью), что позволяет нам снова пройтись по данным в цикле:


Выборка.Сбросить(); // Возвращаемся в начало

Пока Выборка.Следующий() Цикл
    ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
    ОбластьСтрока.Параметры.Номенклатура = Выборка.ВидРаботыНаименование;
    ТабДок.Вывести(ОбластьСтрока);
КонецЦикла;

Решение 2: Оптимизация через метод Заполнить()

Для ускорения написания кода и уменьшения количества ошибок рекомендуется использовать метод Заполнить() для параметров области. Этот метод автоматически сопоставляет имена параметров в макете с именами полей в объекте (в данном случае — в выборке).

Разберем по шагам, как это упрощает работу:

  1. В запросе даем полям такие же псевдонимы, какие имена параметров заданы в макете (например, ТЧ.Ссылка.Контрагент КАК Контрагент).
  2. В коде вместо построчного присваивания используем одну команду.

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

Это не только сокращает объем текста в модуле, но и работает производительнее на стороне сервера 1С.

Решение 3: Обход по группировкам (Профессиональный подход)

Если печатная форма сложная, лучше всего использовать структуру запроса с итогами или группировками. Проанализируем ситуацию, когда данные шапки выносятся в отдельную группировку. Это позволяет избежать использования метода Сбросить().

Пример построения кода с обходом по группировкам:


// В запросе добавляем ИТОГИ ПО Ссылка
РезультатЗапроса = Запрос.Выполнить();
ВыборкаПоДокументам = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);

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

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

Дополнительные советы по оформлению печатных форм

Чтобы ваша печатная форма выглядела профессионально и корректно работала у пользователя, обратите внимание на следующие моменты:

Подведем итог: главная причина отсутствия данных в шапке — попытка чтения из объекта ВыборкаИзРезультатаЗапроса без предварительного вызова Следующий(). Используйте либо метод Сбросить() для повторного обхода, либо структуру запроса с группировками для более чистого и эффективного кода.

← На главную