Почему печатная форма документа в 1С формируется со второй строки и как это исправить?

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

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

Выясняем причину: как работают итоги в запросе 1С

Основная причина возникновения пустой первой строки кроется в особенностях обхода результата запроса, содержащего секцию ИТОГИ. Рассмотрим механизм детально:

  1. Когда в тексте запроса присутствует конструкция ИТОГИ, результат запроса приобретает иерархическую структуру.
  2. Если вызвать метод РезультатЗапроса.Выбрать() без явного указания параметров, платформа по умолчанию применяет режим ОбходРезультатаЗапроса.ПоГруппировкам.
  3. При таком режиме первая запись выборки верхнего уровня представляет собой строку общих итогов по всей выборке. В этой строке детальные реквизиты конкретного документа (например, ссылка, номер или дата) не заполнены и имеют значение NULL.
  4. Когда в цикле выполняется вызов Шапка.Параметры.Заполнить(Выборка), параметры области макета заполняются пустыми значениями из строки общих итогов, после чего пустая область выводится в ТабличныйДокумент. Только на следующей итерации цикла выборка переходит к фактическим данным первого документа, из-за чего визуально печать начинается со второй строки.

Вариант 1. Удаление секции итогов из запроса

Если запрос предназначен для простой последовательной печати документов или их реквизитов и вам не требуется рассчитывать промежуточные или общие агрегатные суммы, наиболее простым и эффективным решением будет удаление конструкции ИТОГИ из текста запроса.

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


Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ
|	Работы.Ссылка КАК Ссылка,
|	Работы.Номер КАК Номер,
|	Работы.Дата КАК Дата,
|	Работы.Контрагент КАК Контрагент
|ИЗ
|	Документ.Работы КАК Работы";

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

ТабДок = Новый ТабличныйДокумент;
Макет = Документы.Работы.ПолучитьМакет("Печать");
ОбластьШапка = Макет.ПолучитьОбласть("Шапка");

Пока Выборка.Следующий() Цикл
	ОбластьШапка.Параметры.Заполнить(Выборка);
	ТабДок.Вывести(ОбластьШапка);
КонецЦикла;

Вариант 2. Корректный многоуровневый обход выборки с итогами

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

Рассмотрим структуру такого обработчика:


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

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

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

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

Как разместить по 2 документа на одном печатном листе

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

  1. Использование штатного свойства табличного документа:

    У объекта ТабличныйДокумент есть свойство ЭкземпляровНаСтранице. Установив значение в 2, мы передаем управление компоновкой платформе 1С:

    
    ТабДок.ЭкземпляровНаСтранице = 2;
    ТабДок.АвтоМасштаб = Истина;
    
  2. Программный вывод разделителей страниц:

    Если требуется вручную контролировать разбиение на страницы (например, разделять печатные бланки чертой или гарантировать разрыв только после каждого четного документа), применим метод ВывестиГоризонтальныйРазделительСтраниц():

    
    СчетчикДокументов = 0;
    
    Пока ВыборкаДокумент.Следующий() Цикл
    	СчетчикДокументов = СчетчикДокументов + 1;
    	
    	// Если это не первый документ и он нечетный, делаем разрыв страницы
    	Если СчетчикДокументов > 1 И СчетчикДокументов % 2 = 1 Тогда
    		ТабДок.ВывестиГоризонтальныйРазделительСтраниц();
    	КонецЕсли;
    	
    	ОбластьШапка.Параметры.Заполнить(ВыборкаДокумент);
    	ТабДок.Вывести(ОбластьШапка);
    КонецЦикла;
    
  3. Контроль переноса методом ПроверитьВывод():

    Чтобы исключить ситуацию, при которой второй документ разрывается пополам между страницами, перед выводом области формируют массив областей и передают его в функцию ТабДок.ПроверитьВывод(МассивОбластей). Если метод возвращает Ложь, перед выводом области вызывается принудительный разделитель страниц.

Обратите внимание: второй параметр в вызове ТабДок.Вывести(Шапка, 0) задает уровень группировки строк в результирующем табличном документе и не влияет на вертикальные отступы или разбиение на страницы.

← На главную