Как программно удалить столбец в отчете 1С с разным форматом строк, включая отчеты СКД?

Программист 1С v8.3 (Обычные формы) 1С:Управление торговлей
← На главную

При работе с отчетами в 1С, особенно теми, что формируются Системой Компоновки Данных (СКД), часто возникает задача программного изменения структуры выведенного табличного документа. Одной из таких задач является удаление лишнего столбца. Ситуация усложняется, когда отчет содержит строки с разным форматированием или когда столбец присутствует на разных уровнях группировок СКД. В этой статье мы подробно рассмотрим различные подходы к решению этой проблемы, начиная от пост-обработки уже сформированного табличного документа и заканчивая изменением настроек самой СКД.

Пост-обработка табличного документа: программное удаление области

Если нам необходимо удалить столбец из уже сформированного табличного документа, мы можем воспользоваться методом УдалитьОбласть() объекта ТабличныйДокумент. Этот метод позволяет удалить произвольную область документа, сдвигая при этом остальные ячейки.

Разберем по шагам, как это сделать:

  1. Получение объекта ТабличныйДокумент: Прежде всего, нам нужен сам табличный документ, который мы хотим изменить. Чаще всего он получается после формирования отчета. Предположим, что наш отчет возвращает результат в переменную ДокументРезультат, которая является объектом типа ТабличныйДокумент.
  2. Определение удаляемой области: Для удаления столбца нам необходимо указать область, которую нужно удалить. Область определяется с помощью координат: начальная строка, начальная колонка, конечная строка, конечная колонка. Важно учитывать, что счет строк и колонок начинается с 1.
  3. Выбор типа смещения: Метод УдалитьОбласть() принимает вторым параметром тип смещения. Для удаления столбца нам нужен ТипСмещенияТабличногоДокумента.ПоГоризонтали. Это означает, что ячейки, расположенные справа от удаляемой области, будут сдвинуты влево, заполняя пустое пространство. Если же выбрать ТипСмещенияТабличногоДокумента.ПоВертикали, то будут сдвигаться строки снизу, что приведет к удалению строк, а не колонок.

Пример кода для программного удаления столбца

Изначально, автор темы попытался удалить область из макета, что не является корректным, если документ уже сформирован. Важно удалять область именно из объекта ТабличныйДокумент, а не из его макета:


// Предположим, что ДокументРезультат - это уже сформированный ТабличныйДокумент
// ДокументРезультат = Новый ТабличныйДокумент;
// ... код формирования отчета, который заполняет ДокументРезультат ...

// Определяем область для удаления.
// Например, второй столбец от 4-й строки до конца таблицы.
// Здесь 'Кол' - это номер колонки, которую нужно удалить.
// Определить 'Кол' можно по заголовку или по фиксированному положению.
// Допустим, нам нужно удалить вторую колонку (пустой столбец между Номенклатурой и Т1).
// Если известна начальная строка, например, СтрокаНоменклатуры,
// и номер колонки, например, 2.

Перем СтрокаНоменклатуры, Кол; // Эти переменные нужно определить в вашем коде
// Пример определения:
// СтрокаНоменклатуры = 4; // Или найти программно, например, по тексту "Номенклатура"
// Кол = 2; // Колонка, которую нужно удалить

ОбластьКолонки = ДокументРезультат.Область(СтрокаНоменклатуры, Кол, ДокументРезультат.ВысотаТаблицы, Кол);

// Удаляем область со смещением по горизонтали
ДокументРезультат.УдалитьОбласть(ОбластьКолонки, ТипСмещенияТабличногоДокумента.ПоГоризонтали);

ДокументРезультат.Показать();

В этом примере ДокументРезультат.Область(НачальнаяСтрока, НачальнаяКолонка, КонечнаяСтрока, КонечнаяКолонка) создает объект ОбластьТабличногоДокумента, представляющий собой наш столбец. Затем ДокументРезультат.УдалитьОбласть() фактически выполняет операцию удаления.

Сложности при разных форматах строк

Проблема, упомянутая автором темы, заключается в том, что "табличный документ имеет разный формат". Это часто происходит в отчетах СКД, где разные группировки или объединения ячеек могут создавать отдельные форматы строк для разных частей документа. Если в документе присутствуют строки с разной шириной колонок (т.е. они относятся к разным форматам строк), то простое удаление одной и той же области по координатам может привести к нежелательным результатам:

Причиной этого является то, что 1С хранит информацию о ширине колонок для каждого формата строк. Если удаляемая колонка охватывает области с разными форматами, система может не применить смещение корректно для всех форматов.

Предпочтительный подход для отчетов СКД: исключение столбца на уровне настроек

Для отчетов, построенных с использованием Системы Компоновки Данных (СКД), наиболее корректным и надежным способом является исключение ненужного столбца на этапе формирования отчета, а не пост-обработкой. Это позволяет СКД самостоятельно перестроить макет, учитывая отсутствие поля, и избежать проблем с разными форматами строк.

Как правило, СКД формирует отчет, основываясь на настройках, которые включают в себя "Выбранные поля", "Группировки", "Отборы" и т.д. Если столбец выводится как часть горизонтальной группировки, простое удаление его из "Выбранных полей" может быть недостаточным, так как группировка все равно будет стремиться вывести данные. Решение заключается в том, чтобы отключить использование самого поля в рамках этой группировки.

Рассмотрим, как это сделать программно:

  1. Получение настроек СКД: Сначала нам необходимо получить доступ к объекту настроек компоновки данных. Это обычно делается через КомпоновщикНастроек отчета, хотя программное создание СКД может быть значительно упрощено при помощи специальных модулей.
  2. Обход группировок: СКД использует структуру группировок для вывода данных. Если столбец является частью горизонтальной группировки, нам нужно найти эту группировку.
  3. Отключение использования поля: Как только мы найдем нужную группировку, мы можем установить свойство Использовать для поля в этой группировке в значение Ложь. Это укажет СКД, что данное поле не должно выводиться.

Пример кода для исключения столбца из СКД

Предположим, что ненужный столбец выводится как часть горизонтальной группировки с именем "Заказ". Мы можем программно обойти все группировки и отключить это поле:


// Предположим, что ОтчетОбъект - это объект вашего отчета (например, Отчет.МойОтчет)
// и у него есть КомпоновщикНастроек.

Если ОтчетОбъект.КомпоновщикНастроек.Настройки.Группировки.Количество() > 0 Тогда
    Для Каждого Группировка Из ОтчетОбъект.КомпоновщикНастроек.Настройки.Группировки Цикл
        // Проверяем, является ли текущая группировка горизонтальной
        Если Группировка.ТипГруппировки = ТипГруппировкиКомпоновщикаДанных.Горизонтальная Тогда
            // Если у группировки есть элементы (поля), то ищем нужный
            Если Группировка.Выбор.Элементы.Количество() > 0 Тогда
                Для Каждого ЭлементВыбора Из Группировка.Выбор.Элементы Цикл
                    // Ищем элемент, соответствующий полю, которое мы хотим удалить.
                    // Например, если имя поля в СКД - "ПолеДляУдаления".
                    Если ЭлементВыбора.Вид = ВидЭлементаВыбораКомпоновщикаДанных.Поле И ЭлементВыбора.Поле.Имя = "Заказ" Тогда
                        ЭлементВыбора.Использовать = Ложь;
                        // Можно добавить Break, если уверены, что поле уникально и нужно удалить только первое найденное
                    КонецЕсли;
                КонецЦикла;
            КонецЕсли;
        КонецЕсли;
        // Если есть вложенные группировки, нужно будет пройтись и по ним рекурсивно
        // Или найти нужную группировку по имени/другим свойствам, если известно
    КонецЦикла;
КонецЕсли;

// После изменения настроек необходимо заново сформировать отчет,
// чтобы изменения вступили в силу.
// Например:
// ОтчетОбъект.СкомпоноватьРезультат(ДокументРезультат);
// ДокументРезультат.Показать();

Важно: Название поля "Заказ" в примере выше является условным. Вам необходимо будет заменить его на реальное имя поля, которое вы хотите исключить из отчета. Это имя можно найти в конфигураторе.

Этот метод является наиболее мощным для отчетов СКД, так как позволяет СКД полностью перестроить внутреннюю структуру и макет, не выводя ненужный столбец. Это исключает проблемы с разными форматами строк и объединенными ячейками, так как СКД изначально строит документ без этого элемента.

Временное решение: скрытие столбца изменением ширины

В некоторых случаях, когда истинное удаление столбца является слишком сложным или приводит к непредсказуемым результатам из-за сложной структуры отчета с множеством форматов строк и объединенных ячеек, можно прибегнуть к компромиссному решению – скрытию столбца путем установки его ширины в минимальное значение.

Хотя это не является физическим удалением столбца, для пользователя он станет невидимым. Это может быть полезно, если:

Пример кода для скрытия столбца

Для скрытия столбца нам также понадобится объект ТабличныйДокумент и информация о номере колонки. Мы можем установить ширину колонки для всех строк, начиная с определенной, в очень маленькое значение, например, 0.1:


// Предположим, что ДокументРезультат - это уже сформированный ТабличныйДокумент
// Предположим, что СтрокаНоменклатуры и Кол уже определены.
// Например:
// СтрокаНоменклатуры = 4;
// Кол = 2; // Номер колонки, которую нужно скрыть

// Получаем область, соответствующую всей колонке от нужной строки до конца
ОбластьКолонкиДляСкрытия = ДокументРезультат.Область(СтрокаНоменклатуры, Кол, ДокументРезультат.ВысотаТаблицы, Кол);

// Устанавливаем ширину колонки
ОбластьКолонкиДляСкрытия.ШиринаКолонки = 0.1;

ДокументРезультат.Показать();

Этот подход менее "чистый", чем истинное удаление или исключение из СКД, но может служить быстрым и простым решением в некоторых сценариях.

Общие рекомендации и нюансы

  1. Отладка – ваш лучший друг: При работе со сложными отчетами и программным изменением табличных документов, всегда используйте отладчик. Пошаговое выполнение кода, проверка границ областей (Верх, Низ, Лево, Право), содержимого ячеек и свойств объекта ТабличныйДокумент поможет вам понять, что происходит на каждом этапе и выявить причину некорректной работы.
  2. Различие между ТабличныйДокумент и ТаблицаЗначений: Важно помнить, что ТабличныйДокумент – это объект для отображения и печати данных, имеющий визуальную структуру. ТаблицаЗначений – это структура данных в памяти, не имеющая непосредственной визуальной формы. Методы УдалитьКолонки() или Удалить() для ТаблицаЗначений.Колонки относятся именно к данным, а не к визуальному представлению.
  3. Сложности с вложенными группировками СКД: Если ваш отчет СКД содержит многоуровневые или вложенные группировки, поиск нужной группировки для отключения поля может потребовать более сложного обхода структуры настроек СКД. Возможно, придется использовать рекурсивные функции для глубокого поиска.
  4. Макеты СКД: В некоторых случаях, если вам нужна жестко фиксированная структура отчета и вы не планируете давать пользователю возможность изменять поля, можно создать собственный макет СКД. Это позволяет полностью контролировать вывод каждой ячейки, но требует значительных усилий при разработке и сопровождении. Автор темы упоминал, что создание собственного макета СКД вызывало у него сложности (вывод "лишних колонок с цифрами в заголовках"), что подтверждает, что это не всегда простой путь.

Выбирая метод удаления столбца, всегда начинайте с наиболее высокоуровневого и предпочтительного для вашего случая: для отчетов СКД это изменение настроек компоновки данных. Если это невозможно или слишком сложно, переходите к пост-обработке табличного документа методом УдалитьОбласть(). И только в крайнем случае, как временное или компромиссное решение, используйте скрытие столбца изменением его ширины.

← На главную