Как загрузить данные из Excel в таблицу значений и почему запрос к ней может быть пустым?

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

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

Анализ основной ошибки: работа с пустой таблицей

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

Если в таблице-источнике ноль строк, то и результат запроса всегда будет содержать ноль строк. Прежде чем обращаться к данным через Запрос, их необходимо физически прочитать из файла и поместить в объект ТаблицаЗначений.

Шаг 1: Передача файла с клиента на сервер

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

  1. Пользователь вызывает диалог выбора файла.
  2. Выбранный файл помещается во временное хранилище с помощью метода ПоместитьФайлВоВременноеХранилище().
  3. Адрес этого хранилища (строка) передается в серверную процедуру.
  4. На сервере данные извлекаются по адресу и обрабатываются.

Посмотрим на пример кода для выбора файла:


&НаКлиенте
Процедура ВыбратьИЗагрузитьФайл(Команда)
    Оповещение = Новый ОписаниеОповещения("ПослеВыбораФайла", ЭтотОбъект);
    ПараметрыДиалога = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
    ПараметрыДиалога.Фильтр = "Excel (*.xlsx)|*.xlsx";
    ПараметрыДиалога.Показать(Оповещение);
КонецПроцедуры

&НаКлиенте
Процедура ПослеВыбораФайла(ВыбранныеФайлы, ДополнительныеПараметры) Экспорт
    Если ВыбранныеФайлы <> Неопределено Тогда
        АдресХранилища = "";
        // Помещаем файл во временное хранилище для доступа сервера
        ПоместитьФайл(АдресХранилища, ВыбранныеФайлы[0], , Ложь);
        ЗагрузитьДанныеНаСервере(АдресХранилища);
    КонецЕсли;
КонецПроцедуры

Шаг 2: Чтение данных из XLSX на сервере

Выясним, как прочитать данные, когда адрес файла уже получен. Самый надежный и современный способ, не требующий установки Microsoft Excel на сервере, — использование объекта ТабличныйДокумент.

Разберем по шагам процесс чтения:


&НаСервере
Процедура ЗагрузитьДанныеНаСервере(АдресХранилища)
    // Извлекаем данные из хранилища
    ДанныеФайла = ПолучитьИзВременногоХранилища(АдресХранилища);
    ИмяВременногоФайла = ПолучитьИмяВременногоФайла("xlsx");
    ДанныеФайла.Записать(ИмяВременногоФайла);
    
    // Читаем файл в табличный документ
    ТабДок = Новый ТабличныйДокумент;
    ТабДок.Прочитать(ИмяВременногоФайла);
    
    // Создаем таблицу значений для хранения "сырых" данных
    ТЗ_Данные = Новый ТаблицаЗначений;
    ТЗ_Данные.Колонки.Добавить("ТоварНаименование", Новый ОписаниеТипов("Строка"));
    ТЗ_Данные.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число"));
    
    // Обходим строки табличного документа (начиная со второй, если первая - заголовок)
    Для НомерСтроки = 2 По ТабДок.ВысотаТаблицы Цикл
        НоваяСтрока = ТЗ_Данные.Добавить();
        НоваяСтрока.ТоварНаименование = ТабДок.Область(НомерСтроки, 1).Текст;
        НоваяСтрока.Количество = Число(ТабДок.Область(НомерСтроки, 2).Текст);
    КонецЦикла;
    
    // Теперь ТЗ_Данные заполнена, и ее можно передавать в запрос
    ОбработатьДанныеЗапросом(ТЗ_Данные);
КонецПроцедуры

Шаг 3: Использование запроса для обработки загруженных данных

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

Важный момент: для использования таблицы значений в запросе необходимо передать её как параметр и обязательно описать её структуру внутри текста запроса (типы колонок должны быть определены).


&НаСервере
Процедура ОбработатьДанныеЗапросом(ТЗ_Данные)
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   ДанныеИзФайла.ТоварНаименование КАК ТоварНаименование,
        |   ДанныеИзФайла.Количество КАК Количество
        |ПОМЕСТИТЬ ВТ_Загрузка
        |ИЗ
        |   &ТЗ_Данные КАК ДанныеИзФайла
        |;
        |
        |////////////////////////////////////////////////////////////////////////////////
        |ВЫБРАТЬ
        |   ВТ_Загрузка.ТоварНаименование КАК Наименование,
        |   ЕСТЬNULL(Номенклатура.Ссылка, ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)) КАК СсылкаНаТовар,
        |   СУММА(ВТ_Загрузка.Количество) КАК ОбщееКоличество
        |ИЗ
        |   ВТ_Загрузка КАК ВТ_Загрузка
        |       ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Номенклатура
        |       ПО ВТ_Загрузка.ТоварНаименование = Номенклатура.Наименование
        |ГРУППИРОВАТЬ ПО
        |   ВТ_Загрузка.ТоварНаименование,
        |   Номенклатура.Ссылка";
    
    Запрос.УстановитьПараметр("ТЗ_Данные", ТЗ_Данные);
    
    Результат = Запрос.Выполнить();
    ТаблицаРезультат = Результат.Выгрузить();
    
    // Загружаем результат в реквизит формы (табличную часть)
    Объект.Товары.Загрузить(ТаблицаРезультат);
КонецПроцедуры

Альтернативные методы загрузки

Посмотрим на другие способы, упомянутые в ходе обсуждения:

Основные выводы и советы

Подведем итоги нашего исследования проблемы загрузки данных:

  1. Никогда не выполняйте запрос к пустой таблице. Сначала наполните таблицу данными из файла через цикл обхода ТабличногоДокумента или через ПостроительЗапроса.
  2. Соблюдайте контекст. Помните, что путь к файлу на диске C:\Users... на сервере может быть недоступен. Используйте временное хранилище.
  3. Типизируйте данные. При чтении из Excel все данные могут восприниматься как строки. Перед помещением в запрос или таблицу значений преобразуйте их к нужным типам (число, дата) с помощью функций Число() или Дата().
  4. Сопоставляйте объекты. Загрузка данных — это не просто копирование текста. Важно найти соответствующие элементы в справочниках 1С (через НайтиПоНаименованию или соединение в запросе), чтобы в системе хранились ссылки, а не просто строковые значения.

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

← На главную