Почему съезжают данные при выводе отчета в 1С и как правильно настроить макет

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

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

В этой статье мы подробно проанализируем ситуацию, когда добавление одного параметра (штрихкода) ломает структуру всей таблицы, и разберем механизмы 1С, которые управляют заполнением табличного документа.

Механика работы методов Вывести и Присоединить

Для начала разберем базовые принципы работы с объектом ТабличныйДокумент. Существует два основных метода заполнения документа областями из макета:

  1. Вывести() — этот метод добавляет область вниз. Каждое использование Вывести создает новую строку (или группу строк) в итоговом документе. Указатель текущей строки при этом смещается в самый низ документа.
  2. Присоединить() — этот метод добавляет область справа от последней выведенной области. Важно понимать: Присоединить работает именно с той строкой (или набором строк), которая была выведена последним методом Вывести.

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

Анализ типичной ошибки: пропуск пустых данных

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


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

В этом примере, если для одной номенклатуры есть три типа цен, а для другой — только два, и один из них пустой, то итоговое количество колонок в строках будет разным. Это визуально ломает вертикальную структуру отчета. Чтобы колонки всегда стояли друг под другом, присоединять область нужно в любом случае, даже если она пустая. Мы должны обеспечить одинаковое количество вызовов Присоединить для каждой горизонтальной строки.

Разбор кейса с добавлением штрихкода (ШК)

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

Посмотрим на исправленный подход к выводу детальных записей:


// Сначала выводим основное «тело» строки (Номенклатура, ШК, Характеристика)
Область_Детали_Тело.Параметры.Заполнить(Выборка_ЕдИзм);
_Дополнительно = Новый Структура;
_Дополнительно.Вставить("шк", глСформироватьВнутреннийШтрихкод(Выборка_ЕдИзм.Номенклатура));
Область_Детали_Тело.Параметры.Заполнить(_Дополнительно);

// ВЫВОДИМ строку (создаем новую строку в документе)
ТабличныйДокумент.Вывести(Область_Детали_Теo, Детали_Уровень + 1);

// ПРИСОЕДИНЯЕМ колонку с единицей измерения к только что выведенной строке
Область_Детали_ЕдИзм.Параметры.Заполнить(Выборка_ЕдИзм);
ТабличныйДокумент.Присоединить(Область_Детали_ЕдИзм);

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

Проблема «задвоения» строк и её решение

Если при выводе данных вы замечаете дублирование строк (например, две строки с одинаковой характеристикой), проанализируйте логику вложенности выборок. Часто разработчик делает Выбрать() по группировке «Характеристика», а внутри еще один Выбрать() по группировке «Единица измерения». Если в данных одна единица измерения соответствует одной характеристике, может возникнуть путаница: на каком уровне вызывать метод Вывести.

Рекомендация: Если данные должны располагаться в одной горизонтальной линии, используйте Вывести только для самой левой части макета, а всё, что находится правее — добавляйте через Присоединить в рамках одного прохода цикла.

Использование параметров отступа и автогруппировки

Для иерархических отчетов важно правильно отображать уровни вложенности. В 1С это реализуется через свойство Отступ ячейки и методы работы с группировками. Проанализируем код управления отступом:


_Уровень = ?(ВыводитьИерархию, Выборка_Номенклатура.Уровень(), 0);
ОбластьНоменклатураТело.Область(1,1,1,1).Отступ = _Уровень;
ТабличныйДокумент.Вывести(ОбластьНоменклатураТело, _Уровень, , Истина);

Здесь используется метод Область(1,1,1,1), который выбирает первую ячейку выводимой секции. Установка отступа программно позволяет создать визуальную древовидную структуру без использования множества разных областей в макете. Однако помните, что если вы меняете отступ у области программно, это изменение сохраняется для всех последующих вызовов, пока вы не перезапишите его. Хорошим тоном считается явно задавать отступ для каждой выводимой строки.

Почему Система компоновки данных (СКД) предпочтительнее?

Если задача переделки отчета становится слишком трудоемкой из-за «поехавших» колонок, стоит рассмотреть переход на СКД. Система компоновки данных берет на себя всю рутину по расчету геометрии таблицы. Вам не нужно следить за тем, сколько раз был вызван Присоединить и не забыли ли вы вывести пустую ячейку для выравнивания — СКД строит таблицу как целостный объект на основе структуры запроса.

Основные преимущества СКД в данном контексте:

  1. Автоматическое управление ресурсами: Цены по типам цен выводятся как кросс-таблица (таблица с динамическими колонками) автоматически.
  2. Иерархия: Группировки и итоги по иерархии работают «из коробки» без ручного расчета уровней и отступов.
  3. Оформление: Условное оформление позволяет выделить цветом или шрифтом определенные данные (например, штрихкоды) без изменения программного кода.

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

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

← На главную