Как исправить ошибку «Длина имени файла превысила 8 символов» при открытии файла DBF в 1С

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

При работе со встроенным в 1С объектом XBase разработчики часто сталкиваются с неприятной ошибкой: «Ошибка при вызове метода контекста (ОткрытьФайл): Длина имени файла превысила 8 символов». Данная проблема унаследована от старого стандарта СУБД dBase (формат DOS 8.3), который жестко ограничивает длину имени файла восемью символами, а расширения — тремя.

Попытки обойти это ограничение с помощью вызова системной функции Windows ShortPath через COM-объект Scripting.FileSystemObject часто приводят к нестабильной работе: у одних клиентов обработка открывает файлы без проблем, а у других тот же самый код выдает фатальную ошибку. В этой статье мы подробно разберем, почему так происходит, и рассмотрим три надежных способа решения этой проблемы.

Почему метод ShortPath работает не у всех клиентов?

Конструкция вида fso.GetFile(ПутьБДШ).ShortPath запрашивает у операционной системы Windows короткое имя файла (например, превращает 000001000005000.dbf в 000001~1.DBF). Однако этот «костыль» ломается, если сама операционная система на конкретном компьютере не сгенерировала короткое имя. Проанализируем основные причины, почему это происходит:

  1. Отключение поддержки имен 8.3 в реестре Windows. В современных версиях Windows (начиная с Windows 8 и Windows Server 2012) функция генерации коротких имен часто отключена по умолчанию для оптимизации производительности файловой системы NTFS. За это отвечает параметр реестра NtfsDisable8dot3NameCreation. Если он равен 1 или 2, короткие имена могут не создаваться.
  2. Отказ работы реестра «задним числом». Даже если включить генерацию имен 8.3 в реестре, операционная система не создаст короткие имена для тех файлов и папок, которые уже существовали на диске до внесения изменений.
  3. Использование неподдерживаемых файловых систем. Если DBF-файл расположен на флеш-карте или внешнем диске с файловой системой exFAT или серверном томе ReFS, метод ShortPath всегда будет возвращать длинный путь, так как эти системы в принципе не поддерживают стандарт 8.3.
  4. Сетевые папки и хранилища (NAS). При чтении файлов с сетевых ресурсов поведение ShortPath зависит от настроек удаленного сервера. Если сетевой диск работает под управлением Linux (Samba) или файловая система сетевого хранилища не настроена на передачу коротких имен, метод вернет длинный путь.
  5. Проблема длинных имен в родительских папках. Для успешной работы метода ShortPath короткие имена должны быть сгенерированы для абсолютно каждого каталога в пути к файлу. Если хотя бы одна папка в пути (например, C:\Новая папка с длинным именем\file.dbf) была создана при отключенной поддержке 8.3, то весь путь не сможет быть сокращен.

Ниже мы рассмотрим три способа решения этой проблемы, начиная с самого простого и надежного.

Решение 1. Копирование файла во временный каталог с коротким именем

Это самый быстрый и гарантированный способ обойти ограничение XBase без вмешательства в настройки операционной системы клиентов. Мы просто создаем копию исходного файла в каталоге временных файлов, переименовывая его в случайное имя длиной не более 8 символов, обрабатываем его и затем удаляем.

Разберем по шагам реализацию этого механизма в коде 1С:


// Очищаем имя от пути и расширения для анализа
ФайлИсточник = Новый Файл(ПутьБДШ);
КаталогИсточника = ФайлИсточник.Путь;

// Генерируем уникальное имя длиной строго до 8 символов
// Стандартный ГУИД отлично подходит, если взять от него первые 8 символов
УникальныйПрефикс = Лев(Строка(Новый УникальныйИдентификатор()), 8);
ИмяВременногоФайла = УникальныйПрефикс + ".dbf";
ПутьКВременномуФайлу = КаталогВременныхФайлов() + ИмяВременногоФайла;

// Копируем исходный файл во временный каталог
Попытка
    КопироватьФайл(ПутьБДШ, ПутьКВременномуФайлу);
Исключение
    ВызватьИсключение "Не удалось скопировать файл во временный каталог: " + ОписаниеОшибки();
КонецПопытки;

// Работаем с временным файлом через стандартный XBase
БДШ = Новый XBase;
БДШ.ОтображатьУдаленные = Ложь;
БДШ.Кодировка = КодировкаXBase.ANSI;

Попытка
    БДШ.ОткрытьФайл(ПутьКВременномуФайлу,,0);
    Если БДШ.Открыта() Тогда
        // Выполняем чтение или запись данных
        Пока БДШ.Следующая() Цикл
            // Ваша логика обработки строк, например:
            // КодНоменклатуры = БДШ.ПолучитьЗначение("CODE");
        КонецЦикла;
        БДШ.ЗакрытьФайл();
    КонецЕсли;
Исключение
    // В случае ошибки обязательно закрываем файл, чтобы не заблокировать его в системе
    Если БДШ.Открыта() Тогда
        БДШ.ЗакрытьФайл();
    КонецЕсли;
    // Удаляем временный файл перед вызовом исключения
    УдалитьФайлы(ПутьКВременномуФайлу);
    ВызватьИсключение "Ошибка при обработке DBF: " + ОписаниеОшибки();
КонецПопытки;

// Удаляем временный файл после успешного завершения работы
УдалитьФайлы(ПутьКВременномуФайлу);

Преимущества: Работает абсолютно на любых компьютерах, независимо от операционной системы, настроек реестра, прав доступа и типа файловой системы.

Решение 2. Использование технологии ADODB (без ограничений на длину имени)

Если вы хотите полностью отказаться от устаревшего объекта XBase и не плодить временные файлы на диске, отличной альтернативой станет использование технологии ADO (ActiveX Data Objects). Microsoft Jet OLEDB драйвер позволяет работать с DBF-файлами как с таблицами базы данных с помощью обычных SQL-запросов. При этом ограничений на длину имени файла и пути к нему нет вообще.

Рассмотрим пример чтения данных через ADODB:


// Разделяем полный путь на каталог и имя файла
ФайлДанных = Новый Файл(ПутьБДШ);
КаталогПапки = ФайлДанных.Путь;
ИмяФайла = ФайлДанных.Имя;

Connection = Новый COMObject("ADODB.Connection");
Recordset = Новый COMObject("ADODB.Recordset");

// Формируем строку подключения. Указываем путь к папке как к источнику данных (Data Source)
СтрокаПодключения = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + КаталогПапки + ";Extended Properties=dBase IV;";

Попытка
    Connection.Open(СтрокаПодключения);
Исключение
    // Если Jet OLEDB не установлен (например, на 64-битных системах), пробуем ACE OLEDB
    СтрокаПодключения = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + КаталогПапки + ";Extended Properties=dBase IV;";
    Попытка
        Connection.Open(СтрокаПодключения);
    Исключение
        Предупреждение("Не удалось подключить драйвер DBF: " + ОписаниеОшибки());
        Возврат;
    КонецПопытки;
КонецПопытки;

// Запрос к файлу DBF. Имя файла выступает в роли таблицы
ТекстЗапроса = "SELECT * FROM [" + ИмяФайла + "]";

Попытка
    Recordset.Open(ТекстЗапроса, Connection);
    Пока Recordset.EOF = 0 Цикл
        // Доступ к полям по именам колонки
        ЗначениеПоля = Recordset.Fields("ИмяПоля").Value;
        
        // Переходим к следующей строке
        Recordset.MoveNext();
    КонецЦикла;
    Recordset.Close();
    Connection.Close();
Исключение
    Если Connection.State = 1 Тогда
        Connection.Close();
    КонецЕсли;
    Сообщить("Ошибка выполнения SQL-запроса к DBF: " + ОписаниеОшибки());
КонецПопытки;

Преимущества: Высокая скорость чтения больших объемов данных, возможность фильтрации и сортировки на уровне SQL-запроса, полное отсутствие проблем с длинными путями.

Решение 3. Включение поддержки коротких имен в Windows

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

Выполните следующие шаги на проблемном ПК:

  1. Откройте редактор реестра (нажмите Win + R, введите regedit и нажмите Enter).
  2. Перейдите по пути: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem.
  3. Найдите параметр NtfsDisable8dot3NameCreation. Установите его значение в 0 (включить создание коротких имен для всех томов) или 2 (определять параметры индивидуально для каждого тома).
  4. Если файлы лежат на конкретном несистемном диске (например, D:), откройте командную строку от имени Администратора и выполните команду проверки поддержки коротких имен: fsutil 8dot3name query D:
  5. Если поддержка отключена, включите ее командой: fsutil 8dot3name set D: 0
  6. Внимание! Чтобы короткие имена создались для уже существующих файлов, скопируйте всю папку с DBF-файлами в новое место, удалите старую папку, а затем верните скопированную обратно. При физическом перезаписывании файлов на диск операционная система сгенерирует для них новые короткие имена 8.3, и метод ShortPath в 1С заработает корректно.

Мы проанализировали причины сбоя при открытии DBF-файлов с длинными именами в 1С и изучили три способа решения проблемы. Наиболее универсальным и рекомендуемым является Решение 1 (создание временной копии с коротким именем) или переход на современную технологию ADODB, которая навсегда избавит вашу конфигурацию от зависимости от настроек операционной системы клиентов.

← На главную