Как выгрузить номенклатуру с иерархией в Excel в 1С:Предприятие 8.3?

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

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

Причины ошибок при прямой выгрузке через COM-объект

Проанализируем типичные ошибки, возникающие при попытке заполнить ячейки Excel напрямую через Excel.Application:

  1. Передача ссылочного типа вместо строки или числа. Если поле запроса содержит ссылку (например, СправочникСсылка.ЕдиницыИзмерения), COM-объект Excel не может автоматически преобразовать внутренний объект 1С в поддерживаемый тип данных. В ячейку необходимо передавать строковое представление или примитивный тип.
  2. Вложенные таблицы в запросе. Использование выборки табличных частей (например, Номенклатура.ДополнительныеРеквизиты.(...)) возвращает в каждой строке вложенную таблицу значений, которую невозможно напрямую присвоить значению ячейки.
  3. Низкая скорость работы. Поэлементная запись в ячейки вида Лист.Cells(Строка, Колонка).Value = Значение при больших объемах данных занимает значительное время из-за постоянных межпроцессных вызовов между 1С и Microsoft Excel.

Вариант 1. Нативная выгрузка через ТабличныйДокумент с автогруппировкой (Рекомендуемый)

Наиболее быстрый и надежный способ — сформировать ТабличныйДокумент на стороне сервера и сохранить его в формате XLSX методом Записать(). Этот подход работает без установленного Microsoft Excel, платформенно независим (подходит для Linux-серверов) и в десятки раз быстрее прямого обращения к COM.

Разберем по шагам построение запроса с иерархией и сохранение документа:


&НаСервере
Процедура ВыгрузитьНоменклатуруВФайл(ПутьКФайлу)
    
    // 1. Формируем запрос с получением иерархии
    Запрос = Новый Запрос;
    Запрос.Текст = 
    "ВЫБРАТЬ
    |	Номенклатура.Ссылка КАК Ссылка,
    |	Номенклатура.ЭтоГруппа КАК ЭтоГруппа,
    |	Номенклатура.Код КАК Код,
    |	Номенклатура.Артикул КАК Артикул,
    |	Номенклатура.Наименование КАК Наименование,
    |	ПРЕДСТАВЛЕНИЕ(Номенклатура.ЕдиницаИзмерения) КАК ЕдиницаИзмерения,
    |	ПРЕДСТАВЛЕНИЕ(Номенклатура.ВидНоменклатуры) КАК ВидНоменклатуры
    |ИЗ
    |	Справочник.Номенклатура КАК Номенклатура
    |ИТОГИ ПО
    |	Ссылка ТОЛЬКО ИЕРАРХИЯ";
    
    РезультатЗапроса = Запрос.Выполнить();
    
    // 2. Создаем табличный документ и включаем автогруппировку
    ТабДок = Новый ТабличныйДокумент;
    ТабДок.НачатьАвтогруппировкуСтрок();
    
    // Заполняем шапку
    ТабДок.Область(1, 1).Текст = "Код";
    ТабДок.Область(1, 2).Текст = "Артикул";
    ТабДок.Область(1, 3).Текст = "Наименование";
    ТабДок.Область(1, 4).Текст = "Ед. изм.";
    ТабДок.Область(1, 5).Текст = "Вид номенклатуры";
    
    ТекущаяСтрока = 1;
    
    // 3. Обходим результат по иерархическим группировкам
    Выборка = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);
    ВывестиИерархиюВТабличныйДокумент(Выборка, ТабДок, ТекущаяСтрока);
    
    ТабДок.ЗакончитьАвтогруппировкуСтрок();
    
    // 4. Сохраняем в формат XLSX
    ТабДок.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.XLSX);
    
КонецПроцедуры

&НаСервере
Процедура ВывестиИерархиюВТабличныйДокумент(Выборка, ТабДок, ТекущаяСтрока)
    
    Пока Выборка.Следующий() Цикл
        ТекущаяСтрока = ТекущаяСтрока + 1;
        Уровень = Выборка.Уровень();
        
        ТабДок.Область(ТекущаяСтрока, 1).Текст = Выборка.Код;
        ТабДок.Область(ТекущаяСтрока, 2).Текст = Выборка.Артикул;
        ТабДок.Область(ТекущаяСтрока, 3).Текст = Выборка.Наименование;
        ТабДок.Область(ТекущаяСтрока, 4).Текст = Выборка.ЕдиницаИзмерения;
        ТабДок.Область(ТекущаяСтрока, 5).Текст = Выборка.ВидНоменклатуры;
        
        // Устанавливаем уровень группировки для строки
        ТабДок.УстановитьУровеньГруппировкиСтрок(ТекущаяСтрока, Уровень);
        
        // Рекурсивно выводим подчиненные элементы
        ВыборкаПодчиненные = Выборка.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);
        Если ВыборкаПодчиненные.Количество() > 0 Тогда
            ВывестиИерархиюВТабличныйДокумент(ВыборкаПодчиненные, ТабДок, ТекущаяСтрока);
        КонецЕсли;
    КонецЦикла;
    
КонецПроцедуры

Использование методов НачатьАвтогруппировкуСтрок() и ЗакончитьАвтогруппировкуСтрок() гарантирует, что при открытии полученного файла в Excel пользователю будет доступна стандартная структура сворачиваемых уровней.

Вариант 2. Корректная обработка типов при выгрузке через COM (Excel.Application)

Если специфика задачи требует обязательного использования прямого COM-соединения, необходимо скорректировать текст запроса и процесс заполнения ячеек:

  1. Для ссылочных полей в запросе используйте получение текстового наименования через точку (Номенклатура.ЕдиницаИзмерения.Наименование) или системную функцию ПРЕДСТАВЛЕНИЕ(Номенклатура.ЕдиницаИзмерения).
  2. Исключите выгрузку табличных частей через точку в основном запросе (выгружайте их отдельными запросами при необходимости).

Посмотрим на пример правильного формирования запроса для COM-выгрузки:


&НаСервере
Функция ПолучитьТаблицуДляВыгрузки()
    Запрос = Новый Запрос;
    Запрос.Текст = 
    "ВЫБРАТЬ
    |	Номенклатура.Код КАК Код,
    |	Номенклатура.Артикул КАК Артикул,
    |	Номенклатура.Наименование КАК Наименование,
    |	Номенклатура.ЕдиницаИзмерения.Наименование КАК ЕдиницаИзмерения,
    |	ПРЕДСТАВЛЕНИЕ(Номенклатура.ВидНоменклатуры) КАК ВидНоменклатуры
    |ИЗ
    |	Справочник.Номенклатура КАК Номенклатура
    |ГДЕ
    |	НЕ Номенклатура.ЭтоГруппа";
    
    Возврат Запрос.Выполнить().Выгрузить();
КонецФункции

После получения таблицы данных, где все колонки имеют простые типы (число, строка), перенос в COM-объект не вызовет исключений.

Вариант 3. Использование Системы компоновки данных (СКД)

Для создания гибких отчетов с выгрузкой иерархии можно использовать программный запуск схемы компоновки данных:

  1. Создается отчет на СКД, где в структуре группировок для поля Ссылка (или Номенклатура) указывается тип «Иерархия».
  2. Программно выполняется компоновка макета и вывод в ТабличныйДокумент с помощью ПроцессорКомпоновкиДанных и ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент.
  3. Полученный документ сохраняется методом ТабличныйДокумент.Записать() в файл XLSX. Этот вариант полностью исключает ручное написание кода рекурсивного обхода иерархических уровней.
← На главную