Загрузка данных из внешних файлов формата MXL (родной формат табличных документов 1С) является стандартной задачей при интеграции систем или миграции данных. Однако при использовании таких инструментов, как ПостроительЗапроса, программисты часто сталкиваются с неочевидными ошибками. В этой статье мы разберем, как эффективно прочитать данные из ТабличныйДокумент, почему возникает ошибка «Ожидается выражение ВЫБРАТЬ» и какие альтернативные способы обхода данных существуют.
Этот способ считается наиболее элегантным, так как позволяет быстро преобразовать область табличного документа в типизированную ТаблицаЗначений. Рассмотрим базовый алгоритм работы. Для начала нам необходимо прочитать файл с диска и передать его область в специальный объект-описание. При необходимости чтения локальных файлов в клиент-серверной архитектуре можно воспользоваться руководством по работе с файлами в управляемых формах.
Проанализируем типовой программный код для решения этой задачи:
ТабДок = Новый ТабличныйДокумент;
ТабДок.Прочитать("C:\ПутьКФайлу\Данные.mxl");
// Определяем область, которую хотим загрузить
// Это может быть как именованная область, так и конкретные координаты
ОбластьДанных = ТабДок.Область("R1C1:R" + Формат(ТабДок.ВысотаТаблицы, "ЧГ=0") + "C" + Формат(ТабДок.ШиринаТаблицы, "ЧГ=0"));
Построитель = Новый ПостроительЗапроса;
Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ОбластьДанных);
// Заполняем настройки и выгружаем результат
Построитель.ЗаполнитьНастройки();
Построитель.Выполнить();
ТЗ = Построитель.Результат.Выгрузить();
Важный нюанс: Почему часто возникает ошибка {(1, 1)}: Ожидается выражение "ВЫБРАТЬ"? Выясним причину. Это происходит потому, что ПостроительЗапроса не обладает искусственным интеллектом и не может самостоятельно догадаться, где в вашем файле заканчивается «шапка» (заголовок документа) и начинаются полезные данные. Если в первой строке выбранной области находятся пустые ячейки, объединенные ячейки или декоративный текст, построитель не может сформировать структуру колонок и «вылетает» с ошибкой синтаксиса запроса.
Чтобы метод сработал, первая строка области обязательно должна содержать текстовые заголовки. Эти заголовки в дальнейшем станут именами колонок в полученной таблице значений.
Если структура вашего MXL-файла сложная (например, это печатная форма счета с итогами, подписями и вложенными группировками), ПостроительЗапроса может не справиться. В этом случае мы рекомендуем использовать прямой перебор строк и колонок.
Рассмотрим, как реализовать такой обход:
Для Выс = 1 по ТабДок.ВысотаТаблицы Цикл
// Предположим, мы ищем начало данных по ключевому слову в первой колонке
ТекстЯчейки = ТабДок.Область(Выс, 1).Текст;
Если ТекстЯчейки = "НачалоДанных" Тогда
// Начинаем заполнение своей таблицы значений
НоваяСтрока = ТЗ.Добавить();
НоваяСтрока.Товар = ТабДок.Область(Выс, 2).Текст;
НоваяСтрока.Количество = ТабДок.Область(Выс, 3).Значение; // Используем .Значение для чисел
КонецЕсли;
КонецЦикла;
Проанализируем ситуацию: использование свойства Значение вместо Текст крайне важно. Если в ячейке MXL сохранено число или дата, обращение к .Значение вернет вам готовый тип данных 1С, а не строку, что избавит от необходимости ручного приведения типов.
Иногда требуется не просто выгрузить данные, а сразу сгруппировать их или рассчитать итоги при чтении из файла. Для этого мы можем детально настроить ОписаниеИсточникаДанных. Посмотрим на пример, где мы задаем измерения и итоги прямо в процессе парсинга:
ИсточникДанных = Новый ОписаниеИсточникаДанных(ТабДок.Область("Данные"));
// Указываем, какие колонки будут измерениями (группировками)
ИсточникДанных.Колонки.Услуга.Измерение = Истина;
ИсточникДанных.Колонки.Категория.Измерение = Истина;
// Настраиваем агрегатные функции для ресурсов
ИсточникДанных.Колонки.Тип.Итог = "Максимум(Тип)";
ИсточникДанных.Колонки.Сумма.Итог = "Сумма(Сумма)";
ПЗ = Новый ПостроительЗапроса;
ПЗ.ИсточникДанных = ИсточникДанных;
ПЗ.Выполнить();
// Теперь результат можно обходить по группировкам, как обычный запрос
Выборка = ПЗ.Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока Выборка.Следующий() Цикл
// Работаем с данными
КонецЦикла;
Этот подход позволяет эффективно обрабатывать большие файлы, перекладывая часть логики по свертке данных на механизмы построителя.
Для того чтобы загрузка проходила без ошибок, придерживайтесь следующих правил:
ТабДок.ПолучитьОбласть("Строка"), что гораздо надежнее, чем поиск по координатам.ПостроительЗапроса, убедитесь, что в колонках с числами нет текстовых пометок (например, "грн." или "шт."), иначе колонка будет определена как строковая.Подведем итог: выбор метода загрузки зависит от структуры вашего файла. Если это простая "плоская" таблица — используйте ПостроительЗапроса с предварительной очисткой области. Если это сложный отчет с множеством заголовков и итогов — используйте построчный обход с проверкой свойств ячеек.