Как загрузить данные из Excel в отчет СКД и сравнить их с данными информационной базы

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

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

Метод 1: Использование внешнего набора данных (Набор данных - объект)

Это наиболее «правильный» и гибкий способ с точки зрения архитектуры СКД. Вместо того чтобы пытаться внедрить таблицу значений внутрь текста запроса, мы создаем в схеме отдельный блок, который будет наполняться программно. Проанализируем пошагово процесс настройки такого отчета. Для упрощения программного конструирования схемы компоновки подойдёт модуль-обёртка для программного создания СКД.

Во-первых, в Схеме компоновки данных необходимо добавить новый набор данных с типом Набор данных - объект. В поле Имя объекта содержащего данные следует указать строковый идентификатор, например, ВнешниеДанныеExcel. Именно по этому имени СКД поймет, куда подставить вашу таблицу значений. После этого нужно вручную описать поля (колонки), которые будут приходить из файла: Номенклатура, Артикул, Количество и так далее. Крайне важно, чтобы имена полей в схеме в точности совпадали с именами колонок в создаваемой программно ТаблицеЗначений.

Во-вторых, разберем, как передать саму таблицу в СКД. Это делается в модуле объекта отчета в предопределенной процедуре ПриКомпоновкеРезультата. Рассмотрим пример кода:


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь; // Отключаем стандартный вывод
    
    // Получаем таблицу из Excel (реализацию функции чтения разберем ниже)
    ТаблицаИзФайла = ПолучитьТаблицуИзExcel();
    
    // Подготавливаем настройки
    СхемаКомпоновкиДанных = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
    Настройки = КомпоновщикНастроек.ПолучитьНастройки();
    
    // Связываем внешнюю таблицу с именем в схеме
    ВнешниеДанные = Новый Структура;
    ВнешниеДанные.Вставить("ВнешниеДанныеExcel", ТаблицаИзФайла);
    
    // Инициализируем макет и процессор компоновки
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);
    
    ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеДанные, ДанныеРасшифровки);
    
    // Выводим результат в табличный документ
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
    ПроцессорВывода.Вывести(ПроцессорКомпоновки);
    
КонецПроцедуры

Метод 2: Чтение Excel файла без установленного Microsoft Office

Выясним причину, по которой использование COM-объектов (Excel.Application) уходит в прошлое. Этот метод требует наличия установленного Excel на сервере, что невозможно в средах Linux или в облачных сервисах. Современный подход — использование объекта ТабличныйДокумент, который умеет нативно читать файлы .xlsx. Для готового чтения таблиц без COM-соединения можно использовать универсальную обработку загрузки файлов Excel и CSV в таблицу значений.

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


Функция ПолучитьТаблицуИзExcel(ПутьКФайлу)
    
    ТабДок = Новый ТабличныйДокумент;
    Попытка
        ТабДок.Прочитать(ПутьКФайлу);
    Исключение
        Сообщить("Не удалось прочитать файл: " + ОписаниеОшибки());
        Возврат Неопределено;
    КонецПопытки;
    
    // Определяем область данных (например, начиная со 2-й строки, где данные)
    Область = ТабДок.Область(2, 1, ТабДок.ВысотаТаблицы, ТабДок.ШиринаТаблицы);
    
    // Используем ПостроительЗапроса для быстрого преобразования области в таблицу
    Построитель = Новый ПостроительЗапроса;
    Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(Область);
    Построитель.Выполнить();
    ТЗ = Построитель.Результат.Выгрузить();
    
    // Важно: Построитель создает колонки с именами Колонки1, Колонки2...
    // Переименуем их и типизируем для корректной работы СКД
    ТЗ.Колонки[0].Имя = "Артикул";
    ТЗ.Колонки[1].Имя = "КоличествоФайл";
    
    Возврат ТЗ;
    
КонецФункции

Типизация данных и поиск соответствий

Проанализируем ситуацию: в Excel артикул — это строка, а в 1С номенклатура — это ссылка на справочник. Если просто передать строку в СКД, сравнение с данными базы может работать некорректно или медленно. Рекомендуется выполнять поиск ссылок еще на этапе формирования таблицы значений.

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

  1. Создаем пустую ТаблицуЗначений с четко заданными типами колонок через ОписаниеТипов.
  2. При чтении каждой строки из файла ищем ссылку в базе: Справочники.Номенклатура.НайтиПоАртикулу(ЗначениеИзФайла).
  3. Заполняем таблицу уже найденными ссылками. Если ссылка не найдена, можно оставить поле пустым для последующей фильтрации в отчете.

Объединение данных из файла и базы в СКД

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

Укажите Источник связи (Набор из запроса) и Приемник связи (Набор из файла). В качестве условий связи выберите общие поля, например, Номенклатура или Артикул. Это позволит вывести в одной строке отчета данные из 1С (остаток по бухгалтерии) и данные из файла (остаток по данным поставщика), что даст возможность легко вычислить разницу через Вычисляемые поля.

Важные нюансы работы на сервере

Помните, что процедура ПриКомпоновкеРезультата выполняется на сервере. Если пользователь выбирает файл на своем локальном компьютере, сервер 1С не увидит путь D:\MyFiles\report.xlsx. Для решения этой проблемы необходимо:

Соблюдение этой структуры позволит создать надежный отчет, который не зависит от версии Excel и корректно работает в любых вариантах развертывания 1С:Предприятия.

← На главную