При переходе с файловой версии базы на клиент-серверную или при миграции с платформы 8.1 на 8.2/8.3 программисты часто сталкиваются с ситуацией, когда проверенная временем функция НайтиФайлы перестает возвращать результат. При этом программа не выдает ошибок, а просто возвращает пустой массив, даже если файлы по указанному пути точно существуют. Разберем подробно, почему так происходит, и как заставить сервер «видеть» нужные данные.
Первое, что мы должны проанализировать — это контекст выполнения кода. В файловой версии базы клиент и сервер — это фактически один и тот же процесс, имеющий доступ к одним и тем же ресурсам. В серверной версии код с директивой &НаСервере выполняется на стороне сервера приложений 1С:Предприятие.
Важный момент: Если вы передаете в функцию НайтиФайлы путь, который доступен вам как пользователю (например, «C:\MyFiles\»), сервер будет искать эту папку на своем локальном диске, а не на вашем компьютере. Рассмотрим ситуацию: если путь вводится пользователем на клиенте, а поиск происходит на сервере, сервер ищет файл в собственной файловой системе. Если сервер и клиент физически находятся на разных машинах, результат всегда будет пустым. Для наглядного анализа файловой структуры и обмена объектами между этими средами можно использовать двухпанельный файловый менеджер для обмена файлами между клиентом и сервером.
Выясним причину, связанную с правами доступа. Служба сервера 1С:Предприятие (обычно это usr1cv8) работает под определенной учетной записью Windows. В отличие от интерактивного пользователя, у этой службы часто нет прав на доступ к сетевым ресурсам или даже к определенным локальным папкам.
Если сервер 1С запущен под локальной системной учетной записью (Local System), он не сможет получить доступ к сетевой шаре по UNC-пути (вида \\Server\Share\), так как не имеет прав в доменной сети. Проанализируем возможные решения:
cmdkey, чтобы «подложить» серверу логин и пароль для доступа к конкретному сетевому ресурсу.Рассмотрим пример кода, который позволяет добавить данные авторизации для сетевого ресурса прямо из 1С на стороне сервера:
&НаСервере
Процедура ДобавитьДанныеАвторизацииНаСервере()
// Укажите сетевое имя сервера, логин и пароль
СерверИмя = "pc2222";
Логин = "usr";
Пароль = "psw";
КодВозврата = Неопределено;
Команда = "cmdkey /add:" + СерверИмя + " /user:" + Логин + " /pass:" + Пароль;
ЗапуститьПриложение(Команда, , Истина, КодВозврата);
Если КодВозврата = 0 Тогда
Сообщить("Данные авторизации успешно добавлены");
КонецЕсли;
КонецПроцедуры
Частая ошибка при использовании НайтиФайлы на сервере — использование букв сетевых дисков (например, Z:\Archive\). Процесс сервера 1С не видит сетевые диски, подключенные в сессии пользователя. Проанализируем ситуацию: когда вы подключаете диск Z:, он виден только вам. Для сервера этого диска не существует.
Решение: Всегда используйте только полные UNC-пути. Вместо Z:\Folder\ пишите \\ServerName\ShareName\Folder\. Также обратите внимание на синтаксис слешей. В некоторых случаях (особенно при работе с FTP или в смешанных средах) платформа 1С требует использования прямых слешей / вместо обратных \.
Если ваш сервер 1С работает под управлением ОС Linux, функция НайтиФайлы ведет себя еще более строго. Рассмотрим основные нюансы:
/Archive/File.pdf и /archive/file.pdf идентичны. В Linux это разные пути. Если маска файла указана неверно, поиск ничего не даст.\\server\share. Сетевой ресурс должен быть предварительно смонтирован в файловую систему сервера (например, в /mnt/win_share/). Обращаться в 1С нужно именно к этой точке монтирования.В некоторых случаях стандартная функция НайтиФайлы может работать медленно, если в каталоге находятся десятки тысяч объектов. Посмотрим на альтернативный способ с использованием COMОбъект "Scripting.FileSystemObject" (FSO), который иногда работает быстрее в Windows-среде, но требует осторожности при использовании на сервере.
// Пример использования FSO для получения списка файлов
Попытка
FSO = Новый COMОбъект("Scripting.FileSystemObject");
Каталог = FSO.GetFolder("\\Server\Archive\");
Для Каждого Файл Из Каталог.Files Цикл
// Обработка файла
ИмяФайла = Файл.Name;
КонецЦикла;
Исключение
Сообщить("Ошибка работы с COM: " + ОписаниеОшибки());
КонецПопытки;
Однако помните, что COMОбъект может быть недоступен, если сервер 1С работает на 64-битной платформе без соответствующей настройки компонентов COM+, или если сервер работает на Linux. Поэтому встроенная функция НайтиФайлы остается наиболее универсальным инструментом.
Если ваша задача состоит не в поиске по маске, а в проверке существования конкретного файла (как часто бывает при формировании пути к PDF или изображениям), эффективнее использовать объект Файл. Рассмотрим пример:
ПолныйПуть = "\\Server\Archive\Documents\Check_123.pdf";
ОбъектФайл = Новый Файл(ПолныйПуть);
Если ОбъектФайл.Существует() Тогда
// Файл найден, работаем с ним
Результат = ОбъектФайл.ПолноеИмя;
Иначе
// Файл не найден
КонецЕсли;
Этот метод работает быстрее, чем НайтиФайлы, так как системе не нужно сканировать всё содержимое каталога и формировать массив объектов, если вам нужен лишь один конкретный файл.
Если НайтиФайлы не работает на сервере, пройдите по следующим шагам:
\\Server\Share\), а не через букву диска.&НаСервере, если файлы на локальном ПК пользователя — код &НаКлиенте)./ в пути, если обратные не срабатывают.Соблюдение этих правил гарантирует стабильную работу с файловой системой в любых архитектурных решениях 1С:Предприятия.