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

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

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

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

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

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

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

Проанализируем влияние контекста: сервер и клиент

Одной из самых коварных причин некорректной работы табличного документа является передача объекта между клиентом и сервером. Посмотрим на предупреждение в Синтаксис-помощнике: "Табличные документы, которые выводятся при помощи данного метода, не рекомендуется передавать между клиентом и сервером и обратно".

Почему это важно? Когда мы вызываем методы Вывести() или Присоединить(), объект ТабличныйДокумент хранит внутреннее состояние — тот самый "указатель вывода". При сериализации документа (передаче с сервера на клиент) это состояние может быть сброшено или интерпретировано некорректно. Рассмотрим пример ситуации:


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

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

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

Часто программисты пытаются присоединить один ТабличныйДокумент к другому напрямую. Проанализируем типичный код, вызывающий проблемы:


ТабличныйДокумент.Вывести(ТД1); // ТД1 создан программно
ТабличныйДокумент.Присоединить(ТД2); // ТД2 создан программно

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

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

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

Чтобы избежать "глюков" при позиционировании, следует придерживаться архитектуры, где Присоединить() применяется только к финальному (главному) документу. Посмотрим на правильный пример реализации:


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

// Выводим первую часть (левую колонку)
ОбластьЛево = Макет.ПолучитьОбласть("Строка|КолонкаЛево");
ОбластьЛево.Параметры.Значение = "Данные 1";
Результат.Вывести(ОбластьЛево);

// В цикле присоединяем данные справа
Для Сч = 1 По 10 Цикл
    ОбластьПраво = Макет.ПолучитьОбласть("Строка|КолонкаПраво");
    ОбластьПраво.Параметры.Значение = "Данные " + Сч;
    Результат.Присоединить(ОбластьПраво);
КонецЦикла;

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

Итоги и рекомендации

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

  1. Избегайте передачи недостроенного документа между контекстами. Формируйте всё на сервере "за один заход".
  2. Проверяйте чистоту присоединяемых объектов. Если вы создаете ТабличныйДокумент программно, убедитесь, что в нем нет лишних пустых строк ниже первой. Используйте ТД2.ПолучитьОбласть(1, 1, 1, ТД2.ШиринаТаблицы), чтобы взять только одну конкретную строку.
  3. Следите за параметрами. При использовании ПолучитьОбласть() без параметров данные из ячеек могут не перенестись. Всегда заполняйте параметры непосредственно перед выводом в результирующий документ.
  4. Используйте единый макет. Проблемы с шириной колонок и позиционированием чаще всего возникают, когда данные собираются из разных объектов ТабличныйДокумент. Старайтесь использовать области одного макета внутри одного цикла формирования.

Соблюдение этих правил позволит вам создавать сложные отчеты с динамическим количеством колонок, избегая досадных ошибок верстки и "разъезжающихся" строк.

← На главную