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

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

В процессе разработки часто возникает задача загрузить данные из внешнего файла, например, с расширением .mxl или .xlsx, в ТаблицуЗначений для дальнейшей обработки. Один из распространенных подходов — использование встроенных объектов 1С. Однако, при неверном выборе объекта можно столкнуться с ошибкой «ожидается выражение "ВЫБРАТЬ"». Разберем, почему она возникает и как правильно выполнить преобразование.

Проанализируем ситуацию: разработчик пытается загрузить данные из табличного документа, используя объект ПостроительЗапроса. Код выглядит примерно так:


Построитель = Новый ПостроительЗапроса;
ТабДок = Новый ТабличныйДокумент;
ТабДок.Прочитать("C:\путь\к_файлу.mxl");

// Указываем область табличного документа как источник данных
Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТабДок.Область(1, 1, ТабДок.ВысотаТаблицы, 7));
Построитель.Выполнить(); // Здесь возникает ошибка
ТЗ = Построитель.Результат.Выгрузить();

При выполнении этого кода система выдает ошибку, связанную с языком запросов. Выясним причину. Объект ПостроительЗапроса предназначен для конструирования и выполнения запросов к базе данных. Даже если ему в качестве источника подставить табличный документ, его внутренний механизм все равно пытается построить SQL-подобный запрос. Поскольку текст запроса с ключевым словом ВЫБРАТЬ не был задан, построитель не может сформировать итоговую команду, что и приводит к ошибке.

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

Решение 1: Использование ПостроителяОтчета

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

Рабочий пример кода:


// Создаем ТабличныйДокумент и читаем из файла
ТабДок = Новый ТабличныйДокумент;
ТабДок.Прочитать("C:\путь\к_файлу.mxl");

// Используем ПостроительОтчета
Построитель = Новый ПостроительОтчета;
// Указываем область с данными. Например, со строки 1, колонки 1 до конца таблицы по высоте и на 7 колонок в ширину
Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТабДок.Область(1, 1, ТабДок.ВысотаТаблицы, 7));

// Выполняем построение
Построитель.Выполнить();

// Выгружаем результат в ТаблицуЗначений
ТаблицаРезультат = Построитель.Результат.Выгрузить();

Этот код в большинстве случаев отработает корректно. Однако, существует важный нюанс, который может привести к ошибке даже с этим, казалось бы, верным решением.

Особенности и возможные проблемы при работе с ПостроителемОтчета

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

Критически важный момент: для корректной работы этого метода первая строка указанной области табличного документа должна содержать заголовки колонок. Именно эти значения ПостроительОтчета использует для именования колонок в результирующей ТаблицеЗначений.

Рассмотрим частый случай. Если в вашем файле .mxl первые несколько строк пустые или содержат общую "шапку" документа, а сами заголовки таблицы начинаются, например, с 3-й или 4-й строки, то попытка считать область с первой строки ТабДок.Область(1, 1, ...) приведет к ошибке. Построитель не найдет имен для колонок и не сможет создать структуру таблицы значений.

Как исправить:

  1. Убедитесь, что в исходном файле нет пустых строк перед строкой с заголовками.
  2. Если пустые строки есть и убрать их нельзя, скорректируйте область, которую вы передаете в источник данных. Например, если заголовки начинаются с 4-й строки, код нужно изменить так:

// Указываем, что данные начинаются с 4-й строки
НачальнаяСтрока = 4; 
Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТабДок.Область(НачальнаяСтрока, 1, ТабДок.ВысотаТаблицы, 7));

Также стоит помнить о других особенностях:

Решение 2: Ручной перебор ячеек для полного контроля

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

Пример реализации:


// Предполагаем, что ТабДок уже заполнен, а заголовки находятся в первой строке
ТаблицаРезультат = Новый ТаблицаЗначений;

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

// 2. Начинаем перебор со второй строки, так как первая - это заголовки
Для НомерСтроки = 2 По ТабДок.ВысотаТаблицы Цикл
    НоваяСтрока = ТаблицаРезультат.Добавить();
    Для НомерКолонки = 1 По ТаблицаРезультат.Колонки.Количество() Цикл
        // Получаем текст из ячейки и присваиваем значение
        ЗначениеЯчейки = ТабДок.Область(НомерСтроки, НомерКолонки).Текст;
        НоваяСтрока[НомерКолонки - 1] = ЗначениеЯчейки;
    КонецЦикла;
КонецЦикла;

// Теперь в переменной ТаблицаРезультат находится заполненная таблица значений

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

Недостаток:

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

← На главную