Как сохранить группировки при разделении табличного документа 1С на отдельные листы

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При работе с большими отчетами или импортированными файлами Excel программисты часто сталкиваются с задачей разделения одного массивного табличного документа на несколько частей (листов). Однако стандартный подход с использованием метода ПолучитьОбласть() преподносит неприятный сюрприз: данные и оформление переносятся, а структура группировок (те самые «плюсики» слева) бесследно исчезает. Более того, если в исходном файле строки были свернуты, в новом документе они останутся скрытыми, но развернуть их пользователь уже не сможет, так как элементы управления группировками отсутствуют.

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

Почему пропадают группировки? Разбор ситуации

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

Когда мы вызываем НовыйТабДок = ТабличныйДокумент.ПолучитьОбласть(ИмяОбласти), система создает новый объект, заполняет его данными, но не переносит «карту» группировок из родительского документа. Установка свойства ОтображатьГруппировки = Истина лишь включает визуальный интерфейс для дерева групп, но если само дерево пустое (группы не определены), то и отображать нечего.

Способ №1: Программное восстановление группировок

Рассмотрим самый очевидный, но трудоемкий путь — построчный обход исходного документа и перенос уровней вложенности в новый документ. Для этого нам понадобятся методы УровеньГруппировкиСтрок() и НачатьГруппировкуСтрок().

Представим, что мы уже прочитали файл Excel и получили общий табличный документ. Теперь нам нужно извлечь из него область и восстановить в ней иерархию:


// Предположим, Источник - исходный ТабличныйДокумент, 
// а Результат - новый документ, куда мы копируем данные.

ОбластьИсточник = Источник.ПолучитьОбласть("Лист1");
Результат.Вывести(ОбластьИсточник);

// Теперь восстанавливаем группировки
Для НомерСтроки = 1 По ОбластьИсточник.ВысотаТаблицы Цикл
    Уровень = Источник.Область(ИмяОбласти).УровеньГруппировкиСтрок(НомерСтроки);
    Если Уровень > 0 Тогда
        // Здесь логика может быть сложнее, так как НачатьГруппировкуСтрок
        // обычно применяется к диапазону, но мы можем анализировать перепады уровней.
        // Важно: НачатьГруппировкуСтрок(Конец, Истина) создает группу.
    КонецЕсли;
КонецЦикла;

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

Способ №2: Метод «От обратного» (Клонирование и удаление)

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

  1. Создаем копию всего исходного табличного документа (через ЗначениеВСтрокуВнутр / ЗначениеИзСтрокиВнутр или простым присваиванием, если это допустимо).
  2. В каждой копии удаляем все строки, которые не входят в нужный нам «лист» или область.
  3. Используем метод УдалитьОбласть() с типом смещения ТипСмещенияТабличногоДокумента.ПоВертикали.

Посмотрим на пример реализации такого подхода:


// Функция для получения очищенного листа
Функция ПолучитьЛистСГруппировками(ИсходныйДокумент, ИмяОбласти)
    
    НовыйЛист = ИсходныйДокумент; // В реальном коде используйте копирование объекта
    ОбластьЛиста = ИсходныйДокумент.Области[ИмяОбласти];
    
    НачалоЛиста = ОбластьЛиста.Верх;
    КонецЛиста = ОбластьЛиста.Низ;
    ВсегоСтрок = ИсходныйДокумент.ВысотаТаблицы;
    
    // Удаляем хвост (строки после нужной области)
    Если ВсегоСтрок > КонецЛиста Тогда
        ОбластьУдаления = НовыйЛист.Область(КонецЛиста + 1, , ВсегоСтрок, );
        НовыйЛист.УдалитьОбласть(ОбластьУдаления, ТипСмещенияТабличногоДокумента.ПоВертикали);
    КонецЕсли;
    
    // Удаляем голову (строки до нужной области)
    Если НачалоЛиста > 1 Тогда
        ОбластьУдаления = НовыйЛист.Область(1, , НачалоЛиста - 1, );
        НовыйЛист.УдалитьОбласть(ОбластьУдаления, ТипСмещенияТабличногоДокумента.ПоВертикали);
    КонецЕсли;
    
    Возврат НовыйЛист;
КонецФункции

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

Особенности работы с Excel (XLSX)

Выясним причину, по которой группировки могут вести себя странно при чтении из Excel. Платформа 1С, начиная с версии 8.3.10, умеет читать файлы .xlsx напрямую, без установленного Microsoft Office. Однако стоит помнить следующее:

Настройка отображения на форме

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


НоваяТаблица.ОтображатьГруппировки = Истина;
НоваяТаблица.ОтображатьСетку = Ложь; // Часто улучшает производительность отрисовки
НоваяТаблица.ТолькоПросмотр = Истина;

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

Выводы и рекомендации

Подведем итоги нашего анализа. Метод ПолучитьОбласть() — это инструмент для копирования «сырых» данных, а не структуры документа. Если вам критически важно сохранить иерархию (группировки), используйте метод удаления лишнего из копии целого документа. Это сэкономит время разработки и обеспечит высокую скорость работы программы даже на очень больших объемах данных.

Разберем краткий чек-лист при работе с большими Excel-файлами:

  1. Используйте ТабличныйДокумент.Прочитать(ИмяФайла) для загрузки.
  2. Если нужны группировки — не используйте Вывести() или ВставитьОбласть() для создания новых листов с нуля.
  3. Проверьте свойство Видимость у строк после разделения, если данные кажутся «пропавшими».
  4. Для управления деревом программно (если решили идти по пути построчного восстановления) используйте ПоказатьУровеньГруппировокСтрок(), чтобы сразу раскрыть документ до нужного уровня.

Следуя этим правилам, вы сможете эффективно манипулировать табличными данными, сохраняя удобство работы для конечного пользователя.

← На главную