Как передать файл Excel через COM-соединение в другую базу 1С

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

При интеграции различных информационных систем на базе «1С:Предприятие» часто возникает задача программной передачи файлов. Одной из наиболее распространенных технологий для этого является COM-соединение. Однако начинающие разработчики часто сталкиваются с тем, что файл «не доходит» или не сохраняется в целевой базе, даже если код кажется логически верным. В данной статье мы подробно разберем, как правильно передать файл Excel (или любой другой двоичный файл) через COM-интерфейс, проанализируем типичные ошибки и рассмотрим альтернативные методы обеспечения надежности передачи.

Анализ проблемы: почему объект «Файл» не подходит

Рассмотрим типичную ситуацию. Программист пытается создать объект в другой базе через COM-соединение и передать туда данные. Ошибка часто заключается в использовании неправильного типа данных. Посмотрим на пример кода, который не работает:


// ОШИБОЧНЫЙ КОД
двДанные = СОМСервер.NewObject("Файл", ПолныйПутьКФайлу);
СпрУПП.Хранилище = СОМСервер.NewObject("ХранилищеЗначения", двДанные);

Давайте выясним причину неудачи. Объект Файл в системе 1С предназначен для получения метаданных о файле: его размера, расширения, даты изменения или проверки его существования. Он не содержит в себе самого содержимого файла (его байтов). Когда мы передаем такой объект в ХранилищеЗначения, мы записываем информацию о пути к файлу, но не сам файл. Чтобы передать содержимое, нам необходим объект ДвоичныеДанные.

Решение проблемы: использование Двоичных Данных

Для успешной загрузки Excel-файла в справочник «ХранилищеДополнительнойИнформации» (или аналогичный) в целевой базе, необходимо инициализировать объект ДвоичныеДанные внутри контекста COM-соединения. Разберем правильный алгоритм действий по шагам.

  1. Установим COM-соединение с базой-приемником.
  2. Создадим в целевой базе новый элемент справочника.
  3. Создадим объект ДвоичныеДанные, указав путь к файлу.
  4. Поместим эти данные в ХранилищеЗначения.
  5. Запишем элемент.

Проанализируем исправленный код, который успешно решает задачу:


СпрУПП = СОМСервер.Справочники.ХранилищеДополнительнойИнформации.СоздатьЭлемент();
СпрУПП.Объект = ДокУПП.Ссылка;
СпрУПП.ВидДанных = СОМСервер.Перечисления.ВидыДополнительнойИнформацииОбъектов.Файл;
СпрУПП.ИмяФайла = "" + КраткоеИмяФайла + ".xlsx";

// Правильное создание двоичных данных в контексте COM
двДанные = СОМСервер.NewObject("ДвоичныеДанные", ПолныйПутьКФайлу);

// Помещение данных в хранилище с использованием конструктора целевой базы
СпрУПП.Хранилище = СОМСервер.NewObject("ХранилищеЗначения", двДанные); 
СпрУПП.Записать();

Важный момент: при вызове СОМСервер.NewObject первым параметром передается имя типа в виде строки, а последующими — параметры, которые обычно указываются при использовании стандартного оператора Новый. Обратите внимание, что объект ДвоичныеДанные должен быть создан именно через СОМСервер, чтобы он был «родным» для той базы, в которую идет запись.

Особенности работы с путями к файлам

При использовании метода СОМСервер.NewObject("ДвоичныеДанные", ПолныйПутьКФайлу) мы должны учитывать физическое расположение файла. Если ваша база работает в клиент-серверном варианте, выполнение кода может происходить на сервере 1С. В этом случае путь ПолныйПутьКФайлу должен указывать на ресурс, доступный именно серверу (службе rphost), а не вашему локальному компьютеру.

Если файл находится на вашем компьютере, а COM-соединение инициируется сервером, система выдаст ошибку «Файл не найден». В таких случаях рекомендуется сначала копировать файл в общую сетевую папку или использовать передачу данных через строку.

Альтернативный метод: Передача через Base64

Если возникают сложности с правами доступа к файловой системе между серверами, проанализируем более универсальный способ — передачу файла в виде текстовой строки формата Base64. Этот метод позволяет передать содержимое файла непосредственно внутри COM-вызова без обращения к дискам в целевой базе.

Рассмотрим реализацию этого метода:


// В исходной базе преобразуем файл в строку
ФайлДвоичныеДанные = Новый ДвоичныеДанные(ПолныйПутьКФайлу);
СтрокаBase64 = Base64Строка(ФайлДвоичныеДанные);

// В целевой базе через COM восстанавливаем данные из строки
ДвоичныеДанныеДляПриемника = СОМСервер.Base64Значение(СтрокаBase64);

// Далее работаем как обычно
СпрУПП.Хранилище = СОМСервер.NewObject("ХранилищеЗначения", ДвоичныеДанныеДляПриемника);

Преимущество этого подхода в том, что передается сама информация, а не ссылка на файл. Однако помните, что преобразование в Base64 увеличивает объем передаваемых данных примерно на 33%, что может быть критично для очень больших Excel-файлов (сотни мегабайт).

Нюансы сжатия данных в ХранилищеЗначения

При записи данных в ХранилищеЗначения через COM можно использовать дополнительный параметр — СжатиеДанных. Посмотрим на пример:


Сжатие = СОМСервер.NewObject("СжатиеДанных", 9); // Максимальное сжатие
СпрУПП.Хранилище = СОМСервер.NewObject("ХранилищеЗначения", двДанные, Сжатие);

Но стоит ли это делать для Excel-файлов? Проанализируем структуру файлов .xlsx. Современные файлы Excel по сути являются zip-архивами. Повторное сжатие уже сжатых данных средствами 1С практически не уменьшит размер файла, но создаст дополнительную нагрузку на процессор при записи и последующем чтении. Поэтому для файлов .xlsx, .docx, .png или .zip сжатие в ХранилищеЗначения лучше не использовать или устанавливать уровень 0.

Резюме и рекомендации

Подведем итоги нашего исследования. Для успешной передачи файлов через COM-соединение:

  1. Всегда используйте ДвоичныеДанные, а не Файл.
  2. Создавайте объекты ДвоичныеДанные и ХранилищеЗначения через метод NewObject вашего COM-соединения.
  3. Следите за доступностью путей к файлам для серверных процессов.
  4. Для повышения надежности при работе в распределенных сетях используйте механизм Base64.
  5. Учитывайте тип передаваемого файла при выборе параметров сжатия, чтобы не тратить ресурсы сервера впустую.

Соблюдение этих правил позволит вам создавать стабильные и производительные механизмы обмена данными между базами 1С.

← На главную