Чтение xlsx и xls средствами 1С 8.3: табличный документ, COM, ADO и разбор XML
Содержание
Прочитать 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 на сервере не существует, поэтому файл сначала передают через временное хранилище.
Порядок такой:
- На клиенте пользователь выбирает файл в диалоге
ДиалогВыбораФайлас фильтромФайлы Excel|*.xlsx;*.xls. - Файл помещается во временное хранилище: в новых релизах платформы — асинхронным
ПоместитьФайлНаСерверАсинхилиНачатьПомещениеФайлаНаСервер, в старых —ПоместитьФайл. - На сервере двоичные данные из хранилища записываются во временный файл и читаются.
- Временный файл удаляется в любом случае, даже при ошибке.
Серверная часть выглядит так:
&НаСервере
Функция ПрочитатьФайлНаСервере(АдресВХранилище, Расширение)
ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресВХранилище);
ИмяФайла = ПолучитьИмяВременногоФайла(Расширение);
ДвоичныеДанные.Записать(ИмяФайла);
ТабДок = Новый ТабличныйДокумент;
Попытка
ТабДок.Прочитать(ИмяФайла, СпособЧтенияЗначенийТабличногоДокумента.Значение);
Исключение
УдалитьФайлы(ИмяФайла);
ВызватьИсключение "Не удалось прочитать файл: " + КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
КонецПопытки;
УдалитьФайлы(ИмяФайла);
Возврат ТабДок;
КонецФункции
Расширение временного файла передавайте явно ("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:
- Распаковать архив объектом
ЧтениеZipФайлаво временный каталог. - Прочитать
xl/sharedStrings.xml— список всех строк книги в порядке индексов с нуля. - Прочитать лист, например
xl/worksheets/sheet1.xml: ячейки лежат в элементахcс атрибутомr(адрес вродеB5), значение — во вложенномv. - Если у ячейки атрибут
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 тысяч строк разница между подходами уже заметна. Основные приёмы:
- COM: читайте диапазон целиком. Каждое обращение
Cells(Стр, Кол)— отдельный межпроцессный вызов. СвойствоЛист.UsedRange.Valueза один вызов возвращает весь диапазон какCOMSafeArray. МетодВыгрузить()превращает его в массив 1С, где первый индекс — колонка, второй — строка, оба с нуля. Проверьте размеры на своём файле:Данные.Количество()должно совпасть с числом колонок. - Табличный документ: не берите область дважды. Получили
Область(Стр, Кол, Стр, Кол)— сохраните текст в переменную. Для таблиц на десятки тысяч строк быстрее один раз выгрузить данные построителем в таблицу значений. - Ищите элементы не по одному. Вместо запроса к базе на каждую строку соберите все артикулы в массив, одним запросом получите соответствие артикулов и ссылок, а при обходе берите ссылку из
Соответствие. - Пишите порциями. Запись тысяч объектов в одной транзакции держит блокировки и при ошибке откатывает всё. Разбейте на блоки по 500–1000 объектов в отдельных транзакциях.
- Не держите Excel открытым дольше нужного. Прочитали массив — сразу закрыли книгу и вызвали
Quit(), обработку ведите уже по массиву.
Свойство ОбменДанными.Загрузка = Истина при записи ускоряет загрузку, но отключает проверки и часть обработчиков записи. Для справочников с обязательными реквизитами это даёт «битые» элементы. Используйте его, только если понимаете, какие проверки пропускаете.
Ориентир по порядку величин: табличный документ читает лист на десятки тысяч строк за секунды, COM с обходом по ячейкам на том же файле может работать минутами, а COM с чтением всего диапазона сравним с табличным документом.
Частые вопросы о чтении Excel в 1С
Можно ли прочитать Excel в 1С без установленного Microsoft Office?
ТабличныйДокумент.Прочитать() и разбор xlsx как ZIP-архива работают только средствами платформы, в том числе на сервере под Linux.Читает ли 1С старый формат xls?
Как прочитать csv, который пользователи называют «выгрузкой из Excel»?
ЧтениеТекста и разбирайте строку функцией СтрРазделить по точке с запятой; Excel для этого не нужен.