При работе в клиент-серверном варианте платформы «1С:Предприятие 8» разработчики часто сталкиваются со следующей проблемой: при выполнении серверного кода возникает необходимость интерактивно запросить у пользователя файл (например, внешний XML-файл для загрузки данных). Попытка вызвать диалог выбора файла напрямую из серверного модуля приводит к ошибке «Метод объекта не обнаружен» или «Операция недоступна на сервере».
В этой статье мы подробно разберем, почему возникает данная ошибка, изучим архитектурные ограничения платформы и рассмотрим два практических способа решения этой задачи: стандартный механизм параметров в «Конвертации данных 2.1» и правильный перенос логики выбора файлов на клиентскую сторону с передачей данных на сервер через временное хранилище.
Для начала проанализируем архитектуру управляемого приложения. В клиент-серверной модели процессы четко разграничены:
ДиалогВыбораФайла.rphost) выполняет тяжелые вычисления, работает с базой данных и бизнес-логикой. Сервер физически «не видит» экран пользователя и его локальные диски (например, диск C:\ на клиентском компьютере).Связь между ними всегда односторонняя: только клиент может вызвать сервер. Когда управление передано серверу (например, внутри обработчика ПередОбработкой в правилах выгрузки данных), сервер должен полностью завершить свою работу и вернуть результат клиенту. Напрямую «прервать» серверный код, чтобы показать пользователю окно выбора файла, а затем продолжить выполнение серверной процедуры, невозможно.
Любые попытки вызвать клиентский общий модуль или напрямую создать объект ДиалогВыбораФайла на сервере неизбежно приведут к краху системы. Поэтому нам необходимо перестроить архитектуру процесса.
---
Если вы столкнулись с этой проблемой при настройке правил обмена в конфигурации «Конвертация данных 2.1» (КД), вам не нужно писать сложные «костыли» с обработчиками ожидания. В КД предусмотрен готовый штатный механизм, позволяющий запросить у пользователя любые данные перед началом выгрузки.
Разберем по шагам, как это настроить:
ИмяФайлаИсточника).Строка.Как это работает в режиме «1С:Предприятие» при использовании обработки УниверсальныйОбменДаннымиXML:
Перед обработкой правил выгрузки данных вы можете легко обратиться к уже выбранному значению:
// Получаем путь к файлу, выбранному пользователем на клиенте
ПолноеИмяФайла = Параметры.ИмяФайлаИсточника;
Если Не ЗначениеЗаполнено(ПолноеИмяФайла) Тогда
Отказ = Истина;
Возврат;
КонецЕсли;
// Дальнейший разбор файла на сервере
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ПолноеИмяФайла);
// ... код обработки данных
Этот способ является наиболее безопасным и простым, так как полностью опирается на стандартный функционал обмена данными.
---
Если вы разрабатываете собственную обработку обмена, вам необходимо полностью разделить процедуру на два этапа. Сначала на клиенте выполняется интерактивный выбор файла и его отправка на сервер во временное хранилище. Затем вызывается серверная процедура, которая считывает данные из хранилища.
Рассмотрим современный асинхронный подход, соответствующий стандартам платформы 1С версии 8.3.15 и выше (без использования устаревших модальных окон).
Ниже представлен пример реализации в модуле формы вашей обработки:
&НаКлиенте
Процедура ВыгрузитьДанные(Команда)
// Настраиваем параметры диалога выбора файла
ПараметрыДиалога = Новый ПараметрыДиалогаВыбораФайла;
ПараметрыДиалога.Фильтр = "Файлы данных (*.xml)|*.xml";
ПараметрыДиалога.МножественныйВыбор = Ложь;
ПараметрыДиалога.Заголовок = "Выберите XML-файл для импорта";
// Описываем оповещение, которое сработает после того, как файл будет выбран и загружен
ОписаниеОповещения = Новый ОписаниеОповещения("ВыгрузитьДанныеПослеЗагрузкиФайла", ЭтотОбъект);
// Используем современный немодальный метод платформы 8.3.15+
// Метод сам откроет диалог, а затем автоматически поместит выбранный файл в хранилище на сервере
НачатьПомещениеФайлаНаСервер(ОписаниеОповещения, , , , ПараметрыДиалога, УникальныйИдентификатор);
КонецПроцедуры
&НаКлиенте
Процедура ВыгрузитьДанныеПослеЗагрузкиФайла(РезультатПомещения, ДополнительныеПараметры) Экспорт
// Проверяем, выбрал ли пользователь файл или закрыл диалог
Если РезультатПомещения = Неопределено Тогда
Возврат;
КонецЕсли;
// Файл успешно помещен во временное хранилище.
// Передаем адрес хранилища в серверную процедуру выгрузки
АдресФайлаВХранилище = РезультатПомещения.Адрес;
ВыгрузитьДанныеНаСервере(АдресФайлаВХранилище);
КонецПроцедуры
Теперь рассмотрим, как должна выглядеть серверная часть, принимающая файл из временного хранилища:
&НаСервере
Процедура ВыгрузитьДанныеНаСервере(АдресФайлаВХранилище)
// Извлекаем двоичные данные файла из временного хранилища
ДвоичныеДанныеФайла = ПолучитьИзВременногоХранилища(АдресФайлаВХранилище);
// Поскольку ЧтениеXML требует физический путь к файлу или поток,
// мы можем сохранить двоичные данные во временный файл на стороне сервера
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("xml");
ДвоичныеДанныеФайла.Записать(ИмяВременногоФайла);
// Читаем файл на сервере
Парсер = Новый ЧтениеXML;
Попытка
Парсер.ОткрытьФайл(ИмяВременногоФайла);
// Выполняем чтение и обработку XML-структуры
// ... код вашей логики обмена
Парсер.Закрыть();
Исключение
Парсер.Закрыть();
ВызватьИсключение КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
КонецПопытки;
// Обязательно удаляем временный файл на сервере после завершения работы
УдалитьФайлы(ИмяВременногоФайла);
КонецПроцедуры
Важная деталь: обратите внимание на последний параметр метода НачатьПомещениеФайлаНаСервер, в который мы передали УникальныйИдентификатор нашей управляемой формы. Это гарантирует, что временный файл в хранилище будет «жить» на сервере до тех пор, пока пользователь не закроет форму обработки. Если не передать этот идентификатор, данные могут удалиться сборщиком мусора платформы до начала выполнения серверной процедуры.
Если ваша конфигурация разработана с использованием Библиотеки стандартных подсистем (БСП), рекомендуется использовать функции из общего модуля ФайловаяСистемаКлиент, такие как ПоместитьФайлНаСервер, которые скрывают рутинную работу по созданию описания оповещений и гарантируют кроссплатформенную работу (включая веб-клиент).
Применяя предложенные подходы, вы сможете легко обойти ограничения клиент-серверной архитектуры 1С и обеспечить стабильную работу вашей системы импорта данных в любых режимах работы платформы.