При работе с табличными документами в 1С программисты часто сталкиваются с ситуацией, когда метод Присоединить() ведет себя непредсказуемо. Вместо того чтобы добавить новую область справа от уже выведенных данных, система помещает её ниже, как если бы был вызван метод Вывести(). Это создает массу сложностей при формировании сложных отчетов, где требуется склейка нескольких таблиц по горизонтали. Рассмотрим подробнее, почему это происходит и как правильно организовать программный код для достижения нужного результата.
Для начала проанализируем внутреннюю логику платформы 1С. Каждый объект ТабличныйДокумент хранит состояние внутреннего курсора (текущей позиции вывода). Когда мы используем метод Вывести(), платформа добавляет область в документ и перемещает курсор на начало следующей строки, под только что выведенный блок. Метод Присоединить(), в свою очередь, предназначен для добавления области справа от последней выведенной области в той же самой строке.
Проблема часто заключается в том, что если строка уже была «закрыта» или если вы пытаетесь присоединить данные к документу, который был сформирован не последовательным выводом, а, например, получен как результат работы СКД, 1С не может определить «последнюю выведенную область». В этом случае система по умолчанию переходит на новую строку, и данные уходят вниз. Также критической ошибкой является попытка объекта «присоединить самого себя». Это вызывает конфликт обращения к памяти и некорректную работу алгоритмов позиционирования.
Как показывает практика и обсуждения экспертов, наиболее стабильный способ — это использование третьего, «чистого» табличного документа, в который мы будем поочередно собирать данные. При этом крайне важно не использовать метод ПолучитьОбласть() без параметров, так как он может захватывать лишние пустые колонки или строки, которые физически не видны, но присутствуют в структуре макета.
Рассмотрим правильный алгоритм действий:
Вывести().Присоединить().Посмотрим на пример кода, реализующий этот подход:
// Создаем результирующий документ
ТабДокРезультат = Новый ТабличныйДокумент;
// Получаем левую часть с четким указанием координат
// Параметры: Верх, Лево, Низ, Право
ОбластьЛево = ТабДокИсточник1.ПолучитьОбласть(1, 1, ТабДокИсточник1.ВысотаТаблицы, ТабДокИсточник1.ШиринаТаблицы);
ТабДокРезультат.Вывести(ОбластьЛево);
// Получаем правую часть, которую нужно приклеить справа
ОбластьПраво = ТабДокИсточник2.ПолучитьОббасть(1, 1, ТабДокИсточник2.ВысотаТаблицы, ТабДокИсточник2.ШиринаТаблицы);
ТабДокРезультат.Присоединить(ОбластьПраво);
В данном примере использование свойств ВысотаТаблицы и ШиринаТаблицы гарантирует, что мы берем только заполненный диапазон. Это исключает ситуацию, когда «невидимые» широкие границы области мешают корректному присоединению.
Вторая распространенная причина «вылета» области вниз — конфликт ширин колонок. Если в целевом документе уже сформирована определенная сетка, а присоединяемая область имеет свои настройки ширины, которые не помещаются в текущую видимую область печати или конфликтуют с существующими колонками, 1С может принять решение о переносе данных.
Выясним причину такого поведения. Платформа 1С старается сохранить читаемость документа. Если Присоединить() приведет к тому, что суммарная ширина превысит параметры страницы, установленные в Автомасштаб или ШиринаСтраницы, может произойти принудительный разрыв. Чтобы этого избежать, перед выполнением операции рекомендуется проверить возможность размещения области:
Если ТабДокРезультат.ПроверитьПрисоединение(ОбластьПраво) Тогда
ТабДокРезультат.Присоединить(ОбластьПраво);
Иначе
Сообщить("Область слишком велика и не помещается по ширине!");
// Здесь можно принять решение о выводе вниз или масштабировании
КонецЕсли;
Также важно помнить о свойстве СоздаватьКолонкиПриНеобходимости. Если оно установлено в значение Ложь, а в приемнике меньше колонок, чем требуется для присоединяемой области, результат будет непредсказуемым.
Проанализируем ситуацию, когда данные получены из Системы компоновки данных. СКД формирует документ «монолитно». Попытка вызвать Присоединить() к готовому результату СКД в 99% случаев приведет к выводу вниз, так как компоновщик уже закрыл все строки и установил финальную позицию курсора в самый низ документа.
Для решения этой задачи мы должны:
ПолучитьОбласть(), как было описано выше, для переноса фрагментов во второй (основной) документ.ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент, где в цикле обхода результата вызывать Присоединить() для каждого элемента строки.При использовании Присоединить() обратите внимание на следующие технические нюансы:
Присоединить(), но визуально может выглядеть как смещение.Подводя итог, можно сказать: секрет корректной работы Присоединить() заключается в строгой последовательности (сначала Вывести, потом Присоединить), использовании промежуточного документа и явном указании координат области через (1, 1, Высота, Ширина). Соблюдение этих правил позволит вам создавать отчеты любой сложности с идеальным позиционированием данных.