Разработка в среде обычных форм (толстый клиент) имеет свои архитектурные особенности, особенно когда речь заходит о взаимодействии клиента и сервера. В управляемых формах мы привыкли использовать асинхронные методы вроде НачатьПомещениеФайлов(), однако в обычных формах (ОФ) такие механизмы работают иначе или требуют иного подхода. В этой статье мы подробно разберем, как передать файл с локального компьютера пользователя на сервер 1С, если вы работаете с классическим интерфейсом.
Для начала проанализируем ситуацию. В обычном приложении 1С код модуля формы по умолчанию выполняется на стороне клиента. В отличие от управляемого приложения, здесь нет явных директив &НаСервере или &НаКлиенте. Чтобы код действительно выполнился на стороне сервера (что критично для записи файла в серверную папку), нам необходимо использовать специальные механизмы платформы.
Многие начинающие разработчики полагают, что в толстом клиенте "сервер" находится там же, где и "клиент". Это верно только для файловых баз. В клиент-серверном варианте (SQL) физический сервер приложений может находиться на другом компьютере, и прямой доступ к его диску через обычный путь C:\Temp с клиента невозможен.
Это наиболее "правильный" с точки зрения платформы способ, который работает в версиях 8.2 и 8.3. Мы используем временное хранилище как промежуточный буфер.
Рассмотрим пошагово, как это реализовать:
ПоместитьФайл(). Он открывает диалог выбора файла и загружает его во временное хранилище 1С.Посмотрим на пример кода в модуле обычной формы:
Процедура КнопкаЗагрузитьНажатие(Элемент)
Перем ВыбранныйПуть;
АдресХранилища = "";
// В обычных формах метод ПоместитьФайл работает синхронно
// Важно передать УникальныйИдентификатор формы, чтобы данные не удалились сразу
Если ПоместитьФайл(АдресХранилища, "", ВыбранныйПуть, Истина, ЭтаФорма.УникальныйИдентификатор) Тогда
// Теперь вызываем серверный метод для сохранения
РаботаСФайламиСервер.СохранитьФайлИзХранилища(АдресХранилища, "имя_файла.txt");
Предупреждение("Файл успешно загружен на сервер!");
КонецЕсли;
КонецПроцедуры
Важный нюанс: Чтобы данные во временном хранилище "жили" достаточно долго, в качестве параметра УникальныйИдентификатор нужно передавать идентификатор текущей формы. Это гарантирует, что файл будет доступен до тех пор, пока форма не будет закрыта.
Если по каким-то причинам вы не хотите использовать временное хранилище, можно воспользоваться объектом ДвоичныеДанные. Этот метод прост, но имеет ограничение: он потребляет значительный объем оперативной памяти, так как файл полностью считывается в переменную.
Разберем этот способ:
ДвоичныеДанные, указывая путь к локальному файлу.Записать() объекта ДвоичныеДанные.Пример реализации:
// Код в модуле формы (Клиент)
ПутьКФайлу = "C:\MyFiles\report.pdf";
ДанныеФайла = Новый ДвоичныеДанные(ПутьКФайлу);
// Вызов серверного общего модуля
РаботаСФайламиСервер.ЗаписатьФайлНаСервер(ДанныеФайла, "report_server.pdf");
Выясним причину, по которой иногда выбирают этот путь. Если сервер 1С и клиентская машина находятся в одной сети и у пользователя есть права на сетевую папку сервера, можно использовать FileSystemObject. Это позволяет копировать файлы напрямую, минуя сервер приложений 1С.
FSO = Новый COMОбъект("Scripting.FileSystemObject");
Попытка
FSO.CopyFile("C:\local\file.txt", "\\ServerName\SharedFolder\file.txt", Истина);
Исключение
Сообщить("Ошибка копирования: " + ОписаниеОшибки());
КонецПопытки;
Внимание: Этот метод менее надежен, так как сильно зависит от настроек прав доступа Windows и сетевой связности, которые часто блокируются политиками безопасности.
Чтобы методы, описанные выше, действительно сработали "на сервере", необходимо правильно настроить Общий модуль. Проанализируем необходимые свойства модуля:
Пример серверного кода в общем модуле РаботаСФайламиСервер:
Процедура СохранитьФайлИзХранилища(АдресХранилища, ИмяФайла) Экспорт
// Получаем данные из временного хранилища
Данные = ПолучитьИзВременногоХранилища(АдресХранилища);
// Формируем путь на диске СЕРВЕРА
ПутьНаСервере = "D:\Storage\" + ИмяФайла;
// Записываем файл на диск
Данные.Записать(ПутьНаСервере);
КонецПроцедуры
Рассмотрим типичные ошибки при реализации загрузки файлов:
1. Права службы 1С: При выполнении кода на сервере, запись на диск происходит от имени учетной записи, под которой запущена служба 1C:Enterprise 8.3 Server Agent (обычно это USR1CV8). У этой учетной записи должны быть права на запись в целевую папку на сервере.
2. Локальные пути: Помните, что путь C:\Temp в серверном коде — это папка на системном диске сервера, а не на компьютере пользователя. Всегда проверяйте существование каталогов перед записью.
3. Файловый режим: Если ваша база работает в файловом режиме, то разделение на клиент и сервер чисто номинальное. Файл будет сохранен на том же компьютере, где запущен клиент, просто в указанную папку.
Подводя итог, можно сказать, что хотя в обычных формах нет современных асинхронных методов "из коробки", связка синхронного ПоместитьФайл() и серверного общего модуля полностью решает задачу передачи данных на сервер.