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