Существует ли файл: проверка на клиенте, сервере и в сетевой папке 1С 8.3

· 9 мин

Содержание

Чтобы в 1С проверить существование файла, создайте объект Новый Файл(ПолноеИмя) и вызовите у него метод Существует(): он вернёт Истина или Ложь. На клиенте с отключённой модальностью используйте асинхронный вариант — НачатьПроверкуСуществования() или, в платформе 8.3.18 и новее, Ждать Файл.СуществуетАсинх().

Типичная ситуация: обработка загрузки выписок падает с ошибкой открытия файла, хотя бухгалтер клянётся, что файл лежит в папке. Почти всегда причина не в коде проверки, а в том, на каком компьютере и от чьего имени он выполняется. Ниже — рабочий код и разбор этих тонкостей. Всё сказанное относится к платформе 8.3 и не зависит от конфигурации: БП, ЗУП и УТ работают с файлами одинаково.

1. Объект Файл: базовая проверка существования файла

Объект Файл описывает путь, а не открытый файл. Создание Новый Файл(...) ничего не читает с диска и не падает, если файла нет. Обращение к диску происходит только при вызове методов.

Синхронный вариант (сервер и толстый клиент)

&НаСервере
Функция ФайлСуществует(ПолноеИмя)
	
	Если ПустаяСтрока(ПолноеИмя) Тогда
		Возврат Ложь;
	КонецЕсли;
	
	ПроверяемыйФайл = Новый Файл(ПолноеИмя);
	Возврат ПроверяемыйФайл.Существует() И ПроверяемыйФайл.ЭтоФайл();
	
КонецФункции

Проверка ЭтоФайл() здесь не лишняя. Существует() вернёт Истина и для каталога с тем же именем. Если дальше код читает файл через ТекстовыйДокумент.Прочитать() или ЧтениеТекста, на каталоге он упадёт.

Как проверить наличие папки

Каталог проверяют тем же объектом, но вторым условием ставят ЭтоКаталог():

Каталог = Новый Файл("D:\Обмен\Входящие");
Если Не (Каталог.Существует() И Каталог.ЭтоКаталог()) Тогда
	СоздатьКаталог("D:\Обмен\Входящие");
КонецЕсли;

СоздатьКаталог() создаёт и промежуточные папки, если их нет. Поэтому отдельно проверять каждый уровень пути не нужно.

Что ещё умеет объект Файл

Метод / свойствоЧто даёт
Существует()есть ли файл или каталог по пути
ЭтоФайл(), ЭтоКаталог()что именно лежит по пути
Размер()размер в байтах, удобно отсечь пустой файл
ПолучитьВремяИзменения()дата изменения, чтобы не грузить старую выгрузку повторно
ПолучитьТолькоЧтение()стоит ли атрибут «только чтение»
Имя, ИмяБезРасширения, Расширение, Путьразбор полного имени без ручной работы со строкой

Проверка на пустой файл часто полезнее проверки существования. Внешняя программа могла создать файл и ещё не дописать его. Условие Файл.Размер() > 0 отсекает такие случаи.

2. Асинхронная проверка на клиенте и старые способы

В тонком клиенте и веб-клиенте при режиме Использование модальности = Не использовать синхронные методы работы с файлами на клиенте недоступны. Код с Существует() в клиентской процедуре в такой конфигурации выдаст ошибку о запрете синхронных вызовов.

Через описание оповещения

&НаКлиенте
Процедура ПроверитьФайл(Команда)
	ПроверяемыйФайл = Новый Файл(ПутьКФайлу);
	Оповещение = Новый ОписаниеОповещения("ПослеПроверкиФайла", ЭтотОбъект);
	ПроверяемыйФайл.НачатьПроверкуСуществования(Оповещение);
КонецПроцедуры

&НаКлиенте
Процедура ПослеПроверкиФайла(Существует, ДополнительныеПараметры) Экспорт
	Если Существует Тогда
		Сообщить("Файл найден");
	Иначе
		Сообщить("Файл не найден: " + ПутьКФайлу);
	КонецЕсли;
КонецПроцедуры

Процедура-обработчик обязательно экспортная. Без Экспорт платформа не сможет её вызвать.

Через Асинх и Ждать (8.3.18 и новее)

С платформы 8.3.18 тот же код пишется линейно:

&НаКлиенте
Асинх Процедура ПроверитьФайл(Команда)
	ПроверяемыйФайл = Новый Файл(ПутьКФайлу);
	Если Ждать ПроверяемыйФайл.СуществуетАсинх() Тогда
		Сообщить("Файл найден");
	КонецЕсли;
КонецПроцедуры

Если режим совместимости конфигурации ниже 8.3.18, ключевые слова Асинх и Ждать не распознаются. Тогда остаётся вариант с оповещением.

Проверка через НайтиФайлы

Функция НайтиФайлы(Каталог, Маска) возвращает массив объектов Файл. Пустой массив — файла нет:

Найденные = НайтиФайлы("D:\Обмен\Входящие", "kl_to_1c*.txt");
Если Найденные.Количество() = 0 Тогда
	ВызватьИсключение "В папке нет файлов выписки";
КонецЕсли;

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

Старые версии платформы

ПлатформаЧем проверить
8.3, режим совместимости 8.3.18+Существует(), СуществуетАсинх(), НайтиФайлы()
8.3 с отключённой модальностью, совместимость ниже 8.3.18НачатьПроверкуСуществования(), НачатьПоискФайлов()
8.2 и 8.3 с модальностьюНовый Файл(...).Существует() на клиенте и сервере
7.7ФС.СуществуетФайл(ИмяФайла) — возвращает 1 или 0

Код на 7.7 не переносится в 8.x напрямую: глобального объекта ФС в восьмёрке нет.

3. Проверка файла в сетевой папке и по UNC-пути

Главная ловушка сетевых путей — подключённые диски. Пользователь видит папку как Z:\Банк, но буква Z: существует только в его сеансе Windows.

  • 🖥️ Файловая база, код на клиенте — путь Z:\Банк работает, потому что код выполняется в сеансе пользователя.
  • 🗄️ Клиент-серверная база , код на сервере — Z: не существует. Служба сервера 1С запущена от отдельной учётной записи (часто USR1CV8), у неё нет подключённых дисков.
  • 🌐 Терминальный сервер — диски могут отличаться у разных пользователей одного сервера.

Для серверного кода всегда пишите полный UNC-путь:

ПутьКФайлу = "\\fileserver\obmen\bank\kl_to_1c.txt";

Права учётной записи службы

Чтобы серверный код увидел файл в сетевой папке, учётной записи службы сервера 1С нужен доступ:

  1. Узнайте, от чьего имени работает служба: services.msc → служба агента сервера 1С:Предприятия → вкладка «Вход в систему».
  2. Если указана локальная учётная запись, по сети к чужому серверу она не пройдёт. Нужна доменная учётная запись.
  3. Выдайте этой записи права на чтение (или изменение, если код пишет файлы) — и на сетевой ресурс, и на папку в NTFS.
  4. Проверьте доступ от её имени: войдите под этой учётной записью на сервер 1С и откройте путь в проводнике.

Смена учётной записи службы требует перезапуска службы сервера 1С. Все сеансы пользователей оборвутся. Делайте это вне рабочего времени и предупредите пользователей заранее.

Сервер 1С на Linux

На Linux-сервере обратная косая черта не работает , а UNC-путей в привычном виде нет. Сетевую папку монтируют в файловую систему (например, через CIFS), а в коде указывают путь вида /mnt/obmen/bank/kl_to_1c.txt. Регистр букв в имени файла на Linux имеет значение: Bank.TXT и bank.txt — разные файлы.

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

4. Почему файл не находится: разбор причин

Когда Существует() возвращает Ложь, а файл точно на месте, проверяйте по порядку.

Диагностика: выберите симптом

Лишние символы в пути

Пути часто приходят из настроек или реквизитов справочника. Пробел в конце строки, перевод строки после копирования из письма или неразрывный пробел делают путь «невидимо неверным». Перед проверкой прогоните путь через СокрЛП().

Длинные пути

Windows по умолчанию ограничивает полный путь 260 символами. Глубоко вложенные папки с длинными русскими именами упираются в лимит, и файл формально «не существует». Сократите структуру папок или перенесите обмен в каталог ближе к корню диска.

Как обрабатывать ошибки чтения

Существует() отвечает только на вопрос «есть ли путь». Файл может существовать, но быть занят другой программой. Поэтому само чтение оборачивайте в Попытка:

Если Не ФайлСуществует(ПолноеИмя) Тогда
	ВызватьИсключение "Файл не найден: " + ПолноеИмя;
КонецЕсли;

Попытка
	Текст = Новый ТекстовыйДокумент;
	Текст.Прочитать(ПолноеИмя, КодировкаТекста.UTF8);
Исключение
	ЗаписьЖурналаРегистрации("Загрузка выписки", УровеньЖурналаРегистрации.Ошибка, , ,
		ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
	ВызватьИсключение "Не удалось прочитать файл: "
		+ КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
КонецПопытки;

В журнал регистрации пишите подробное представление ошибки, пользователю показывайте краткое. Так администратор увидит стек вызова, а бухгалтер — понятный текст.

5. Массовая проверка файлов без потерь скорости

Каждый вызов Существует() — отдельное обращение к файловой системе. На локальном диске это быстро. На сетевой папке каждое обращение идёт по сети, и цикл по 5 000 файлам может растянуться на минуты.

Если нужно проверить много файлов в одном каталоге, прочитайте каталог один раз:

ИменаВПапке = Новый Соответствие;
Для Каждого НайденныйФайл Из НайтиФайлы(КаталогОбмена, "*.*") Цикл
	ИменаВПапке.Вставить(НРег(НайденныйФайл.Имя), Истина);
КонецЦикла;

Для Каждого Строка Из ТаблицаФайлов Цикл
	Строка.Найден = (ИменаВПапке.Получить(НРег(Строка.ИмяФайла)) <> Неопределено);
КонецЦикла;

Один запрос к каталогу плюс поиск в соответствии в памяти почти всегда быстрее тысяч отдельных проверок. НРег() здесь выравнивает регистр для Windows. На Linux-сервере регистр важен, и приводить имена к нижнему уровню не нужно.

Ещё несколько правил для массовых операций:

  • 📁 Не ищите с флагом поиска в подкаталогах (НайтиФайлы(Каталог, Маска, Истина)) по корню большого общего диска — обход займёт много времени.
  • 🔁 Не проверяйте один и тот же путь в каждой итерации цикла. Проверьте каталог один раз до цикла.
  • 🖥️ Если файлов десятки тысяч, выполняйте проверку на сервере, ближе к хранилищу, а не гоняйте путь с клиента.
  • ⏱️ Длительную проверку запускайте фоновым заданием, чтобы форма не «зависала» у пользователя.

Языком запросов 1С проверить наличие файла нельзя: запрос работает только с таблицами базы. Если путь хранится в реквизите, сначала получите выборку запросом, затем проверяйте файлы кодом в цикле по выборке.

6. Веб-клиент, облако и безопасный режим

Где выполняется проверка, зависит от того, как пользователь подключён к базе.

СредаЧто можно проверитьЧто нужно
Тонкий клиент, клиентский кодфайлы на компьютере пользователяничего, кроме асинхронных методов при отключённой модальности
Веб-клиент, клиентский кодфайлы на компьютере пользователярасширение для работы с файлами в браузере
Любой клиент, серверный кодфайлы на сервере 1С и в доступных ему сетевых папкахправа учётной записи службы
Облачная база (сервис по модели SaaS)только временные файлы сеансаработа через ПоместитьФайл / временное хранилище

Расширение для работы с файлами

В веб-клиенте перед проверкой локального файла подключите расширение. Асинхронно это делается через НачатьПодключениеРасширенияРаботыСФайлами(). Если расширение не установлено, вызовите НачатьУстановкуРасширенияРаботыСФайлами() — браузер предложит его поставить.

Без расширения веб-клиент может только предложить пользователю выбрать файл в стандартном диалоге и передать его на сервер. Проверить «молча», лежит ли файл в папке на диске, не получится.

Облако и безопасный режим

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

  1. Пользователь выбирает файл на своём компьютере.
  2. Файл передаётся на сервер через ПоместитьФайл или его асинхронные аналоги и попадает во временное хранилище.
  3. Серверный код получает двоичные данные по адресу во временном хранилище и сохраняет их во временный файл через ПолучитьИмяВременногоФайла().

После обработки удалите временный файл через УдалитьФайлы(). Иначе временный каталог сервера постепенно забьётся.

Та же логика касается внешних обработок и расширений в локальной клиент-серверной базе. Если для них настроен профиль безопасности, доступ к файловой системе разрешается в нём отдельно — по каталогам. Иначе обращение к диску завершится ошибкой безопасного режима, даже если сам путь правильный.

7. Частые вопросы

Чем Существует() отличается от НайтиФайлы()?
Существует() проверяет один известный путь. НайтиФайлы() ищет по маске и возвращает массив — подходит, когда точное имя файла заранее неизвестно.
Можно ли проверить наличие файла по ссылке http?
Нет, объект Файл работает только с файловой системой. Для адреса в интернете отправьте запрос через HTTPСоединение и проверьте код ответа: 200 означает, что файл доступен.
Вернёт ли Существует() ошибку, если нет прав на папку?
Обычно нет: метод вернёт Ложь, как будто файла нет. Поэтому при «пропавшем» файле в сетевой папке первым делом проверяйте права учётной записи, от которой выполняется код.
Как проверить файл внутри присоединённых файлов документа?
Присоединённые файлы хранятся в базе или в томах, а не по пути, который видит пользователь. Их наличие проверяют запросом к справочнику присоединённых файлов владельца, а не объектом Файл.
Где выполняется код в файловой базе?
В файловом варианте и клиентский, и серверный код работают на компьютере пользователя. Поэтому путь C:\Выгрузка в файловой базе находится, а после перехода на клиент-серверный вариант перестаёт находиться.