Как проверить наличие файла на сервере 1С при работе с клиентской машины

Программист 1С v8.3 (Обычные формы)
← На главную

При разработке в среде 1С:Предприятие, особенно в режиме Обычного приложения, программисты часто сталкиваются с ситуацией, когда код прекрасно работает при запуске базы на самом сервере (через RDP), но отказывается функционировать при подключении с клиентского компьютера. Типичный пример: проверка существования файла по локальному пути типа D:\Files\data.mxl. Разберем подробно, почему так происходит и как правильно организовать проверку и чтение серверных файлов.

Причина проблемы: различие контекстов исполнения

Проанализируем ситуацию: если вы запускаете базу на сервере, ваш сеанс (клиентская часть) и файлы находятся на одном и том же физическом диске. В этом случае 1С видит путь D:\1sb8\.... Однако, когда вы подключаетесь с другого компьютера, код проверки файла по умолчанию выполняется на клиенте. Клиентское приложение ищет диск D: на локальной машине пользователя, а не на сервере, и, естественно, ничего не находит.

Многие полагают, что установка галочки "Сервер" в свойствах общего модуля автоматически заставляет код работать на сервере. В управляемых формах это регулируется директивами &НаСервере, но в обычных формах ситуация иная. Если у модуля стоят флаги "Клиент" и "Сервер", то при вызове из обычной формы приоритет отдается клиентскому исполнению. Рассмотрим, как гарантировать выполнение кода именно на стороне сервера.

Решение 1. Проверка прав доступа службы 1С

Прежде чем приступать к написанию кода, важно выяснить одну критическую деталь: под чьим именем работает сервер 1С. Выясним причину, по которой даже "правильный" серверный код может не видеть файл. Когда код выполняется на сервере, он обращается к операционной системе от имени пользователя, под которым запущена служба "Агент сервера 1С:Предприятия" (обычно это USR1CV8).

Что необходимо проверить:

  1. Зайдите в управление службами на сервере и найдите службу 1С.
  2. Посмотрите вкладку "Вход в систему".
  3. Убедитесь, что у этого пользователя (например, USR1CV8) есть права на чтение и просмотр содержимого папки D:\1sb8\Коды_ТНВЭД\. Если файл лежит в профиле другого пользователя или на закрытом системном диске, служба его не увидит, даже если он там есть.

Решение 2. Использование временного хранилища для передачи данных

Рассмотрим сценарий, когда нам нужно не просто проверить наличие файла, но и прочитать его содержимое (например, табличный документ) на сервере, а затем отобразить результат пользователю на клиенте. Для этого лучше всего подходит механизм Временного хранилища.

Посмотрим на пример правильной реализации функций в общем модуле, который имеет флаг "Сервер" (и желательно только его, либо вызывается из строго серверного контекста):


// Функция выполняется строго на сервере
Функция ПолучитьАдресФайлаНаСервере() Экспорт
    ПутьКФайлу = "D:\1sb8\Коды_ТНВЭД\Список ГСВС.mxl";
    ФайлНаДиске = Новый Файл(ПутьКФайлу);
    
    Если НЕ ФайлНаДиске.Существует() Тогда
        Возврат Неопределено;
    КонецЕсли;
    
    // Читаем табличный документ на сервере
    ТабДок = Новый ТабличныйДокумент;
    Попытка
        ТабДок.Прочитать(ПутьКФайлу);
    Исключение
        Сообщить("Ошибка чтения файла: " + ОписаниеОшибки());
        Возврат Неопределено;
    КонецПопытки;
    
    // Помещаем объект во временное хранилище и возвращаем адрес
    Возврат ПоместитьВоВременноеХранилище(ТабДок);
КонецФункции

На стороне клиента (в форме или клиентском модуле) мы вызываем эту функцию и получаем объект обратно:


Процедура ЗагрузитьДанныеССервера()
    Адрес = ОбщийМодульСервер.ПолучитьАдресФайлаНаСервере();
    
    Если Адрес = Неопределено Тогда
        Предупреждение("Файл на сервере не найден!");
        Возврат;
    КонецЕсли;
    
    // Получаем объект из хранилища
    РезультатТабДок = ПолучитьИзВременногоХранилища(Адрес);
    // Теперь РезультатТабДок доступен на клиенте
КонецПроцедуры

Важный нюанс: Не используйте устаревшие функции ЗначениеВСТрокуВнутр для передачи сложных объектов вроде ТабличныйДокумент. Метод ПоместитьВоВременноеХранилище прекрасно справляется с передачей объектов напрямую.

Решение 3. Использование метода НайтиФайлы

Иногда объект Новый Файл() может вести себя некорректно при специфических настройках прав. Проанализируем альтернативный способ проверки через функцию НайтиФайлы(). Этот метод возвращает массив найденных объектов, и если он пуст — файла не существует.


Функция ФайлСуществуетНаСервере(ПолныйПуть) Экспорт
    МассивФайлов = НайтиФайлы(ПолныйПуть);
    Возврат МассивФайлов.Количество() > 0;
КонецФункции

Этот метод удобен тем, что поддерживает маски (например, *.mxl), что позволяет делать более гибкие проверки.

Решение 4. Архитектурный подход — хранение в макетах

Разберем ситуацию: если ваш файл Список ГСВС.mxl является справочным и меняется не каждый час, то хранить его просто "на диске D:" — не самая лучшая практика. Это создает зависимость от файловой системы и конкретного сервера. В кластере 1С может быть несколько рабочих серверов, и файл должен лежать на каждом из них по одному и тому же пути.

Рекомендуемый подход:

  1. Создайте в конфигурации или в конкретной обработке Макет типа "Табличный документ".
  2. Загрузите ваш MXL-файл в этот макет.
  3. Обращайтесь к нему через ЭтотОбъект.ПолучитьМакет("ИмяМакета").

В этом случае данные будут храниться внутри базы данных, они будут доступны мгновенно на любом сервере кластера и любому пользователю, независимо от его прав на папки Windows.

Подведем итоги

Для успешной проверки файла на сервере необходимо:

← На главную