При разработке отчетов на базе системы компоновки данных (СКД) программисты часто сталкиваются с необходимостью зафиксировать одну или несколько колонок слева (например, колонку с наименованием сотрудника, номенклатуры или контрагента). Это позволяет комфортно анализировать большие таблицы с горизонтальной прокруткой. Однако, как только в одном отчете выводятся две и более таблицы или сложные разнородные группировки, стандартный механизм фиксации начинает вести себя непредсказуемо либо полностью перестает работать. Выясним, почему это происходит, проанализируем внутреннее поведение платформы 1С и разберем все возможные способы решения этой проблемы.
Для того чтобы понять природу проблемы, заглянем во внутренние механизмы платформы 1С:Предприятие. По умолчанию любой табличный документ (ТабличныйДокумент) имеет единую жесткую сетку колонок по всей своей высоте. Если вы меняете ширину первой колонки в первой строке, она автоматически меняется для всего документа.
Однако СКД умеет обходить это ограничение. Когда в отчете выводятся несколько таблиц друг под другом или присутствуют сложные группировки, СКД автоматически применяет механизмы, аналогичные методам СоздатьФорматСтрок() или СоздатьНовыйФорматСтрок(). Это позволяет разным строкам (или целым секциям) табличного документа иметь индивидуальную ширину колонок, никак не связанную со смежными областями.
Проблема кроется в том, как платформа обрабатывает свойство ФиксацияСлева. Когда мы указываем системе зафиксировать, например, две колонки (ФиксацияСлева = 2), платформа отсчитывает первые две колонки по их порядковому индексу в каждой строке:
Именно поэтому стандартная фиксация при разнородных группировках в СКД считается несовместимой с механизмом индивидуальных форматов строк.
Если ваш отчет имеет простую структуру (одна таблица без пересекающихся форматов строк), вы можете установить фиксацию программно. Для этого нам потребуется переопределить стандартный вывод отчета СКД. Сделаем это в модуле объекта отчета в предопределенной процедуре ПриКомпоновкеРезультата.
Рассмотрим по шагам, как выглядит данный шаблон кода:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
// Отключаем стандартный вывод, чтобы управлять процессом вывода самостоятельно
СтандартнаяОбработка = Ложь;
// Инициализируем схему и настройки
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, КомпоновщикНастроек.ПолучитьНастройки(), ДанныеРасшифровки);
// Запускаем процессор компоновки
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки, Истина);
// Выводим результат в табличный документ
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
// Устанавливаем фиксацию нужного количества колонок слева (например, 2 колонки)
ДокументРезультат.ФиксацияСлева = 2;
КонецПроцедуры
Важное примечание: данный код сработает корректно только в том случае, если свойство СтандартнаяОбработка установлено в значение Ложь. Если оставить его равным Истина, платформа повторно сгенерирует отчет поверх ваших изменений и сбросит установленную фиксацию.
Если в вашем отчете действительно выводятся разнородные данные (например, детальная таблица продаж по сотрудникам, а под ней — сводная таблица KPI с абсолютно другими колонками), стандартный код выше приведет к визуальным искажениям. Проанализируем 5 альтернативных вариантов решения этой проблемы.
Самый надежный способ подружить фиксацию и сложную структуру — полностью отказаться от разных форматов строк в макете СКД. Мы должны спроектировать отчет так, чтобы верхняя и нижняя таблицы использовали одну и ту же сетку вертикальных колонок.
Разберем алгоритм по шагам:
ПриКомпоновкеРезультата после вывода данных мы программно обходим строки нижней таблицы и объединяем нужные ячейки с помощью метода Область.Объединить().Поскольку формат строк остается единым для всего табличного документа, свойство ФиксацияСлева будет отрабатывать идеально по всей высоте отчета, не вызывая смещений и графических артефактов при прокрутке.
Если отчет разрабатывается под управляемые формы и предназначен в первую очередь для интерактивного анализа на экране, а не для печати, отличным решением будет отказ от использования классического поля табличного документа на форме.
Рассмотрим эту схему подробнее:
ТаблицаЗначений или ДеревоЗначений.ПроцессорВывода.Вывести(ПроцессорКомпоновки, Истина) (или выгружаем напрямую в коллекцию значений).Так как элемент формы «Таблица» работает по принципам классического списка базы данных, а не сложного печатного листа, фиксация выбранных колонок будет работать всегда стабильно и быстро, независимо от того, какие сложные данные или итоги выгружаются в другие строки.
Если по техническому заданию вам обязательно нужно выводить и большую сложную таблицу с сотрудниками, и блок итогов, но вы не хотите, чтобы при прокрутке они ломали друг друга, можно пойти по пути разделения интерфейса:
РезультатОсновной и РезультатИтоги).РезультатОсновной.ФиксацияСлева = 1. Во втором документе, где выводятся только компактные итоги, фиксировать ничего не потребуется, так как данные будут полностью помещаться на экране.Для создания эффекта «цельного» отчета разработчики часто размещают эти табличные документы вплотную друг к другу (убрав границы) или программно выводят итоги в компактные реквизиты формы, стилизованные под общую цветовую гамму отчета. Также для разделения результатов нескольких схем без конфликтов форматирования можно использовать пример вывода нескольких отчетов СКД на отдельные вкладки.
Если вы хотите предоставить пользователям возможность самостоятельно решать, какие именно колонки фиксировать при просмотре, можно задействовать штатный интерактивный механизм платформы 1С. Начиная с версии платформы 8.3.16, этот процесс стал максимально дружелюбным:
Иногда в процессе обсуждения на форумах всплывает идея «удалить индивидуальные форматы строк у табличного документа», чтобы вернуть его к единой сетке и зафиксировать колонки. Проанализируем, почему этот путь таит в себе подводные камни.
В платформе 1С не существует единого простого метода, который мог бы «сбросить» локальный формат строк определенной области до стандартного, сохранив при этом все оформление (цвета, шрифты, границы ячеек). Метод Область.Очистить(Ложь, Истина, Ложь) позволяет очистить форматирование самих ячеек, однако уникальная ширина колонок в строках все равно может остаться заблокированной.
Если вам действительно необходимо программно избавиться от индивидуальных форматов строк, единственным надежным способом является **копирование данных через буфер**. Вы можете создать новый (чистый) табличный документ и построчно скопировать в него значения и базовые свойства оформления ячеек из исходного документа СКД, избегая переноса свойств строк целиком. После такого переноса документ получит единую сетку колонок, и вы сможете без проблем применить к нему свойство ФиксацияСлева.
Выбор оптимального метода фиксации в СКД зависит от структуры вашего отчета и требований пользователей:
ПриКомпоновкеРезультата и свойство ФиксацияСлева.