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