Загрузка xlsx в 1С 8.3 кодом: от ТабличныйДокумент.Прочитать() до драйвера ACE

· 9 мин

Содержание

Чтобы прочитать Excel файл в 1С 8.3, проще всего создать Новый ТабличныйДокумент и вызвать у него метод Прочитать(ИмяФайла): платформа сама откроет xls или xlsx, и дальше вы обходите ячейки по номерам строк и колонок. Excel на компьютере для этого не нужен. COM-объект Excel.Application и драйвер ADO нужны в особых случаях: когда важен конкретный лист, нужна выборка SQL-запросом или программа работает на старой платформе.

Типичная боль — прайс поставщика на 5000 строк, который вручную переносить день. Ниже разобраны три способа с рабочим кодом, приведение типов, ускорение массовой загрузки и ошибки, на которых обычно спотыкаются.

Какой метод чтения Excel выбрать и что подготовить

Начните с вопроса: где выполняется код и что установлено на этой машине. В клиент-серверной базе код на сервере работает под пользователем службы 1С, и Excel там обычно нет.

СпособНужен ExcelНужны драйверыГде работаетКогда брать
ТабличныйДокумент.Прочитать()нетнетсервер, толстый клиент, Windows и Linuxпочти всегда
COM Excel.Applicationданеттолько Windowsнужен конкретный лист, формулы, форматирование
ADO + провайдер ACE/JetнетAccess Database Engineтолько WindowsSQL-выборка по листу, большие плоские таблицы
Типовая обработка загрузкинетнетинтерактивноразовая загрузка без программирования

Подготовка перед любым способом:

  • 📄 закройте файл в Excel — открытая книга блокируется, и чтение падает;
  • 🧹 уберите из шапки объединённые ячейки или запомните, с какой строки идут данные;
  • 🔢 проверьте, что числа в файле — числа, а не текст с пробелами;
  • 🖥 узнайте разрядность клиента и сервера 1С (32 или 64 бита) — это важно для COM и ADO.

Если загрузка разовая, сначала проверьте типовой механизм. В БСП-конфигурациях (БП 3.0, УТ 11, ЗУП 3.1) у ряда списков и табличных частей есть команда загрузки из файла: вы вставляете таблицу из Excel и сопоставляете колонки с реквизитами. Код писать не придётся.

Чтение Excel файла как табличного документа

Это родной механизм платформы. Метод Прочитать понимает форматы xls, xlsx, mxl и ods. Он доступен на сервере, в толстом клиенте и во внешнем соединении. В тонком и веб-клиенте его нет, поэтому файл сначала передают на сервер.

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

&НаКлиенте
Процедура ЗагрузитьИзExcel(Команда)
	Оповещение = Новый ОписаниеОповещения("ПослеПомещенияФайла", ЭтотОбъект);
	НачатьПомещениеФайла(Оповещение, , , Истина, УникальныйИдентификатор);
КонецПроцедуры

&НаКлиенте
Процедура ПослеПомещенияФайла(Результат, Адрес, ВыбранноеИмяФайла, ДополнительныеПараметры) Экспорт
	Если Не Результат Тогда
		Возврат;
	КонецЕсли;
	Расширение = Сред(Новый Файл(ВыбранноеИмяФайла).Расширение, 2); // ".xlsx" -> "xlsx"
	ЗагрузитьНаСервере(Адрес, Расширение);
КонецПроцедуры

На платформе 8.3.18 и выше есть более новый метод НачатьПомещениеФайлаНаСервер, но приведённый вариант тоже работает.

Шаг 2. Прочитать файл на сервере

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

	ТабДок = Новый ТабличныйДокумент;
	ТабДок.Прочитать(ИмяФайла, СпособЧтенияЗначенийТабличногоДокумента.Текст);
	УдалитьФайлы(ИмяФайла);

	ПерваяСтрокаДанных = 2; // строка 1 — шапка
	Для НомерСтроки = ПерваяСтрокаДанных По ТабДок.ВысотаТаблицы Цикл
		Артикул = СокрЛП(ТабДок.Область(НомерСтроки, 1, НомерСтроки, 1).Текст);
		Наименование = СокрЛП(ТабДок.Область(НомерСтроки, 2, НомерСтроки, 2).Текст);
		ЦенаТекстом = ТабДок.Область(НомерСтроки, 3, НомерСтроки, 3).Текст;
		Если ПустаяСтрока(Артикул) Тогда
			Продолжить;
		КонецЕсли;
		НоваяСтрока = Объект.Товары.Добавить();
		НоваяСтрока.Артикул = Артикул;
		НоваяСтрока.Наименование = Наименование;
		НоваяСтрока.Цена = ПривестиКЧислу(ЦенаТекстом);
	КонецЦикла;
КонецПроцедуры

ВысотаТаблицы и ШиринаТаблицы дают размер заполненной области. Ячейку удобно получать через Область(Верх, Лево, Низ, Право) с одинаковыми номерами — так не нужно собирать строку вида R2C3.

Два режима чтения значений

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

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

Для загрузки прайсов и остатков режим «Текст» надёжнее: вы сами контролируете разбор и сразу видите мусор в данных.

Внешняя обработка вместо доработки конфигурации

Чтобы не трогать типовую конфигурацию , код выносят во внешнюю обработку (.epf). Форма с полем табличного документа даёт ещё один приём: пользователь открывает файл, видит его прямо в форме, проверяет глазами и только потом жмёт «Загрузить». Табличный документ в реквизите формы читается на сервере тем же циклом.

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

Чтение Excel через COM-объект Excel.Application

COM управляет настоящим Excel. Способ гибкий, но требует установленного Excel и работает только в Windows. На сервере 1С его не любят: служба крутится без рабочего стола, нужны права DCOM для пользователя службы, а Microsoft не поддерживает такой сценарий для Office.

Excel = Новый COMОбъект("Excel.Application");
Excel.DisplayAlerts = Ложь;
Попытка
	Книга = Excel.Workbooks.Open(ИмяФайла);
	Лист = Книга.Worksheets(1); // номер или имя листа: Книга.Worksheets("Прайс")
	ВсегоСтрок = Лист.UsedRange.Rows.Count;
	Для НомерСтроки = 2 По ВсегоСтрок Цикл
		Артикул = Лист.Cells(НомерСтроки, 1).Text;
		Цена = Лист.Cells(НомерСтроки, 3).Value;
		// обработка строки
	КонецЦикла;
	Книга.Close(Ложь);
Исключение
	Сообщить(ОписаниеОшибки());
КонецПопытки;
Excel.Quit();
Excel = Неопределено;

Разница свойств ячейки:

  • Value — исходное значение: число, дата, строка;
  • Text — то, что отображается на экране, с форматированием.

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

Список листов: Книга.Worksheets.Count и Книга.Worksheets(Н).Name. Так легко дать пользователю выбрать лист перед загрузкой.

Чтение через ADO, ADOX и драйвер Microsoft ACE

Здесь Excel-файл открывается как база данных, а лист — как таблица. Excel не нужен, но нужен провайдер: Microsoft.ACE.OLEDB.12.0 из пакета Microsoft Access Database Engine. Старый Microsoft.Jet.OLEDB.4.0 читает только xls и существует только в 32-битном варианте.

Разрядность драйвера должна совпадать с разрядностью процесса 1С, который выполняет код: 64-битный сервер не увидит 32-битный ACE.

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

Выборка = Новый COMОбъект("ADODB.Recordset");
Выборка.Open("SELECT * FROM [Прайс$]", Соединение);
Пока Не Выборка.EOF Цикл
	Артикул = Выборка.Fields(0).Value;
	Цена = Выборка.Fields(2).Value;
	// обработка строки
	Выборка.MoveNext();
КонецЦикла;
Выборка.Close();
Соединение.Close();

Что значат параметры строки подключения:

ПараметрСмысл
Excel 12.0 Xmlформат xlsx; для xls — Excel 8.0
HDR=YESпервая строка — имена колонок, их можно писать в SELECT
IMEX=1смешанные колонки читать как текст

Как получить список листов через ADOX

Имя листа в запросе пишется с $ в квадратных скобках. Если имя заранее неизвестно, перечислите таблицы через каталог ADOX:

Каталог = Новый COMОбъект("ADOX.Catalog");
Каталог.ActiveConnection = Соединение;
Для Индекс = 0 По Каталог.Tables.Count - 1 Цикл
	Сообщить(Каталог.Tables(Индекс).Name); // например: Прайс$
КонецЦикла;

Каталог показывает не только листы, но и именованные диапазоны — их имена идут без $ на конце. Отфильтруйте по этому признаку.

Драйвер угадывает тип колонки по первым строкам. Если там числа, а ниже встречается «12-А», такие значения придут пустыми. IMEX=1 снимает большую часть проблем: смешанная колонка читается как текст.

Обработка данных: приведение типов Excel к типам 1С

Сырые строки из Excel редко ложатся в реквизиты как есть. Три вещи, которые ломаются чаще всего.

Числа

В файле встречаются неразрывные пробелы между разрядами, запятая и точка вперемешку, знак валюты. Функция Число() на такой строке вызывает исключение. Очистите строку и приводите через описание типов: оно вернёт 0 вместо ошибки.

Функция ПривестиКЧислу(Знач Текст)
	Текст = СтрЗаменить(Текст, Символы.НПП, "");
	Текст = СтрЗаменить(Текст, " ", "");
	Текст = СтрЗаменить(Текст, "р.", "");
	Текст = СтрЗаменить(Текст, ",", ".");
	ОписаниеЧисла = Новый ОписаниеТипов("Число");
	Возврат ОписаниеЧисла.ПривестиЗначение(Текст);
КонецФункции

Ноль после приведения — повод записать строку в журнал ошибок, а не молча загрузить цену 0.

Даты

Через COM Value и через ADO дата обычно приходит уже датой. В режиме «Текст» придёт строка вида 15.03.2025, её разбирают по частям: Дата(Число(Сред(С, 7, 4)), Число(Сред(С, 4, 2)), Число(Сред(С, 1, 2))).

Если вместо даты видите число вроде 45731, это серийный номер дня Excel. Перевод: Дата(1899, 12, 30) + СерийныйНомер * 86400. Для 45731 получится 15.03.2025.

Ссылки на справочники

Артикул или ИНН из файла надо превратить в ссылку. Не ищите НайтиПоРеквизиту в каждой строке — об этом в следующем разделе.

Ускорение массового импорта из Excel

На файле в сотню строк разницы не видно. На десятках тысяч строк выбор приёма решает, загрузится файл за минуту или за час.

  • ⚡ COM: читайте диапазон целиком. Каждое обращение Cells(i, j) — вызов в другой процесс. Лист.UsedRange.Value отдаёт весь диапазон одним вызовом как COMSafeArray, дальше перебор идёт уже в памяти 1С.
  • 🗂 Справочники — одним запросом. Соберите все артикулы из файла в массив, выполните запрос ГДЕ Номенклатура.Артикул В (&Артикулы) и положите результат в Соответствие. Поиск ссылки по ключу соответствия почти бесплатный.
  • 💾 Записывайте порциями. Создание тысяч элементов справочника оборачивайте в транзакции по несколько сотен объектов. Одна гигантская транзакция держит блокировки, а запись без транзакций медленнее.
  • 🧾 Табличную часть заполняйте в памяти. Добавьте все строки в Объект.Товары, а документ запишите один раз в конце.
  • 🖥 Тяжёлый импорт — на сервер. Вызов сервера из клиента в цикле по строкам — самый частый тормоз во внешних обработках. Передайте файл на сервер один раз и обработайте его там целиком.

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

Где выполняется ваш код загрузки?

Ошибки при чтении Excel в 1С и что с ними делать

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

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

Частые вопросы

Можно ли прочитать Excel в 1С без установленного Microsoft Excel?
Да. Метод ТабличныйДокумент.Прочитать() открывает xls и xlsx средствами самой платформы. Excel нужен только для способа через COM-объект Excel.Application.
Как прочитать файл формата csv из Excel?
Csv — это текст, а не книга. Его читают через ЧтениеТекста или ТекстовыйДокумент и делят строки функцией СтрРазделить по разделителю, обычно точке с запятой.
Почему после загрузки длинные коды вроде 4601234567890 превращаются в 4,60123E+12?
В Excel колонка числовая, и при чтении текста берётся отображаемое значение. Задайте колонке текстовый формат в Excel или читайте исходное значение и форматируйте его через Формат(Значение, “ЧГ=0”).
Работает ли чтение Excel в 1С на Linux?
Работает только через ТабличныйДокумент.Прочитать(). COM-объекты и драйверы ADO — технологии Windows, на Linux-сервере их нет.
Как прочитать все листы книги, а не только первый?
Через COM перебором Книга.Worksheets или через ADO, получив список листов каталогом ADOX и выполнив запрос к каждому листу.