При работе с печатными формами в 1С часто возникает задача динамического управления видимостью колонок в зависимости от определенных условий. Например, мы хотим скрыть колонку с описанием или изображением для определенной организации. Однако, простое удаление или скрытие колонки в макете может привести к нежелательному смещению соседних колонок и некорректному отображению данных. Давайте разберем эту проблему подробно и рассмотрим различные подходы к ее решению.
Основная сложность заключается в том, что табличный документ 1С формируется на основе макета, и логика заполнения данных может быть реализована как через именованные параметры областей, так и через прямую адресацию ячеек по индексам (номер строки, номер колонки). Если код жестко обращается к ячейкам по их порядковым номерам, то любое изменение структуры макета (удаление или скрытие колонки) приведет к тому, что данные будут записываться не в те колонки, для которых они предназначены, вызывая "смещение".
Один из самых прямолинейных и часто используемых подходов — это создание нескольких макетов печатной формы. Мы создаем один макет, содержащий все необходимые колонки (например, "Описание" и "Изображение"), и второй макет, из которого эти колонки уже удалены. В зависимости от условия, мы просто выбираем нужный макет для формирования печатной формы.
Рассмотрим пример кода:
Функция Печать()
// ... получение ссылки на объект ...
Перем Макет;
Если СсылкаНаОбъект.Организация.Код = "00001" Тогда
// Для организации "00001" используем макет без колонок Описание и Изображение
Макет = ПолучитьМакет("СчетЗаказБезОписания");
Иначе
// Для других организаций используем стандартный макет
Макет = ПолучитьМакет("СчетЗаказ");
КонецЕсли;
// Далее, используем выбранный Макет для формирования табличного документа
// ...
КонецФункции
Область.Параметры.ТекстОписания = "Мое описание";), а путем обращения к ячейкам по их индексам, например, ТабличныйДокумент.Область("R2C3").Текст = "Мое описание";. В таком случае, удаление колонки в макете меняет индексы последующих колонок, а код продолжает записывать данные по старым индексам, но уже в другие ячейки.Что делать, если при использовании двух макетов происходит смещение:
ОбластьДетальныхСтрок.Параметры.Наименование = "Мой товар";), а не прямые обращения к ячейкам по индексам.Более гибкий подход, который позволяет избежать дублирования макетов, заключается в разделении основной области на вертикальные подобласти (то есть, колонки). Мы будем присоединять только те вертикальные области, которые нам нужны, в зависимости от условия.
Рассмотрим пример того, как мы могли бы это реализовать для строки товаров:
Функция Печать()
ТабДок = Новый ТабличныйДокумент;
ТабДок.ИмяПараметровПечати = "ПАРАМЕТРЫ_ПЕЧАТИ_Документ";
Макет = ПолучитьМакет("МойМакет");
ОбластьЗаголовок = Макет.ПолучитьОбласть("Заголовок");
// ... заполнение параметров заголовка ...
ТабДок.Вывести(ОбластьЗаголовок);
// Получаем области для каждой колонки
ОбластьОписание = Макет.ПолучитьОбласть("КолонкаОписание");
ОбластьИзображение = Макет.ПолучитьОбласть("КолонкаИзображение");
ОбластьРазмер = Макет.ПолучитьОбласть("КолонкаРазмер");
ОбластьКоличество = Макет.ПолучитьОбласть("КолонкаКоличество");
// Создаем строку для заголовков колонок
СтрокаЗаголовков = ТабДок.Область("R1C1:R1C" + ОбластьРазмер.КоличествоКолонок()); // Пример
// Определяем, нужно ли выводить описание и изображение
НужноВыводитьОписаниеИИзображение = (СсылкаНаОбъект.Организация.Код <> "00001");
Для Каждого СтрокаТЧ Из СсылкаНаОбъект.ТабличнаяЧасть Цикл
НоваяСтрокаДокумента = ТабДок.Область("R" + (ТабДок.ВысотаТаблицы + 1) + "C1");
// Если нужно выводить описание и изображение
Если НужноВыводитьОписаниеИИзображение Тогда
ОбластьОписание.Параметры.Описание = СтрокаТЧ.Описание;
ОбластьИзображение.Параметры.Изображение = СтрокаТЧ.Изображение;
ТабДок.Присоединить(ОбластьОписание);
ТабДок.Присоединить(ОбластьИзображение);
Иначе
// Если колонки Описание и Изображение не выводим,
// можно присоединить пустую область, если это необходимо для форматирования,
// или просто пропустить эти колонки
// Например, можно создать пустую вертикальную область в макете
// и присоединять ее при необходимости, если без нее что-то "съезжает"
// ОбластьПустая = Макет.ПолучитьОбласть("ПустаяКолонка");
// ТабДок.Присоединить(ОбластьПустая);
// ТабДок.Присоединить(ОбластьПустая); // Дважды, если скрыли две колонки
КонецЕсли;
ОбластьРазмер.Параметры.Размер = СтрокаТЧ.Размер;
ОбластьКоличество.Параметры.Количество = СтрокаТЧ.Количество;
ТабДок.Присоединить(ОбластьРазмер);
ТабДок.Присоединить(ОбластьКоличество);
ТабДок.Вывести(НоваяСтрокаДокумента); // Или просто ТабДок.Вывести() если присоединяли по одной
КонецЦикла;
Возврат ТабДок;
КонецФункции
Обратите внимание: Для корректной работы с вертикальными областями, вероятно, потребуется использовать метод ТабличныйДокумент.Присоединить(Область, ИмяОбласти) для каждой ячейки или группы ячеек в строке, чтобы точно контролировать их расположение. Возможно, придется перепроектировать макет таким образом, чтобы каждая "колонка" была отдельной вертикальной областью, а строки формировались путем вывода этих областей. Это требует более глубокого понимания работы с макетами и тщательной проработки.
Для областей табличного документа существует свойство Видимость. Мы можем установить его в Ложь, чтобы визуально скрыть область.
Видимость.Пример кода:
ОбластьКолонкиОписание = Макет.ПолучитьОбласть("R1C3:R" + Макет.ВысотаТаблицы() + "C3"); // Пример для 3-ей колонки
ОбластьКолонкиОписание.Видимость = Ложь;
Видимость = Ложь лишь скрывает содержимое, но физически область остается частью табличного документа. Если код заполняет ячейки по индексам, смещение все равно произойдет. Эта область будет "пустым местом", а следующие за ней колонки не сдвинутся влево.Мы можем попытаться установить ширину нежелательной колонки в 0, чтобы она не отображалась.
Пример кода:
ТабличныйДокумент.ШиринаКолонки(НомерКолонкиОписание) = 0;
ТабличныйДокумент.ШиринаКолонки(НомерКолонкиИзображение) = 0;
Видимость, этот метод может лишь визуально скрыть колонку, но если данные заполняются по индексам, смещение останется, и данные будут записываться в ту же "невидимую" колонку.Если после всех попыток колонки все равно смещаются, нам критически важно проанализировать код, отвечающий за заполнение табличного документа. Это является наиболее частой причиной проблем, когда изменение макета не дает ожидаемого эффекта.
Область.Ячейки.Получить(Строка, Колонка) или ТабличныйДокумент.Область("R2C1").[ИмяПараметра], а в коде мы присваиваем этому параметру значение: Область.Параметры.ИмяПараметра = Значение;.ТабличныйДокумент.Вывести(Область), то это обычно работает корректно, так как система сама распознает параметры в области. Но если мы формируем строки "по частям" с помощью ТабличныйДокумент.Присоединить(Область), то нужно следить за порядком присоединения и убедиться, что присоединяются только нужные области.Для сложных отчетов с высокой степенью динамичности состава колонок наиболее современным и гибким подходом является использование Системы Компоновки Данных (СКД).
Если печатная форма представляет собой по сути отчет с табличными данными, и требования к динамическому составу колонок достаточно сложны, мы настоятельно рекомендуем рассмотреть переход на СКД.
Для эффективного решения проблемы динамического скрытия колонок в печатных формах 1С без смещения, мы должны глубоко понимать механизмы формирования табличного документа. Всегда начинаем с анализа кода, который заполняет табличный документ, чтобы убедиться, что он использует именованные параметры, а не жестко закодированные индексы ячеек. В зависимости от сложности задачи и частоты изменений, выбираем наиболее подходящий подход: от создания двух макетов для простых случаев до использования вертикальных областей или Системы Компоновки Данных для более сложных и гибких отчетов. Помним, что чисто визуальное скрытие или обнуление ширины колонок не решит проблему, если данные продолжают записываться в "невидимые" места.