Почему метод Присоединить() в табличном документе 1С выводит данные вниз, а не справа?

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

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

Разберем основную причину: механизм работы «курсора»

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

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

Решение №1: Использование целевого документа и четких координат

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

Рассмотрим правильный алгоритм действий:

  1. Создаем новый пустой табличный документ (приемник).
  2. Получаем область из первого (левого) документа, четко указывая его границы.
  3. Выводим эту область в приемник методом Вывести().
  4. Получаем область из второго (правого) документа с четкими границами.
  5. Добавляем её в приемник методом Присоединить().

Посмотрим на пример кода, реализующий этот подход:


// Создаем результирующий документ
ТабДокРезультат = Новый ТабличныйДокумент;

// Получаем левую часть с четким указанием координат
// Параметры: Верх, Лево, Низ, Право
ОбластьЛево = ТабДокИсточник1.ПолучитьОбласть(1, 1, ТабДокИсточник1.ВысотаТаблицы, ТабДокИсточник1.ШиринаТаблицы);
ТабДокРезультат.Вывести(ОбластьЛево);

// Получаем правую часть, которую нужно приклеить справа
ОбластьПраво = ТабДокИсточник2.ПолучитьОббасть(1, 1, ТабДокИсточник2.ВысотаТаблицы, ТабДокИсточник2.ШиринаТаблицы);
ТабДокРезультат.Присоединить(ОбластьПраво);

В данном примере использование свойств ВысотаТаблицы и ШиринаТаблицы гарантирует, что мы берем только заполненный диапазон. Это исключает ситуацию, когда «невидимые» широкие границы области мешают корректному присоединению.

Решение №2: Контроль ширины колонок и сетки

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

Выясним причину такого поведения. Платформа 1С старается сохранить читаемость документа. Если Присоединить() приведет к тому, что суммарная ширина превысит параметры страницы, установленные в Автомасштаб или ШиринаСтраницы, может произойти принудительный разрыв. Чтобы этого избежать, перед выполнением операции рекомендуется проверить возможность размещения области:


Если ТабДокРезультат.ПроверитьПрисоединение(ОбластьПраво) Тогда
    ТабДокРезультат.Присоединить(ОбластьПраво);
Иначе
    Сообщить("Область слишком велика и не помещается по ширине!");
    // Здесь можно принять решение о выводе вниз или масштабировании
КонецЕсли;

Также важно помнить о свойстве СоздаватьКолонкиПриНеобходимости. Если оно установлено в значение Ложь, а в приемнике меньше колонок, чем требуется для присоединяемой области, результат будет непредсказуемым.

Особенности работы с результатами СКД

Проанализируем ситуацию, когда данные получены из Системы компоновки данных. СКД формирует документ «монолитно». Попытка вызвать Присоединить() к готовому результату СКД в 99% случаев приведет к выводу вниз, так как компоновщик уже закрыл все строки и установил финальную позицию курсора в самый низ документа.

Для решения этой задачи мы должны:

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

Важные замечания по форматированию

При использовании Присоединить() обратите внимание на следующие технические нюансы:

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

← На главную