При работе в клиент-серверном варианте (SQL) разработчики часто сталкиваются с проблемой: привычный код выгрузки в DBF, который отлично работал в файловой базе, перестает функционировать. Основная причина заключается в том, что код, выполняющийся на сервере, не имеет прямого доступа к файловой системе клиентского компьютера. В этой статье мы подробно разберем, как правильно организовать выгрузку данных, используя объект XBase и механизм временного хранилища.
В файловой базе 1С клиент и «сервер» — это один и тот же процесс, имеющий доступ к одним и тем же дискам. В клиент-серверном варианте база данных находится на SQL-сервере, а программный код выполняется на сервере приложений 1С. Когда вы указываете путь типа C:\MyFiles\export.dbf, сервер ищет этот путь на своем локальном диске, а не на диске пользователя. Чтобы передать файл пользователю, нам нужно сначала создать его на стороне сервера, а затем «перекачать» на клиент.
Для реализации корректной выгрузки мы будем использовать следующую последовательность действий:
XBase, создаем структуру колонок и наполняем файл данными.ДвоичныеДанные и помещаем их во ВременноеХранилище.Рассмотрим серверную функцию, которая выполняет основную работу. Мы будем использовать объект XBase для работы с форматом DBF. Обратите внимание на использование метода ПолучитьИмяВременногоФайла, который гарантирует уникальность имени файла на сервере.
&НаСервере
Функция СформироватьDBFНаСервере()
// 1. Подготовка временного пути на сервере
ИмяФайлаСервер = ПолучитьИмяВременногоФайла("dbf");
// 2. Инициализация объекта XBase
ФайлДБФ = Новый XBase;
ФайлДБФ.Поля.Добавить("ID", "N", 10);
ФайлДБФ.Поля.Добавить("NAME", "S", 100);
ФайлДБФ.Поля.Добавить("PRICE", "N", 15, 2);
// Устанавливаем кодировку (обычно OEM для старых систем или ANSI для Windows)
ФайлДБФ.Кодировка = КодировкаXBase.ANSI;
// Создаем файл по временному пути
ФайлДБФ.СоздатьФайл(ИмяФайлаСервер);
// 3. Наполнение данными (пример на основе запроса)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Код КАК Код,
| Номенклатура.Наименование КАК Наименование,
| 100 КАК Цена"; // Пример статической цены
Результат = Запрос.Выполнить().Выбрать();
Пока Результат.Следующий() Цикл
ФайлДБФ.Добавить();
ФайлДБФ.ID = Результат.Код;
ФайлДБФ.NAME = Результат.Наименование;
ФайлДБФ.PRICE = Результат.Цена;
ФайлДБФ.Записать();
КонецЦикла;
// 4. Обязательно закрываем файл
ФайлДБФ.ЗакрытьФайл();
// 5. Помещаем файл во временное хранилище
// Читаем файл с диска сервера в двоичные данные
ДвоичныеДанныеФайла = Новый ДвоичныеДанные(ИмяФайлаСервер);
АдресХранилища = ПоместитьВоВременноеХранилище(ДвоичныеДанныеФайла, ЭтаФорма.УникальныйИдентификатор);
// Удаляем временный файл с диска сервера, так как он уже в памяти (хранилище)
УдалитьФайлы(ИмяФайлаСервер);
Возврат АдресХранилища;
КонецФункции
Теперь разберем клиентскую часть. Нам нужно вызвать серверную функцию, получить адрес временного хранилища и предложить пользователю сохранить файл. В современных версиях 1С для этого рекомендуется использовать асинхронные методы, чтобы не блокировать интерфейс программы.
&НаКлиенте
Процедура ВыгрузитьДанные(Команда)
// Вызываем серверный метод
АдресФайла = СформироватьDBFНаСервере();
// Параметры сохранения
ИмяФайлаДляКлиента = "Выгрузка_Номенклатуры.dbf";
// Используем стандартный диалог для сохранения файла
// В управляемом приложении 8.3 рекомендуется ПолучитьФайл
ПолучитьФайл(АдресФайла, ИмяФайлаДляКлиента, Истина);
КонецПроцедуры
Проанализируем технические ограничения, которые могут привести к ошибкам при выгрузке из SQL-баз:
НаименованиеНоменклатуры, при добавлении в XBase.Поля его имя будет обрезано, что может вызвать путаницу.КодировкаXBase.OEM (DOS-кодировка). Для Excel и современных Windows-приложений лучше подходит КодировкаXBase.ANSI.Строка без ограничения). В DBF максимальная длина строкового поля составляет 254 символа. Если ваши данные длиннее, они будут обрезаны автоматически.usr1cv8) должна иметь права на запись в папку временных файлов сервера. Метод ПолучитьИмяВременногоФайла() обычно возвращает путь к стандартной временной папке, на которую у службы права есть.Если ваша конфигурация работает в веб-клиенте, синхронный метод ПолучитьФайл может не сработать. В таком случае рекомендуется использовать метод НачатьПолучениеФайлаССервера. Рассмотрим пример:
&НаКлиенте
Процедура ВыгрузитьАсинхронно(Команда)
АдресФайла = СформироватьDBFНаСервере();
ОписаниеЗавершения = Новый ОписаниеОповещения("ЗавершитьСохранениеФайла", ЭтотОбъект);
ПараметрыПолучения = Новый ПараметрыПолученияФайлаССервера;
ПараметрыПолучения.ЗаголовокДиалога = "Выберите путь для сохранения DBF";
НачатьПолучениеФайлаССервера(ОписаниеЗавершения, АдресФайла, "export.dbf", ПараметрыПолучения);
КонецПроцедуры
&НаКлиенте
Процедура ЗавершитьСохранениеФайла(Результат, ДополнительныеПараметры) Экспорт
Если Результат <> Неопределено Тогда
ПоказатьОповещениеПользователя("Успех", , "Файл успешно сохранен!");
КонецЕсли;
КонецПроцедуры
Мы рассмотрели универсальный и безопасный способ выгрузки данных в DBF из SQL-базы 1С. Главное правило: всегда разделяйте логику формирования файла и логику его сохранения. Формирование должно происходить на сервере во временную папку, а сохранение — на клиенте через временное хранилище. Такой подход гарантирует стабильную работу обработки независимо от того, где физически находится сервер 1С и какие права доступа у пользователя к сетевым ресурсам.