При разработке печатных форм в 1С часто возникает задача вывода иерархических данных или таблиц со сложной структурой. Типичный пример — отчет, в котором одному товару соответствует несколько заказов. В таком случае требуется, чтобы информация о товаре (наименование, артикул, штрихкод) выводилась в одной большой объединенной ячейке, а справа от нее располагалось несколько строк с данными по конкретным заказам. Разберем подробно, как реализовать такой механизм в различных версиях платформы 1С.
Независимо от версии платформы, логика построения такой таблицы строится на выполнении последовательных шагов. Проанализируем стандартную последовательность действий, которую должен выполнить программист:
В версии 7.7 работа с таблицами имеет свои особенности. Здесь нет полноценных объектов ТабличныйДокумент в том понимании, как в 8.x, работа ведется через объект типа Таблица. Посмотрим, как это выглядит в коде. Предположим, что Таб — это наш объект печатной формы.
Для начала рассмотрим, как вычислить границы. Метод ВысотаТаблицы() позволяет нам узнать, сколько строк уже выведено. Проанализируем пример кода:
// Перед циклом по товарам
ВыборкаТоваров.ВыбратьСтроки();
Пока ВыборкаТоваров.ПолучитьСтроку() = 1 Цикл
// Запоминаем первую строку для текущего товара
НомерНачала = Таб.ВысотаТаблицы() + 1;
// Выводим заказы товара
ВыборкаЗаказов = СоздатьОбъект("ТаблицаЗначений"); // Допустим, заказы там
// ... заполнение и обход заказов ...
ПервыйЗаказ = 1;
ВыборкаЗаказов.ВыбратьСтроки();
Пока ВыборкаЗаказов.ПолучитьСтроку() = 1 Цикл
// Выводим секцию строки заказа.
// В секции "Заказ" в колонках товара должны быть пустые ячейки с границами
Таб.ВывестиСекцию("Заказ");
Если ПервыйЗаказ = 1 Тогда
// Заполняем данные товара только в первую строку (необязательно, если будем объединять)
// Но лучше заполнить, чтобы после объединения текст сохранился
ПервыйЗаказ = 0;
КонецЕсли;
КонецЦикла;
НомерКонца = Таб.ВысотаТаблицы();
// Если строк больше одной, выполняем объединение
Если НомерКонца > НомерНачала Тогда
// Синтаксис: Область(R1, C1, R2, C2)
// Объединяем колонку 1 (Товар)
Таб.Область(НомерНачала, 1, НомерКонца, 1).Объединить(1);
// Объединяем колонку 2 (Артикул)
Таб.Область(НомерНачала, 2, НомерКонца, 2).Объединить(1);
// Устанавливаем выравнивание по центру (3 - по центру)
Таб.Область(НомерНачала, 1, НомерКонца, 2).ВертикальноеВыравнивание(3);
КонецЕсли;
КонецЦикла;
Важный момент: метод Объединить(1) в 7.7 требует передачи единицы в качестве параметра для фактического слияния ячеек. Если этого не сделать, объединение может не произойти.
В современных версиях 1С (8.3 и выше) работа с табличным документом более гибкая, но принцип остается прежним. Рассмотрим пример, где мы используем метод Объединить() объекта ОбластьЯчеекТабличногоДокумента. Выясним причину, по которой это удобнее делать программно после вывода.
Посмотрим на пример реализации в управляемых формах:
// ТабДок - ТабличныйДокумент
// Макет - полученный макет обработки/отчета
Для Каждого СтрокаТовар Из СписокТоваров Цикл
НачалоОбъединения = ТабДок.ВысотаТаблицы + 1;
Для Каждого СтрокаЗаказ Из СтрокаТовар.Заказы Цикл
ОбластьМакета = Макет.ПолучитьОбласть("СтрокаЗаказа");
// Заполняем параметры заказа
ОбластьМакета.Параметры.Заполнить(СтрокаЗаказ);
// Если это первая строка, заполним и параметры товара
Если ТабДок.ВысотаТаблицы + 1 = НачалоОбъединения Тогда
ОбластьМакета.Параметры.Товар = СтрокаТовар.Наименование;
ОбластьМакета.Параметры.Артикул = СтрокаТовар.Артикул;
КонецЕсли;
ТабДок.Вывести(ОбластьМакета);
КонецЦикла;
КонецОбъединения = ТабДок.ВысотаТаблицы;
Если КонецОбъединения > НачалоОбъединения Тогда
// Создаем область для объединения: Область(стрНач, колНач, стрКон, колКон)
// Предположим, Товар в 1-й колонке, Артикул во 2-й
ОбластьТовар = ТабДок.Область(НачалоОбъединения, 1, КонецОбъединения, 1);
ОбластьАртикул = ТабДок.Область(НачалоОбъединения, 2, КонецОбъединения, 2);
ОбластьТовар.Объединить();
ОбластьАртикул.Объединить();
// Установка визуальных свойств
ОбластьТовар.ВертикальноеПоложение = ВертикальноеПоложение.Центр;
ОбластьАртикул.ВертикальноеПоложение = ВертикальноеПоложение.Центр;
КонецЕсли;
КонецЦикла;
Часто в таких таблицах требуется выводить штрихкод товара. Если мы объединили ячейки товара по вертикали, штрихкод должен располагаться красиво по центру всей этой большой области. Проанализируем, как этого добиться в 1С 8.x.
Для этого используется коллекция Рисунки табличного документа. Основная сложность — правильно позиционировать картинку. Мы можем использовать метод Расположить(), передав в него нашу объединенную область.
// Создаем рисунок (штрихкод)
НовыйРисунок = ТабДок.Рисунки.Добавить(ТипРисункаТабличногоДокумента.Картинка);
НовыйРисунок.Картинка = ПолучитьКартинкуШтрихкода(СтрокаТовар.Штрихкод); // Ваша функция генерации
НовыйРисунок.РазмерКартинки = РазмерКартинки.Пропорционально;
// Определяем область, в которой нужно разместить картинку
// Это та самая многострочная область, которую мы получили после объединения
ОбластьДляШтрихкода = ТабДок.Область(НачалоОбъединения, 3, КонецОбъединения, 3);
НовыйРисунок.Расположить(ОбластьДляШтрихкода);
Такой подход гарантирует, что штрихкод будет отцентрирован относительно всех строк заказов справа. Обратите внимание, что если вы используете компоненту для печати штрихкодов, которая вставляется как объект ActiveX, логика позиционирования остается аналогичной.
Разберем несколько тонкостей, которые помогут избежать ошибок при формировании сложных печатных форм:
АвтовысотаСтроки не всегда корректно работает для объединенных по вертикали ячеек. Если название товара очень длинное, платформа может не растянуть объединенную ячейку автоматически. Рекомендуется либо ограничивать длину выводимого текста, либо заранее рассчитывать требуемую высоту строк.Обвести(), убедитесь, что вы применяете это к итоговой объединенной области, чтобы рамка вокруг товара была сплошной и красивой.Область() и Объединить() может замедлить формирование формы. В таких случаях старайтесь объединять ячейки только тогда, когда это действительно необходимо (если строк заказов больше одной).ТабДок.ФиксацияСлева. Это позволит пользователю прокручивать длинный список заказов вправо, при этом название товара всегда будет оставаться видимым.Таким образом, мы рассмотрели универсальный подход к созданию сложных печатных форм. Комбинируя методы определения границ выведенных данных и инструменты управления областями, можно реализовать практически любую структуру документа, требуемую бизнес-задачей.