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