Как прочитать данные из сложного Excel-файла или PDF-счета в 1С

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

Чтение входящих счетов от контрагентов — классическая задача для разработчика 1С. Однако на практике мы часто сталкиваемся с тем, что файлы имеют сложную структуру: объединенные ячейки, "плавающие" колонки, вложенные таблицы или вовсе приходят в формате PDF. Разберем основные стратегии и технические приемы, которые позволят автоматизировать загрузку таких данных, минимизируя ручной труд пользователей.

Метод 1: Использование стандартного объекта ТабличныйДокумент

Самый простой и доступный способ прочитать Excel-файл без установленного Microsoft Office на сервере — это использование встроенных средств платформы 1С. Рассмотрим, как это реализовать технически. Основным инструментом здесь выступает объект ТабличныйДокумент.

Проанализируем базовый алгоритм чтения:


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

Важный нюанс при работе со счетами, сформированными в 1С и выгруженными в Excel: они часто содержат объединенные ячейки. Выясним, как программа воспринимает такие области. При объединении нескольких колонок (например, с 2-й по 5-ю), фактическое значение будет содержаться только в самой левой верхней ячейке этой области. Посмотрим на пример обхода строк:


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

Метод 2: Алгоритм «Поиск по якорям»

При работе со сложными счетами мы не можем полагаться на фиксированные номера строк и колонок, так как поставщик может добавить логотип, рекламный баннер или изменить ширину шапки. Рассмотрим стратегию поиска по ключевым словам или «якорям».

Вместо обращения к ячейке (10, 5), мы проанализируем таблицу на наличие заголовков, таких как «Наименование», «Кол-во», «Сумма». Разберем, как реализовать универсальный поиск координат:


КолонкаНаименования = 0;
КолонкаКоличества = 0;

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

Этот подход делает ваш парсер устойчивым к изменениям формата файла. Даже если контрагент добавит новую колонку «Артикул» в начало таблицы, ваш код автоматически найдет нужные данные по тексту заголовков.

Метод 3: Использование специализированных обработок (Прыг-Скок)

Если задача стоит остро, а времени на написание собственного кода нет, можно воспользоваться легендарными универсальными загрузками, такими как «Прыг-Скок». Проанализируем, в чем их преимущество. Эти инструменты уже содержат в себе логику очистки данных от «мусора» (пустых строк, промежуточных итогов, подписей в подвале документа) и позволяют настраивать сопоставление полей через визуальный интерфейс.

Это особенно полезно, когда нужно загрузить данные в типовые документы, такие как ПоступлениеТоваровУслуг или ЗаказПоставщику.

Метод 4: Проблема PDF-файлов и их парсинг

Часто счета приходят в формате PDF. Если это «правильный» PDF (содержащий текстовый слой, а не просто картинку), попытка конвертировать его в Excel через сторонние утилиты часто приводит к тому, что верстка «разъезжается», и данные попадают в непредсказуемые ячейки.

Рассмотрим альтернативный путь: прямой парсинг текста PDF. Для этого можно использовать внешние компоненты или консольные утилиты (например, на базе poppler или unipdf). Выясним преимущества этого метода: вы получаете поток текста с координатами, что позволяет программно вычислить принадлежность текста к той или иной колонке, основываясь на его горизонтальном смещении.

Однако, наиболее современным решением в экосистеме 1С является сервис «1С:Распознавание первичных документов». Посмотрим, как он решает проблему:

  1. Вы отправляете файл (Excel, PDF или скан) в облачный сервис 1С.
  2. Нейросеть распознает таблицу, отделяет номенклатуру от единиц измерения.
  3. Сервис автоматически сопоставляет номенклатуру поставщика с вашим справочником Номенклатура.
  4. Вам остается только проверить результат и нажать кнопку «Создать документ».

Метод 5: Создание адаптивного шаблона (Маппинг)

Если у вас десятки поставщиков с разными форматами счетов, писать отдельный код под каждого — тупиковый путь. Разберем создание системы маппинга. Создадим в базе справочник или регистр сведений «НастройкиЗагрузкиИзExcel», где для каждого контрагента будем хранить:

Проанализируем пример функции, использующей такие настройки:


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

Метод 6: Чтение через ADO для больших файлов

Если Excel-файл содержит тысячи строк, ТабличныйДокумент может работать медленно. В таких случаях рассмотрим использование COM-объекта ADODB.Connection. Это позволяет работать с листом Excel как с таблицей базы данных, используя SQL-запросы.

Посмотрим на пример инициализации соединения:


Connection = Новый COMОбъект("ADODB.Connection");
ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + ПутьКФайлу + ";Extended Properties=""Excel 12.0 Xml;HDR=YES"";";
Connection.Open(ConnectionString);

Recordset = Connection.Execute("SELECT * FROM [Лист1$]");
Пока НЕ Recordset.EOF() Цикл
    // Обработка полей через Recordset.Fields("НазваниеКолонки").Value
    Recordset.MoveNext();
КонецЦикла;

Важно: Этот метод требует наличия установленного драйвера Access Database Engine на сервере 1С и не всегда подходит для файлов с очень сложным форматированием и объединенными ячейками, так как он ожидает увидеть «чистую» таблицу.

Рекомендации по автоматизации процесса

Для достижения максимальной стабильности загрузки, мы рекомендуем придерживаться следующих правил:

  1. Валидация данных: Перед загрузкой всегда проверяйте итоговую сумму по документу. Сумма всех строк в 1С должна совпадать со значением ячейки «Итого» в файле.
  2. Регулярные выражения (RegEx): Используйте VBScript.RegExp для очистки строк от лишних символов (например, когда в ячейке с ценой написано «150.00 руб.»).
  3. Логирование: Если строка не была загружена из-за ошибки сопоставления номенклатуры, выводите пользователю список таких строк в конце обработки, а не прерывайте весь процесс.

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

← На главную