В практике разработки на платформе 1С:Предприятие 8 часто встречается ситуация: программист пишет код для выгрузки данных, выбирает путь к файлу на своем компьютере, но при попытке записи система выдает ошибку «Каталог не обнаружен». Особенно остро эта проблема проявляется в клиент-серверных версиях программы. Давайте подробно разберем, почему так происходит, и как правильно организовать работу с файловой системой, чтобы избежать подобных ошибок.
Разберем ситуацию, описанную в теме. Пользователь работает в серверной базе, выбирает файл на диске X: и вызывает процедуру записи. В ответ 1С выдает сообщение: гФайлДанных.Записать(Объект.ИмяФайла,КодировкаТекста.ANSI); по причине: Каталог не обнаружен 'X:\Cos\Обработки\выгр.txt'.
Главная причина здесь заключается в разрыве контекста между клиентом (вашим компьютером) и сервером (удаленной машиной, где установлена служба 1С:Предприятие). Когда мы используем директиву &НаСервере, весь код выполняется от имени системной службы сервера. Проанализируем, что «видит» сервер в этот момент:
C:, D:), но не имеет доступа к вашему диску C:.X: — это сетевой ресурс, который подключен в сеансе конкретного пользователя Windows. Служба 1С работает в так называемой «Сессии 0» (Session 0 Isolation). В этой сессии сетевые диски пользователей не монтируются. Для сервера диска X: просто не существует.Desktop из серверного кода приведет к тому, что 1С будет искать рабочий стол системной учетной записи (например, USR1CV8), к которому у обычного пользователя доступа нет, либо папка вовсе будет отсутствовать.Если нам жизненно необходимо, чтобы сервер 1С записывал файл напрямую в сетевую папку, мы должны отказаться от использования букв дисков (X:, Z: и т.д.). Вместо этого следует использовать полные сетевые пути в формате UNC.
Рассмотрим пример правильного указания пути:
// Вместо X:\Cos\Обработки\выгр.txt
ПутьКФайлу = "\\ServerName\ShareFolder\Cos\Обработки\выгр.txt";
Однако просто заменить путь недостаточно. Нужно убедиться, что у пользователя, под которым запущена служба 1С:Предприятия (обычно это USR1CV8 или LocalSystem), есть права на запись в эту сетевую папку. Разберем по шагам, как это проверить:
Как справедливо заметили участники обсуждения, если файл должен появиться на компьютере пользователя, то и записывать его нужно «НаКлиенте». В файловой базе это различие незаметно, так как клиент и сервер — это одно и то же приложение. Но в клиент-серверном варианте это критично.
Проанализируем пример кода, который решает проблему простым переносом логики:
&НаКлиенте
Процедура ВыполнитьВыгрузку(Команда)
// Подготавливаем данные на сервере
ДанныеДляЗаписи = ПодготовитьДанныеНаСервере();
// Записываем файл непосредственно на клиенте
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст(ДанныеДляЗаписи);
ТекстовыйДокумент.Записать(Объект.ИмяФайла, КодировкаТекста.ANSI);
КонецПроцедуры
В этом случае 1С использует ресурсы вашего локального компьютера, и диск X: будет прекрасно виден.
В современных конфигурациях на управляемых формах (8.3) хорошим тоном считается использование временного хранилища. Это позволяет разделить логику подготовки данных и их сохранения, обеспечивая стабильную работу даже через веб-клиент (браузер).
Рассмотрим алгоритм совместной работы клиента и сервера:
Пример реализации такого подхода:
&НаСервере
Функция СформироватьФайлНаСервере()
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("txt");
// Логика заполнения файла
гФайлДанных = Новый ТекстовыйДокумент;
гФайлДанных.ДобавитьСтроку("Данные выгрузки...");
гФайлДанных.Записать(ИмяВременногоФайла, КодировкаТекста.ANSI);
// Помещаем в хранилище и получаем адрес
ДанныеФайла = Новый ДвоичныеДанные(ИмяВременногоФайла);
АдресХранилища = ПоместитьВоВременноеХранилище(ДанныеФайла, ЭтаФорма.УникальныйИдентификатор);
УдалитьФайлы(ИмяВременногоФайла); // Очищаем за собой временный каталог сервера
Возврат АдресХранилища;
КонецФункции
&НаКлиенте
Процедура СохранитьФайл(Команда)
Адрес = СформироватьФайлНаСервере();
ПараметрыПолучения = Новый ПараметрыПолученияФайла;
// Этот метод предложит пользователю выбрать место сохранения на его компьютере
ПолучитьФайлССервера(Адрес, "выгр.txt", ПараметрыПолучения);
КонецПроцедуры
Выясним причину еще одной возможной ошибки. Если ваш сервер 1С работает под управлением ОС Linux, то пути формата C:\... или X:\... работать не будут в принципе, даже если папка расшарена. Linux использует прямые слеши (/) и свою иерархию папок (например, /mnt/share/file.txt).
Для написания универсального кода, который работает на любой ОС, рекомендуется использовать методы работы с путями из Библиотеки Стандартных Подсистем (БСП) или встроенные функции платформы, которые автоматически учитывают тип разделителей. Также всегда проверяйте существование каталога перед записью с помощью функции НайтиФайлы().
Подводя итог, можно выделить три золотых правила работы с файлами в 1С:
Соблюдение этих правил позволит вашим обработкам работать надежно в любой сетевой инфраструктуре.