Чтение xlsx и xls средствами 1С 8.3: табличный документ, COM, ADO и разбор XML

· 10 мин

Содержание

Прочитать Excel в 1С 8.3 проще всего методом ТабличныйДокумент.Прочитать(): он открывает xlsx, xls и ods без установленного Microsoft Excel, работает на сервере под Windows и Linux и появился в платформе 8.3.6. COM-объект Excel.Application нужен, когда требуются формулы, макросы или особые свойства книги, но он требует Excel на той машине, где выполняется код. ADO подходит для больших «плоских» таблиц, а разбор xlsx как ZIP-архива с XML — для случаев, когда нельзя полагаться ни на Excel, ни на драйверы.

Какой способ выбрать в типичной ситуации:

СпособКогда выбиратьЧто нужноСлабое место
Табличный документОбычная загрузка прайса, остатков, справочниковПлатформа 8.3.6 и новееОбъединённые ячейки и сложная шапка
COM ExcelНужны формулы, несколько листов, форматированиеУстановленный Excel, WindowsМедленно по ячейкам, процессы-«зомби»
ADO (ACE OLE DB)Таблица на десятки тысяч строк, нужен SQL-отборДрайвер Access Database Engine той же разрядности, что и 1СУгадывает типы колонок по первым строкам
Разбор XMLСервер на Linux, нет Excel и драйверов, нужен полный контрольТолько платформаБольше кода, только xlsx

Подготовка: где лежит файл и где выполняется код

Первый вопрос — не «каким методом», а «на каком компьютере». Файл пользователь выбирает у себя, а читать его чаще всего удобнее на сервере. В клиент-серверной базе путь C:\Users\...\Прайс.xlsx на сервере не существует, поэтому файл сначала передают через временное хранилище.

Порядок такой:

  1. На клиенте пользователь выбирает файл в диалоге ДиалогВыбораФайла с фильтром Файлы Excel|*.xlsx;*.xls.
  2. Файл помещается во временное хранилище: в новых релизах платформы — асинхронным ПоместитьФайлНаСерверАсинх или НачатьПомещениеФайлаНаСервер, в старых — ПоместитьФайл.
  3. На сервере двоичные данные из хранилища записываются во временный файл и читаются.
  4. Временный файл удаляется в любом случае, даже при ошибке.

Серверная часть выглядит так:

&НаСервере
Функция ПрочитатьФайлНаСервере(АдресВХранилище, Расширение)

    ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресВХранилище);
    ИмяФайла = ПолучитьИмяВременногоФайла(Расширение);
    ДвоичныеДанные.Записать(ИмяФайла);

    ТабДок = Новый ТабличныйДокумент;
    Попытка
        ТабДок.Прочитать(ИмяФайла, СпособЧтенияЗначенийТабличногоДокумента.Значение);
    Исключение
        УдалитьФайлы(ИмяФайла);
        ВызватьИсключение "Не удалось прочитать файл: " + КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
    КонецПопытки;

    УдалитьФайлы(ИмяФайла);
    Возврат ТабДок;

КонецФункции

Расширение временного файла передавайте явно ("xlsx" или "xls"). Метод Прочитать определяет формат по расширению, и файл без него может не открыться.

Перед загрузкой договоритесь с теми, кто готовит файлы, о простой форме: одна строка шапки, данные с первой колонки, без объединённых ячеек и итоговых строк посередине. Это убирает половину проблем ещё до написания кода.

Чтение Excel через табличный документ 1С

Метод Прочитать загружает лист Excel в объект ТабличныйДокумент. Дальше с ним работают как с обычной печатной формой: обращаются к ячейкам по номерам строки и колонки.

Второй параметр задаёт, что брать из ячейки:

  • 🔢 СпособЧтенияЗначенийТабличногоДокумента.Значение — платформа пытается получить типизированное значение: число, дату. Подходит для цен и количеств.
  • 🔤 СпособЧтенияЗначенийТабличногоДокумента.Текст — всё читается как строка, ровно как отображается. Подходит для артикулов вроде 00125, где важны ведущие нули.

Обход строк и колонок

Размер заполненной части таблицы дают свойства ВысотаТаблицы и ШиринаТаблицы. Пример читает прайс, где в колонке 1 артикул, в колонке 2 наименование, в колонке 3 цена, а первая строка — шапка:

ТабДок = ПрочитатьФайлНаСервере(Адрес, "xlsx");

Для НомерСтроки = 2 По ТабДок.ВысотаТаблицы Цикл

    Артикул = СокрЛП(ТабДок.Область(НомерСтроки, 1, НомерСтроки, 1).Текст);
    Если ПустаяСтрока(Артикул) Тогда
        Продолжить; // пустые строки и разделители пропускаем
    КонецЕсли;

    Наименование = СокрЛП(ТабДок.Область(НомерСтроки, 2, НомерСтроки, 2).Текст);
    ЦенаТекст    = ТабДок.Область(НомерСтроки, 3, НомерСтроки, 3).Текст;
    Цена         = СтрокаВЧисло(ЦенаТекст);

    // дальше — поиск номенклатуры по артикулу и запись цены
КонецЦикла;

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

Функция СтрокаВЧисло(Знач Текст)

    Текст = СтрЗаменить(Текст, " ", "");
    Текст = СтрЗаменить(Текст, Символы.НПП, "");
    Текст = СтрЗаменить(Текст, ",", ".");

    Попытка
        Возврат Число(Текст);
    Исключение
        Возврат 0;
    КонецПопытки;

КонецФункции

Нужный лист книги

Прочитать загружает книгу целиком, а несколько листов появляются в табличном документе как отдельные области. Надёжнее всего договориться, что данные лежат на первом листе. Если листов несколько и порядок не гарантирован, удобнее перейти на COM или разбор XML, где лист выбирают по имени.

Табличный документ в таблицу значений

Для дальнейшей обработки (свёртка, поиск, запрос) данные удобно перевести в ТаблицаЗначений. Классический приём — построитель запроса, который берёт область табличного документа как источник и считает первую строку шапкой:

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

Имена колонок построитель берёт из первой строки. Шапка вида Цена, руб. превратится в непривычное имя, поэтому сначала выведите ТЗ.Колонки в отладчике и посмотрите, как они назвались.

Чтение через COM-соединение с Excel.Application

COM — самый старый способ. 1С запускает невидимый Excel и управляет им через его объектную модель. Работает только в Windows и только там, где установлен Excel: на клиенте — у пользователя, на сервере — на сервере 1С.

Excel = Новый COMОбъект("Excel.Application");
Excel.DisplayAlerts = Ложь;
Книга = Excel.Workbooks.Open(ИмяФайла);

Попытка
    Лист = Книга.Worksheets("Прайс"); // или Worksheets(1)
    ЧислоСтрок = Лист.UsedRange.Rows.Count;

    Для НомерСтроки = 2 По ЧислоСтрок Цикл
        Артикул = Лист.Cells(НомерСтроки, 1).Text;
        Цена    = Лист.Cells(НомерСтроки, 3).Value;
        // обработка строки
    КонецЦикла;
Исключение
    ТекстОшибки = КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
КонецПопытки;

Книга.Close(Ложь);
Excel.Quit();
Excel = Неопределено;

Разница между свойствами ячейки: Value отдаёт значение (число, дату), Text — строку в том виде, как её видно на экране с учётом формата. Для артикулов берите Text, для сумм — Value.

Всегда закрывайте книгу и вызывайте Quit(), в том числе в ветке ошибки. Иначе в диспетчере задач копится EXCEL.EXE, держит файл открытым, и следующая загрузка того же файла падает.

Запускать Excel на сервере 1С Microsoft не рекомендует: службе нужен профиль пользователя и настроенные права DCOM, а зависший процесс блокирует соседние сеансы. Если COM неизбежен, выполняйте его на клиенте и передавайте на сервер уже готовые данные.

ADO, сторонние компоненты и разбор xlsx как XML

ADO через драйвер ACE OLE DB

Excel-файл можно открыть как базу данных и выбрать строки SQL-запросом. Нужен установленный Microsoft Access Database Engine той же разрядности, что и процесс 1С: для 64-битного сервера — 64-битный драйвер.

Соединение = Новый COMОбъект("ADODB.Connection");
Соединение.Open("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + ИмяФайла
    + ";Extended Properties=""Excel 12.0 Xml;HDR=YES;IMEX=1"";");

Выборка = Новый COMОбъект("ADODB.Recordset");
Выборка.Open("SELECT * FROM [Прайс$]", Соединение);

Пока Не Выборка.EOF() Цикл
    Артикул = Выборка.Fields(0).Value;
    Цена    = Выборка.Fields(2).Value;
    Выборка.MoveNext();
КонецЦикла;

Выборка.Close();
Соединение.Close();

HDR=YES означает, что первая строка — шапка. IMEX=1 просит читать колонки со смешанными данными как текст. Без него драйвер угадывает тип по первым строкам, и если там числа, текстовые артикулы ниже вернутся пустыми.

Готовые обработки и компоненты

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

Разбор xlsx без Excel

Файл xlsx — это ZIP-архив с XML внутри. Его читают штатными средствами платформы, и это работает на сервере под Linux:

  1. Распаковать архив объектом ЧтениеZipФайла во временный каталог.
  2. Прочитать xl/sharedStrings.xml — список всех строк книги в порядке индексов с нуля.
  3. Прочитать лист, например xl/worksheets/sheet1.xml: ячейки лежат в элементах c с атрибутом r (адрес вроде B5), значение — во вложенном v.
  4. Если у ячейки атрибут t="s", в v лежит не текст, а номер строки из sharedStrings.

Даты Excel хранит числом дней. Перевод в дату 1С:

ДатаИзExcel = Дата(1899, 12, 30) + Число(ЗначениеV) * 86400;

Проверка: число 45658 соответствует 01.01.2025. Порядок листов в книге задаёт xl/workbook.xml; имя файла sheet1.xml не обязательно совпадает с первым листом, который видит пользователь.

Ошибки при чтении Excel и как их обойти

Диагностика: выберите симптом

Ещё несколько нюансов импорта, которые всплывают уже после первой «успешной» загрузки:

  • 📅 Даты из разных источников. В одном файле часть дат бывает настоящими датами, часть — строками 01.02.2025. Проверяйте тип значения через ТипЗнч() и разбирайте строку отдельно.
  • 🔗 Объединённые ячейки. Значение хранится только в левой верхней ячейке, остальные пустые. Если в группе строк товар указан один раз, запоминайте последнее непустое значение и подставляйте его ниже.
  • 🧮 Формулы. Читается последнее вычисленное значение, которое сохранил Excel. Файлы, сформированные другими программами без пересчёта, могут вернуть пустые ячейки на месте формул — откройте и пересохраните такой файл в Excel.
  • 🙈 Скрытые строки и листы. Ни табличный документ, ни ADO их не пропускают. Если в файле есть скрытые черновые строки, их загрузят вместе с данными.
  • 🔁 Повторная загрузка. Ищите существующий элемент по артикулу или ИНН, а не создавайте новый на каждой строке, иначе после второго запуска справочник задвоится.

Как ускорить чтение больших файлов

На файле в 5–10 тысяч строк разница между подходами уже заметна. Основные приёмы:

  1. COM: читайте диапазон целиком. Каждое обращение Cells(Стр, Кол) — отдельный межпроцессный вызов. Свойство Лист.UsedRange.Value за один вызов возвращает весь диапазон как COMSafeArray. Метод Выгрузить() превращает его в массив 1С, где первый индекс — колонка, второй — строка, оба с нуля. Проверьте размеры на своём файле: Данные.Количество() должно совпасть с числом колонок.
  2. Табличный документ: не берите область дважды. Получили Область(Стр, Кол, Стр, Кол) — сохраните текст в переменную. Для таблиц на десятки тысяч строк быстрее один раз выгрузить данные построителем в таблицу значений.
  3. Ищите элементы не по одному. Вместо запроса к базе на каждую строку соберите все артикулы в массив, одним запросом получите соответствие артикулов и ссылок, а при обходе берите ссылку из Соответствие.
  4. Пишите порциями. Запись тысяч объектов в одной транзакции держит блокировки и при ошибке откатывает всё. Разбейте на блоки по 500–1000 объектов в отдельных транзакциях.
  5. Не держите Excel открытым дольше нужного. Прочитали массив — сразу закрыли книгу и вызвали Quit(), обработку ведите уже по массиву.

Свойство ОбменДанными.Загрузка = Истина при записи ускоряет загрузку, но отключает проверки и часть обработчиков записи. Для справочников с обязательными реквизитами это даёт «битые» элементы. Используйте его, только если понимаете, какие проверки пропускаете.

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

Перед запуском загрузки в рабочую базу
Выполнено: 0 / 5

Частые вопросы о чтении Excel в 1С

Можно ли прочитать Excel в 1С без установленного Microsoft Office?
Да. ТабличныйДокумент.Прочитать() и разбор xlsx как ZIP-архива работают только средствами платформы, в том числе на сервере под Linux.
Читает ли 1С старый формат xls?
Табличный документ открывает и xls, и xlsx. Разбор XML подходит только для xlsx: старый xls — двоичный формат, его проще пересохранить.
Как прочитать csv, который пользователи называют «выгрузкой из Excel»?
CSV — обычный текст. Читайте его через ЧтениеТекста и разбирайте строку функцией СтрРазделить по точке с запятой; Excel для этого не нужен.
Почему файл читается у меня, а у пользователя на сервере нет?
У вас код, скорее всего, работает в файловой базе или на клиенте, где есть Excel и доступ к пути. На сервере нужен файл во временном хранилище и способ без COM.
Можно ли читать файл, открытый у кого-то в Excel?
Обычно нет: Excel блокирует файл на запись, и часть способов не может его открыть. Попросите закрыть файл или работайте с его копией.