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

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

При работе с файлами, например, Microsoft Excel, часто возникает задача загрузить данные в 1С, но не из всего файла целиком, а только с одного конкретного листа. Стандартный метод Прочитать() объекта ТабличныйДокумент загружает все листы файла. В этой статье мы подробно разберем, как после загрузки такого многостраничного документа извлечь из него нужный лист и сформировать на его основе совершенно новый, одностраничный табличный документ.

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

Решение 1: Использование метода ПолучитьОбласть() по имени листа

Это самый прямой и элегантный способ для решения нашей задачи. Разберемся в механике его работы. Когда платформа 1С читает файл Excel с помощью метода Прочитать(), она не просто загружает ячейки. Каждый лист исходного файла автоматически преобразуется в именованную область внутри объекта ТабличныйДокумент. Имя этой области в точности соответствует названию листа в Excel (например, "Лист1", "Sheet1", "Отчет по продажам" и т.д.).

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

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

Посмотрим на пример кода:

Представим, что у нас есть функция, которая должна прочитать файл и вернуть табличный документ, содержащий только первый лист.


&НаСервере
Функция ПолучитьПервыйЛистИзФайла(ИмяФайла)
    
    // 1. Создаем объект для чтения исходного файла
    ИсходныйДокумент = Новый ТабличныйДокумент;
    ИсходныйДокумент.Прочитать(ИмяФайла);
    
    // 2. Проверяем, есть ли в документе вообще области (листы)
    Если ИсходныйДокумент.Области.Количество() = 0 Тогда
        // Возвращаем пустой документ или вызываем исключение
        Возврат Новый ТабличныйДокумент;
    КонецЕсли;
    
    // 3. Получаем объект области первого листа по индексу 0
    ОбластьПервогоЛиста = ИсходныйДокумент.Области[0];
    
    // 4. Получаем имя этой области
    ИмяПервогоЛиста = ОбластьПервогоЛиста.Имя;
    
    // 5. Вызываем метод ПолучитьОбласть() с этим именем
    // Метод вернет НОВЫЙ табличный документ
    Результат = ИсходныйДокумент.ПолучитьОбласть(ИмяПервогоЛиста);
    
    Возврат Результат;
    
КонецФункции

Этот код можно сделать более лаконичным, объединив шаги 3, 4 и 5 в одну строку, как это в итоге и было сделано в обсуждаемой теме на форуме:


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

Преимущества этого подхода:

Решение 2: Создание нового документа и копирование в него области

Этот подход более "ручной" и многословный, но он дает больше гибкости. Например, если нам нужно не просто скопировать один лист, а собрать итоговый документ из нескольких областей разных листов. Существует два основных способа скопировать область в новый документ: через метод Вывести() и через ВставитьОбласть().

Вариант А: Использование метода Вывести()

Метод Вывести() предназначен для последовательного добавления областей в табличный документ, обычно одна под другой. Чтобы использовать его для копирования целого листа, нам нужно сначала получить область этого листа, а затем вывести ее в новый, пустой документ.

Рассмотрим по шагам:

  1. Создаем и читаем исходный табличный документ.
  2. Создаем пустой табличный документ, который будет нашим результатом.
  3. Получаем объект нужной нам области (листа) из исходного документа, например, по индексу.
  4. Используя свойства этой области (Верх, Низ, Лево, Право), получаем саму область ячеек через метод ПолучитьОбласть() с координатами.
  5. Вызываем у документа-результата метод Вывести() и передаем ему полученную область.

Пример кода:


&НаСервере
Функция ПолучитьЛистЧерезВывод(ИмяФайла)

    // 1. Читаем исходный файл
    ИсходныйДокумент = Новый ТабличныйДокумент;
    ИсходныйДокумент.Прочитать(ИмяФайла, СпособЧтенияЗначенийТабличногоДокумента.Значение);
    
    Если ИсходныйДокумент.Области.Количество() = 0 Тогда
        Возврат Новый ТабличныйДокумент;
    КонецЕсли;
    
    // 2. Получаем объект области первого листа
    ОбластьПервогоЛиста = ИсходныйДокумент.Области[0];
    
    // 3. Получаем область ячеек по координатам
    ОбластьДляВывода = ИсходныйДокумент.ПолучитьОбласть(
        ОбластьПервогоЛиста.Верх, 
        ОбластьПервогоЛиста.Лево, 
        ОбластьПервогоЛиста.Низ, 
        ОбластьПервогоЛиста.Право
    );
    
    // 4. Создаем новый пустой документ для результата
    ДокументРезультат = Новый ТабличныйДокумент;
    
    // 5. Выводим область в новый документ
    ДокументРезультат.Вывести(ОбластьДляВывода);
    
    Возврат ДокументРезультат;

КонецФункции

Важное замечание: Как показывает практика, метод Вывести() иногда может вести себя непредсказуемо при работе с большими и сложными областями, например, добавлять пустые строки или столбцы. Его основное предназначение — последовательный вывод макетов при формировании отчетов.

Вариант Б: Использование метода ВставитьОбласть()

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

Пример кода:


&НаСервере
Функция ПолучитьЛистЧерезВставку(ИмяФайла)

    // 1. Читаем исходный файл
    ИсходныйДокумент = Новый ТабличныйДокумент;
    ИсходныйДокумент.Прочитать(ИмяФайла);
    
    Если ИсходныйДокумент.Области.Количество() = 0 Тогда
        Возврат Новый ТабличныйДокумент;
    КонецЕсли;
    
    // 2. Получаем область первого листа
    ОбластьПервогоЛиста = ИсходныйДокумент.Области[0];
    
    // 3. Создаем новый пустой документ для результата
    ДокументРезультат = Новый ТабличныйДокумент;
    
    // 4. Определяем целевую область в новом документе (начиная с ячейки R1C1)
    ЦелеваяОбласть = ДокументРезультат.Область(1, 1);
    
    // 5. Вставляем область исходного листа в новый документ
    ДокументРезультат.ВставитьОбласть(ОбластьПервогоЛиста, ЦелеваяОбласть);
    
    Возврат ДокументРезультат;

КонецФункции

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

Рекомендации по стилю кода и важные замечания

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

← На главную