Как программно прочитать файл Excel из присоединенных файлов в 1С:Бухгалтерия 3.0

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

При разработке в конфигурациях, использующих Библиотеку Стандартных Подсистем (БСП), таких как 1С:Бухгалтерия 3.0 (БП 3.0), часто возникает задача программной обработки файлов, прикрепленных пользователями к документам или справочникам. Наиболее распространенный сценарий — чтение данных из таблиц Excel (.xls, .xlsx). Начинающие разработчики часто сталкиваются с тем, что прямое обращение к таблицам базы данных не дает нужного результата или возвращает «битые» данные.

В этой статье мы подробно разберем, как правильно извлекать двоичные данные файлов, почему стандартные методы чтения могут выдавать ошибки и как обойти ограничения платформы при работе с форматом XLSX.

Анализ архитектуры хранения файлов в БСП

Прежде чем переходить к коду, проанализируем, как БСП хранит файлы. В системе существуют справочники вида ИмяМетаданныхПрисоединенныеФайлы (например, КорректировкаДолгаПрисоединенныеФайлы). Однако сами двоичные данные могут находиться в разных местах:

  1. В информационной базе: непосредственно в реквизите типа ХранилищеЗначения.
  2. В томах на диске: во внешнем сетевом хранилище, путь к которому прописан в настройках системы.
  3. В облачных хранилищах: если подключены соответствующие расширения.

Попытка прочитать данные простым запросом к реквизиту или через прямое создание объекта ДвоичныеДанные по пути к файлу часто обречена на провал, так как у сервера 1С может не быть прав на сетевой ресурс или файл может быть версионирован. Поэтому всегда следует использовать программный интерфейс (API) БСП.

Шаг 1. Получение двоичных данных через API БСП

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

Рассмотрим пример кода для получения данных файла:


// СсылкаНаФайл - это ссылка на элемент справочника присоединенных файлов
ДанныеФайла = РаботаСФайлами.ДвоичныеДанныеФайла(СсылкаНаФайл);

Если ДанныеФайла = Неопределено Тогда
    Сообщить("Не удалось получить данные файла. Возможно, он физически отсутствует или ограничен доступ.");
    Возврат;
КонецЕсли;

Важное примечание: Если вы видите, что данные начинаются с последовательности 50 4B 03 04 — не пугайтесь. Это шестнадцатеричная сигнатура формата ZIP. Поскольку современные файлы Excel (.xlsx) являются сжатыми XML-архивами, именно так они и должны выглядеть в сыром бинарном виде.

Шаг 2. Проблема чтения XLSX из потока

Многие разработчики пытаются использовать метод ТабличныйДокумент.Прочитать(), передавая в него поток данных, полученный из ДвоичныеДанные. Рассмотрим, почему это может привести к ошибке. Проанализируем синтакс-помощник для метода Прочитать объекта ТабличныйДокумент:

При чтении из Потока допустимы только следующие форматы: MXL и ODS. Форматы XLS и XLSX через поток напрямую не поддерживаются платформой на текущий момент. Если вы попытаетесь вызвать ТабДок.Прочитать(ДвоичныеДанные.ОткрытьПотокДляЧтения()) для Excel-файла, система либо выдаст ошибку, либо прочитает данные некорректно.

Шаг 3. Реализация корректного чтения через временный файл

Чтобы обойти ограничение потокового чтения, мы применим проверенный алгоритм: сохранение двоичных данных во временный файл на стороне сервера с последующим чтением его как табличного документа.

Разберем этот процесс по шагам:

  1. Получаем уникальное имя временного файла с нужным расширением.
  2. Записываем двоичные данные на диск сервера.
  3. Читаем файл в ТабличныйДокумент.
  4. Удаляем временный файл, чтобы не засорять сервер.

Посмотрим на программную реализацию этой логики:


Процедура ПрочитатьФайлЭксель(СсылкаНаФайл)
    
    // 1. Получаем данные через БСП
    ДвоичныеДанные = РаботаСФайлами.ДвоичныеДанныеФайла(СсылкаНаФайл);
    
    Если ТипЗнч(ДвоичныеДанные) <> Тип("ДвоичныеДанные") Тогда
        Возврат;
    КонецЕсли;
    
    // 2. Создаем путь к временному файлу
    // Важно указать расширение xlsx, чтобы ТабличныйДокумент понял формат
    ИмяФайла = ПолучитьИмяВременногоФайла("xlsx");
    
    // 3. Сохраняем бинарные данные на диск
    ДвоичныеДанные.Записать(ИмяФайла);
    
    // 4. Читаем данные в ТабличныйДокумент
    ТабДок = Новый ТабличныйДокумент;
    Попытка
        ТабДок.Прочитать(ИмяФайла, СпособЧтенияЗначенийТабличногоДокумента.Значение);
    Исключение
        ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Ошибка при чтении Excel: " + ОписаниеОшибки());
        УдалитьФайлы(ИмяФайла);
        Возврат;
    КонецПопытки;
    
    // 5. Обрабатываем данные таблицы
    Для НомерСтроки = 1 По ТабДок.ВысотаТаблицы Цикл
        ТекстЯчейки = ТабДок.Область(НомерСтроки, 1).Текст;
        // Здесь ваша логика обработки строк
    КонецЦикла;
    
    // 6. Обязательная очистка
    УдалитьФайлы(ИмяФайла);
    
КонецПроцедуры

Особенности работы при включенном версионировании

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

Выясним, как работает БСП: основная ссылка в справочнике файлов — это лишь «заголовок». Сами данные и актуальное состояние хранятся в связанном справочнике ...ПрисоединенныеФайлыВерсии. Чтобы всегда получать актуальный файл, рекомендуется использовать функцию РаботаСФайлами.ДанныеФайла(СсылкаНаФайл). Она возвращает структуру, в которой в реквизите СсылкаНаВерсию указана текущая активная версия файла.

Оптимизация чтения больших файлов

Если файл Excel содержит десятки тысяч строк, объект ТабличныйДокумент может потреблять значительный объем оперативной памяти сервера (иногда в 5-10 раз больше размера самого файла). В таких случаях проанализируем альтернативный подход:

Формат .xlsx — это ZIP-архив. Вы можете использовать объект ЧтениеZipФайла, извлечь из него worksheets/sheet1.xml и прочитать его с помощью объекта ЧтениеXML. Это «потоковый» метод, который практически не потребляет память и работает значительно быстрее ТабличногоДокумента, хотя и требует написания более сложного парсера XML-структуры.

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

Часто код чтения файлов падает с ошибкой или возвращает Неопределено из-за ограничений прав доступа (RLS). Если ваша задача выполняется в фоновом задании или при проведении документа, убедитесь, что чтение данных выполняется в привилегированном режиме. Рассмотрим правильное обрамление вызова:


УстановитьПривилегированныйРежим(Истина);
Данные = РаботаСФайлами.ДвоичныеДанныеФайла(СсылкаНаФайл);
УстановитьПривилегированныйРежим(Ложь);

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

Таким образом, мы выяснили, что ключ к успешному чтению Excel-файлов в БП 3.0 лежит в использовании штатных функций БСП для извлечения данных и временных файлов для обхода ограничений платформы по работе с потоками данных в формате XLSX.

← На главную