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