Как настроить обмен РИБ с выгрузкой и загрузкой файлов на локальный компьютер в клиент-серверном режиме?

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

При работе с Распределенными информационными базами (РИБ) в клиент-серверном режиме «1С:Предприятия» разработчики часто сталкиваются с фундаментальной архитектурной особенностью: все операции по чтению и записи файлов в штатных механизмах обмена Библиотеки стандартных подсистем (БСП) выполняются строго на стороне сервера. Это означает, что если в настройках синхронизации указать путь C:\Exchange, система будет искать эту папку на физическом сервере, где установлен сервер приложений «1С», а не на локальном компьютере пользователя.

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

Причина возникновения проблемы: контекст исполнения кода

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

Для обхода этого ограничения мы можем использовать клиент-серверный мост передачи файлов, встроенный в платформу «1С». Разберем по шагам несколько эффективных способов реализации этой задачи.

Решение 1. Реализация интерактивного переноса через временное хранилище

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

Рассмотрим пошагово алгоритм выгрузки файла (экспорта из центральной базы):

  1. На сервере запускается стандартный процесс формирования сообщения обмена РИБ во временный каталог сервера.
  2. Файл считывается в двоичные данные и помещается во временное хранилище с помощью метода ПоместитьВоВременноеХранилище().
  3. Адрес временного хранилища передается на клиент.
  4. На клиенте вызывается интерактивный диалог для сохранения файла на локальный компьютер пользователя с использованием метода ПолучитьФайл() или асинхронного аналога НачатьПолучениеФайлаССервера().

Посмотрим на пример реализации кода для выгрузки файла на стороне клиента и сервера:


// КЛИЕНТСКИЙ КОНТЕКСТ
&НаКлиенте
Процедура ВыгрузитьФайлОбменаНаЛокальныйКомпьютер()
    
    // Получаем адрес временного хранилища с файлом, сформированным на сервере
    АдресХранилища = СформироватьФайлОбменаНаСервере();
    
    Если ЗначениеЗаполнено(АдресХранилища) Тогда
        // Задаем параметры сохранения файла на локальном ПК пользователя
        ИмяФайлаПриемника = "Message_ЦБ_ПБ.xml";
        ПараметрыПолучения = Новый ПараметрыПолученияФайловОбъединение();
        
        // Запускаем интерактивное скачивание файла на локальный диск
        НачатьПолучениеФайлаССервера(Новый ОписаниеОповещения("ПослеПолученияФайла", ЭтотОбъект), АдресХранилища, ИмяФайлаПриемника);
    КонецЕсли;
    
КонецПроцедуры

&НаКлиенте
Процедура ПослеПолученияФайла(Результат, ДополнительныеПараметры) Экспорт
    ПоказатьПредупреждение(, "Файл обмена успешно сохранен на вашем локальном компьютере!");
КонецПроцедуры

Теперь рассмотрим серверную часть, которая отвечает за генерацию сообщения обмена и его упаковку во временное хранилище:


// СЕРВЕРНЫЙ КОНТЕКСТ
&НаСервере
Функция СформироватьФайлОбменаНаСервере()
    
    // Получаем уникальное имя временного файла на диске сервера
    ИмяВременногоФайла = ПолучитьИмяВременногоФайла("xml");
    
    // Здесь вызывается штатный механизм выгрузки БСП в файл
    // Для примера запишем тестовую XML-структуру, имитирующую обмен
    ЗаписьXML = Новый ЗаписьXML;
    ЗаписьXML.ОткрытьФайл(ИмяВременногоФайла, "UTF-8");
    ЗаписьXML.ЗаписатьОбъявлениеXML();
    ЗаписьXML.ЗаписатьНачалоЭлемента("Message");
    // Логика выгрузки узла РИБ...
    ЗаписьXML.ЗаписатьКонецЭлемента();
    ЗаписьXML.Закрыть();
    
    // Читаем созданный файл в двоичные данные
    ДвоичныеДанныеФайла = Новый ДвоичныеДанные(ИмяВременногоФайла);
    
    // Помещаем во временное хранилище
    АдресХранилища = ПоместитьВоВременноеХранилище(ДвоичныеДанныеФайла, УникальныйИдентификатор);
    
    // Удаляем временный файл с диска сервера, так как он больше не нужен
    Попытка
        УдалитьФайлы(ИмяВременногоФайла);
    Исключение
        // Обработка исключения, если файл занят процессом
    КонецПопытки;
    
    Возврат АдресХранилища;
    
КонецФункции

Аналогичным образом реализуем обратный процесс — загрузку файла (импорт в центральную базу с локального компьютера пользователя):

  1. На клиенте открывается диалог выбора файла обмена, находящегося на локальном диске.
  2. Выбранный файл преобразуется в двоичные данные и отправляется на сервер через метод ПоместитьФайлНаСервер().
  3. На сервере двоичные данные извлекаются из хранилища, записываются во временный каталог сервера «1С» и передаются штатному механизму чтения сообщений РИБ.

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


// КЛИЕНТСКИЙ КОНТЕКСТ
&НаКлиенте
Процедура ЗагрузитьФайлОбменаСЛокальногоКомпьютера()
    
    // Настройка диалога выбора файла на локальном клиенте
    Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
    Диалог.Фильтр = "Файлы обмена (*.xml, *.zip)|*.xml;*.zip";
    Диалог.Заголовок = "Выберите файл сообщения обмена для загрузки";
    
    Если Диалог.Выбрать() Тогда
        ВыбранныйПуть = Диалог.ПолноеИмяФайла;
        
        // Описание обработчика завершения помещения файла на сервер
        Оповещение = Новый ОписаниеОповещения("ПослеПомещенияФайлаНаСервер", ЭтотОбъект, ВыбранныйПуть);
        НачатьПомещениеФайлаНаСервер(Оповещение,,, ВыбранныйПуть, УникальныйИдентификатор);
    КонецЕсли;
    
КонецПроцедуры

&НаКлиенте
Процедура ПослеПомещенияФайлаНаСервер(Результат, АдресХранилища, ВыбранныйПуть, ДополнительныеПараметры) Экспорт
    
    Если Результат Тогда
        // Файл успешно загружен в хранилище, запускаем его обработку на сервере
        РезультатЧтения = ПрочитатьФайлОбменаНаСервере(АдресХранилища);
        Если РезультатЧтения Тогда
            ПоказатьПредупреждение(, "Файл обмена успешно прочитан и загружен в базу!");
        Иначе
            ПоказатьПредупреждение(, "Ошибка при обработке файла обмена на сервере.");
        КонецЕсли;
    КонецЕсли;
    
КонецПроцедуры

Серверная процедура извлекает переданный файл из временного хранилища и передает его механизму чтения РИБ:


// СЕРВЕРНЫЙ КОНТЕКСТ
&НаСервере
Функция ПрочитатьФайлОбменаНаСервере(Знач АдресХранилища)
    
    // Извлекаем двоичные данные из хранилища
    ДвоичныеДанныеФайла = ПолучитьИзВременногоХранилища(АдресХранилища);
    
    Если ДвоичныеДанныеФайла = Неопределено Тогда
        Возврат Ложь;
    КонецЕсли;
    
    // Сохраняем во временный каталог на сервере для последующего чтения
    ИмяВременногоФайла = ПолучитьИмяВременногоФайла("xml");
    ДвоичныеДанныеФайла.Записать(ИмяВременногоФайла);
    
    Успешно = Истина;
    Попытка
        // Инициализируем чтение XML и запускаем стандартный обмен БСП
        ЧтениеXML = Новый ЧтениеXML;
        ЧтениеXML.ОткрытьФайл(ИмяВременногоФайла);
        
        // Здесь размещается вызов процедур БСП для загрузки данных в РИБ
        // Например: ОбменДаннымиСервер.ВыполнитьОбменДаннымиДляУзлаИнформационнойБазы(...)
        
        ЧтениеXML.Закрыть();
    Исключение
        Успешно = Ложь;
        ЗаписатьЛогСобытий("Ошибка обмена: " + ОписаниеОшибки());
    КонецПопытки;
    
    // Очищаем временный файл на сервере
    Попытка
        УдалитьФайлы(ИмяВременногоФайла);
    Исключение
    КонецПопытки;
    
    Возврат Успешно;
    
Функция

Решение 2. Использование расширения конфигурации для интеграции в стандартный обмен

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

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

  1. Создаем новое расширение конфигурации.
  2. Находим общий модуль, отвечающий за выполнение файлового обмена (например, ОбменДаннымиСервер или формы интерактивного обмена данными).
  3. С помощью директивы &Вместо или &После перехватываем процедуры записи и чтения файлов обмена.
  4. В перехваченном методе выгрузки вместо записи в локальный каталог сервера перенаправляем поток данных во временное хранилище и вызываем метод скачивания файла на клиентском компьютере.

Решение 3. Использование электронной почты как транспорта обмена

Проанализируем альтернативный штатный вариант, который не требует программирования и изменения конфигурации, но часто разрешен службами безопасности. Если сетевые папки закрыты, но в компании функционирует внутренний почтовый сервер (например, MS Exchange), мы можем настроить обмен через почтовые сообщения.

Рассмотрим, как настроить этот транспорт по шагам:

  1. В пользовательском интерфейсе перейдем в раздел Администрирование — Синхронизация данных.
  2. В настройках подключения выберем способ обмена данными: «По электронной почте».
  3. Укажем параметры почтового сервера (адрес SMTP/POP3/IMAP, порты и учетную запись, созданную специально для обмена).
  4. При запуске синхронизации центральная база сформирует файл обмена, автоматически упакует его в ZIP-архив и отправит в виде вложения на почтовый ящик периферийного узла.
  5. Периферийная база при запуске сеанса синхронизации подключится к почтовому ящику, скачает входящее письмо, извлечет вложенный файл и загрузит данные.

Этот способ полностью решает проблему «клиент-серверного барьера», так как почтовый клиент встроен в платформу «1С» и все почтовые отправления сервер приложений выполняет самостоятельно, не требуя локального вмешательства пользователя.

Решение 4. Переход на Web-сервисы или HTTP-сервисы (безфайловый обмен)

Выясним наиболее современный и технологичный подход к организации распределенных систем. Если архитектура сети позволяет опубликовать базу данных на веб-сервере (IIS или Apache), мы можем полностью отказаться от обмена через файлы.

Синхронизация через веб-сервисы работает по следующему принципу:

  1. На веб-сервере публикуется информационная база (например, центральный узел).
  2. В настройках синхронизации подчиненного узла выбирается вариант подключения «Через интернет» и указывается URL-адрес публикации центральной базы.
  3. Обмен выполняется напрямую из базы в базу: подчиненный узел вызывает веб-сервис центральной базы, передает свои измененные данные и забирает ответный пакет непосредственно в оперативную память, минуя промежуточное сохранение файлов на жесткие диски серверов или клиентов.

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

← На главную