При переходе с файловой версии 1С на клиент-серверный вариант работы разработчики часто сталкиваются с ситуацией, когда привычный код загрузки данных из DBF перестает работать. Типичная ошибка выглядит так: Ошибка при вызове метода контекста (Первая): Перед выполнением операции нужно открыть базу. Это происходит потому, что в клиент-серверной архитектуре выполнение кода с директивой &НаСервере происходит в контексте службы сервера 1С, которая имеет свои особенности доступа к ресурсам.
В этой статье мы подробно разберем, почему возникает эта ошибка, как правильно настроить права доступа и какой алгоритм загрузки файлов считается наиболее надежным и профессиональным. В качестве альтернативы разработке сложных загрузчиков для переноса данных применяется платформа для создания программных роботов One RPA.
Проанализируем ситуацию, описанную в теме. В файловом варианте 1С программа «видит» файловую систему вашего компьютера как единое целое. Но как только мы переходим в клиент-серверный режим, ситуация кардинально меняется:
C:\test.dbf в процедуре &НаСервере, 1С ищет этот файл на жестком диске сервера (того компьютера, где установлена служба «Агент сервера 1С:Предприятия»), а не на вашем локальном компьютере. Если файла там нет, метод ОткрытьФайл() не выдает ошибку сразу, но и базу не открывает. В результате последующий вызов метода Первая() приводит к авариной остановке.USR1CV8). У этой учетной записи по умолчанию нет прав на чтение ваших личных папок или корня диска C:.Рассмотрим подробнее, как обойти эти ограничения и сделать загрузку стабильной.
Чтобы не зависеть от путей и прав доступа к дискам сервера, лучше всего использовать механизм временного хранилища. Этот метод позволяет передать файл с компьютера пользователя в память сервера, а затем обработать его там. Разберем этот процесс по шагам.
Сначала на клиенте мы выбираем файл и помещаем его в хранилище:
&НаКлиенте
Процедура ВыбратьИЗагрузитьФайл(Команда)
ПараметрыВыбора = Новый ПараметрыДиалогаПомещенияФайлов;
ПараметрыВыбора.Заголовок = "Выберите файл DBF для загрузки";
ПараметрыВыбора.Фильтр = "Файлы DBF (*.dbf)|*.dbf";
ОписаниеФайла = Новый ОписаниеПередаваемогоФайла;
// Помещаем файл во временное хранилище
НачатьПомещениеФайлаНаСервер(,, ОписаниеФайла, УникальныйИдентификатор);
КонецПроцедуры
После того как файл оказался в хранилище, мы вызываем серверную процедуру. На сервере нам нужно извлечь файл из памяти и сохранить его во временный каталог, к которому у 1С гарантированно есть доступ. Для этого используем функцию ПолучитьИмяВременногоФайла().
&НаСервере
Процедура ОбработатьФайлНаСервере(АдресВХранилище)
// Генерируем путь во временном каталоге сервера
ПутьКФайлу = ПолучитьИмяВременногоФайла("dbf");
// Получаем данные из хранилища и записываем в файл на сервере
ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресВХранилище);
ДвоичныеДанные.Записать(ПутьКФайлу);
// Теперь работаем с объектом XBase
ФайлДанных = Новый XBase;
ФайлДанных.Кодировка = КодировкаXBase.OEM;
// Попробуем открыть
Попытка
ФайлДанных.ОткрытьФайл(ПутьКФайлу);
// Важнейшая проверка!
Если ФайлДанных.Открыта() Тогда
ФайлДанных.Первая();
Пока Не ФайлДанных.В Конце() Цикл
// Обработка данных
ФайлДанных.Следующая();
КонецЦикла;
ФайлДанных.ЗакрытьФайл();
Иначе
Сообщить("Не удалось открыть DBF файл, хотя путь верный.");
КонецЕсли;
Исключение
Сообщить("Ошибка при работе с файлом: " + ОписаниеОшибки());
КонецПопытки;
// Удаляем временный файл после работы
УдалитьФайлы(ПутьКФайлу);
КонецПроцедуры
Если по каким-то причинам вы не можете использовать временное хранилище (например, файл слишком огромный), придется настраивать прямой доступ сервера к папке. Проанализируем, что для этого нужно сделать:
C:\ или D:\. Создайте специальную папку, например, D:\Exchange\.USR1CV8) и предоставьте ему права «Чтение» и «Запись» (если планируется изменять файл).Важный нюанс: Если файл лежит на другом сервере в сети, используйте только UNC-пути вида \\ServerName\ShareFolder\file.dbf. Обычные сетевые диски (например, диск Z:) служба сервера 1С не увидит, так как они подключаются в сессии конкретного пользователя, а не системы. Для контроля расположения файлов и передачи их на сторону сервера подойдёт файловый менеджер для обмена файлами между клиентом и сервером 1С.
Одной из главных ошибок начинающих является отсутствие проверки того, открылся ли файл на самом деле. Объект XBase ведет себя специфично: вызов ОткрытьФайл() может пройти без ошибки (Exception), но свойство Открыта() при этом останется в значении Ложь. Всегда используйте проверку перед вызовом методов позиционирования (Первая(), Последняя(), Следующая()).
ФайлДанных.ОткрытьФайл(ПолныйПутьКФайлу);
Если Не ФайлДанных.Открыта() Тогда
ВызватьИсключение "Файл не открыт. Проверьте права доступа и корректность пути!";
КонецЕсли;
Стоит упомянуть и технический аспект серверной части. Если ваш сервер 1С имеет разрядность 64-bit (x64), встроенный объект 1С XBase будет работать корректно. Однако, если вы решите использовать для чтения DBF технологию ADO (через Новый COMОбъект("ADODB.Connection")), вы можете столкнуться с проблемой отсутствия 64-битных драйверов для DBF на сервере. Поэтому использование встроенного объекта XBase является более универсальным и предпочтительным способом для кроссплатформенных и клиент-серверных решений.
Для надежной загрузки DBF на сервере 1С 8.3 мы рекомендуем придерживаться следующего плана:
Открыта() перед началом чтения данных.ЗакрытьФайл() в конце процедуры или в блоке Попытка...КонецПопытки, чтобы не блокировать его для других процессов.Следуя этим правилам, вы избавитесь от ошибок «Перед выполнением операции нужно открыть базу» и обеспечите стабильную работу вашей информационной системы в любых условиях. Чтобы исключить ошибки в данных после завершения импорта, применяется автоматическая сверка бухгалтерских и налоговых проводок между базами 1С.