При разработке механизмов выгрузки данных в 1С программисты часто сталкиваются с ситуацией, когда файл отказывается сохраняться в выбранный каталог. На первый взгляд код кажется верным, но система либо выдает ошибку, либо сохраняет файл без расширения, либо вовсе "не видит" целевую папку. В этой статье мы подробно разберем основные причины таких сбоев, научимся правильно формировать имена файлов и эффективно работать в клиент-серверном режиме.
Проанализируем типичную ошибку. Разработчик пытается сформировать имя файла, используя строковое представление ссылки документа: ФайлНазвание = СокрЛП(ДокументОбъект.Ссылка) + ".xml". На первый взгляд, это логично, ведь ссылка содержит тип документа и его номер. Однако именно здесь кроется главная ловушка.
Рассмотрим ситуацию подробнее. Строковое представление ссылки (метод СокрЛП от объекта типа ДокументСсылка) обычно выглядит так: "Реализация товаров и услуг № 00001 от 01.01.2023 12:00:00". В операционных системах семейства Windows (и большинстве других) существует строгий список символов, которые запрещено использовать в именах файлов. К ним относятся:
: (оно всегда присутствует в представлении времени ссылки);/ или \;< >;?;*;";|.Выясним причину неудачи: при попытке сохранить файл, в имени которого есть двоеточие из времени документа, операционная система отклоняет запрос, и 1С не может создать файл. Проанализируем правильный подход: для именования файла следует использовать конкретные реквизиты, не содержащие спецсимволов, например, Номер или Дата (предварительно преобразованная в формат без разделителей).
Посмотрим на пример корректного формирования имени:
// Неправильно: содержит двоеточия
// ФайлНазвание = СокрЛП(ДокументОбъект.Ссылка) + ".xml";
// Правильно: используем номер документа
ИмяФайла = "Выгрузка_" + СокрЛП(ДокументОбъект.Номер) + ".xml";
ПутьКФайлу = КаталогВременныхФайлов() + ИмяФайла;
Если в вашей конфигурации установлена БСП, мы рекомендуем не изобретать велосипед, а воспользоваться встроенными функциями очистки строк. Это гарантирует, что даже если в номере или наименовании документа окажутся кавычки или слэши, программа не "упадет" с ошибкой.
Разберем, как это сделать программно:
ИмяФайла = СтрШаблон("%1 №%2.xml", ДокументОбъект.Метаданные().Синоним, ДокументОбъект.Номер);
// Очищаем имя от запрещенных символов через БСП
ИмяФайла = СтроковыеФункцииКлиентСервер.ЗаменитьНедопустимыеСимволыИмениФайла(ИмяФайла, "_");
ПолныйПуть = КаталогВременныхФайлов() + ИмяФайла;
Функция ЗаменитьНедопустимыеСимволыИмениФайла автоматически заменит все "опасные" знаки на нижнее подчеркивание (или любой другой символ, который вы укажете во втором параметре).
Часто возникает ситуация: на локальной базе (файловой) код работает идеально, но при переносе на серверную базу файлы перестают сохраняться или "исчезают". Выясним причину: это происходит из-за разницы контекстов выполнения кода НаКлиенте и НаСервере.
Проанализируем ситуацию: когда вы вызываете КаталогВременныхФайлов() на стороне сервера, система возвращает путь в профиле пользователя, под которым запущена служба 1cv8 (например, usr1cv8). Этот путь физически находится на жестком диске сервера. Когда же код выполняется на стороне клиента, путь ведет в локальную папку Temp на компьютере пользователя.
Важные правила работы с путями на сервере:
C: или D:. Попытка сохранить файл по пути C:\MyFiles\data.xml из серверного контекста приведет к тому, что 1С будет искать этот путь на сервере.Рассмотрим пример правильной передачи файла с сервера на клиент:
&НаСервере
Функция СформироватьФайлНаСервере()
ИмяФайла = ПолучитьИмяВременногоФайла("xml");
// ... здесь логика записи данных в файл ...
ДвоичныеДанные = Новый ДвоичныеДанные(ИмяФайла);
АдресХранилища = ПоместитьВоВременноеХранилище(ДвоичныеДанные, ЭтаФорма.УникальныйИдентификатор);
УдалитьФайлы(ИмяФайла);
Возврат АдресХранилища;
КонецФункции
&НаКлиенте
Процедура СохранитьФайл()
Адрес = СформироватьФайлНаСервере();
ПараметрыДиалога = Новый ПараметрыДиалогаПолученияФайлов("Выберите путь для сохранения");
ПолучитьФайлССервера(Адрес, "Выгрузка.xml", ПараметрыДиалога);
КонецПроцедуры
Иногда требуется ограничить пользователя в выборе папки или скрыть лишние элементы интерфейса. Стандартный объект ДиалогВыбораФайла имеет свои ограничения. Рассмотрим их подробнее.
Вы можете задать начальный каталог с помощью свойства Каталог, но важно понимать: это не запретит пользователю перейти в другую папку через дерево каталогов. Если же ваша задача — полностью скрыть структуру папок и оставить только список файлов, стандартный диалог Windows/Linux этого сделать не позволит.
В таком случае мы рекомендуем реализовать собственную форму выбора. Для этого:
НайтиФайлы.Посмотрим на пример использования НайтиФайлы для получения только XML-документов в конкретной папке:
СписокФайлов = НайтиФайлы("C:\ExchangeData\", "*.xml", Ложь);
Для Каждого ТекущийФайл Из СписокФайлов Цикл
Если ТекущийФайл.ЭтоФайл() Тогда
// Добавляем ТекущийФайл.Имя в таблицу на форме
КонецЕсли;
КонецЦикла;
Параметр Ложь в методе НайтиФайлы означает, что поиск будет вестись только в указанном каталоге без захода в подпапки. Это и позволяет "отфильтровать" отображение каталогов для пользователя.
Если ваша информационная база работает в смешанной среде (сервер на Linux, клиенты на Windows), вы обязательно столкнетесь с проблемой разделителей. В Windows используется обратный слэш \, а в Linux — прямой /.
Чтобы код был универсальным, проанализируем использование функции ПолучитьРазделительПути(). Никогда не пишите слэши вручную в строковых константах, если планируете кроссплатформенное использование.
Разделитель = ПолучитьРазделительПути();
ПолныйПуть = Каталог + Разделитель + ИмяФайла;
Также помните, что Linux чувствителен к регистру имен файлов. Файл Export.xml и export.xml для Linux — это два разных объекта, тогда как Windows будет считать их одним и тем же файлом. Всегда приводите программно формируемые имена к единому регистру, чтобы избежать ошибок "Файл не найден".
В современных версиях платформы 8.3 (особенно начиная с 8.3.9) включена защита от опасных действий. При попытке программно записать файл на диск пользователя 1С может вывести предупреждение системы безопасности.
Чтобы избежать раздражающих окон для пользователя при работе с доверенными скриптами, эти действия можно настроить в профилях безопасности или отключить проверку для конкретной информационной базы в свойствах пользователя в конфигураторе. Однако лучшей практикой считается использование стандартных механизмов платформы для работы с файлами (ПоместитьФайл, ПолучитьФайл), которые проходят проверку безопасности более "мягко".
Подводя итог, скажем: стабильное сохранение файлов в 1С зависит от трех факторов: чистоты имени (отсутствие спецсимволов), понимания контекста (где выполняется код) и правильной обработки путей. Используя описанные выше методы, вы сможете избежать 99% типичных ошибок при работе с файловой системой.