При работе с внешними источниками данных в формате DBF программисты часто сталкиваются с досадным ограничением встроенного объекта 1С XBase. Несмотря на то что современные операционные системы давно поддерживают длинные имена файлов, объект XBase во многих случаях продолжает требовать соблюдения старого стандарта DOS — так называемого формата 8.3 (не более 8 символов в имени и не более 3 в расширении). Проанализируем, почему эта проблема проявляется избирательно и какими способами её можно гарантированно решить.
Рассмотрим ситуацию, когда один и тот же код успешно открывает файл с длинным именем на одном компьютере, но выдает ошибку на другом. Главная причина кроется в настройках файловой системы NTFS и механизме генерации коротких имен. Исторически Windows создает для каждого файла два имени: длинное (LFN) и короткое (MS-DOS совместимое). Объект XBase внутри платформы 1С обращается именно к короткому пути.
Проанализируем основные факторы, влияющие на доступность коротких имен:
ShortPath объекта FileSystemObject вернет обычное длинное имя, которое 1С не сможет обработать.MAX_PATH (обычно 260 символов). Однако для XBase критичным является именно формат имени конечного файла.Если нам необходимо продолжать использовать объект XBase, самым надежным решением будет временное копирование исходного файла в каталог, где мы можем гарантировать корректное имя. Разберем по шагам, как реализовать этот алгоритм. Мы возьмем исходный файл с длинным названием, скопируем его во временную папку под именем, не превышающим 8 символов, обработаем данные и удалим временную копию.
Рассмотрим программный код, реализующий данный подход:
// Определяем исходный путь к файлу
ПутьКФайлу = "C:\Data\VeryLongFileName_2023_05_10.dbf";
ФайлИст = Новый Файл(ПутьКФайлу);
// Формируем имя для временного файла (берем первые 8 символов или создаем уникальное)
ИмяВременногоФайла = "temp_dbf.dbf";
ПолныйПутьВременногоФайла = КаталогВременныхФайлов() + ИмяВременногоФайла;
// Копируем файл во временное хранилище
КопироватьФайл(ПутьКФайлу, ПолныйПутьВременногоФайла);
// Работаем с DBF через XBase
БДШ = Новый XBase;
БДШ.Кодировка = КодировкаXBase.ANSI;
Попытка
БДШ.ОткрытьФайл(ПолныйПутьВременногоФайла);
Если БДШ.Открыта() Тогда
БДШ.Первая();
Пока Не БДШ.ВКонце() Цикл
// Читаем данные, например, поле "NAME"
Сообщить(БДШ.NAME);
БДШ.Следующая();
КонецЦикла;
БДШ.ЗакрытьФайл();
КонецЕсли;
Исключение
Сообщить("Ошибка при работе с DBF: " + ОписаниеОшибки());
КонецПопытки;
// Обязательно удаляем временный файл после работы
УдалитьФайлы(ПолныйПутьВременногоФайла);
Важный нюанс: Если ваш DBF-файл имеет связанные индексные файлы (например, .cdx), их также необходимо копировать во временный каталог под соответствующими короткими именами, иначе XBase не сможет корректно открыть таблицу или вызовет ошибку несоответствия индексов.
Если вы хотите навсегда избавиться от проблем с именами 8.3, пробелами в путях и кириллицей, рекомендуем рассмотреть использование ADO. Этот метод позволяет работать с DBF-файлом как с полноценной базой данных через SQL-запросы. В этом случае ограничение в 8 символов перестает существовать, так как драйвер (Microsoft Jet или ACE) корректно обрабатывает длинные имена на уровне операционной системы.
Разберем пример подключения к DBF через ADO:
// Путь к каталогу, где лежит файл
КаталогФайла = "C:\My Very Long Path Name\";
// Имя файла (может быть длинным)
ИмяФайла = "Record_From_External_System_2023.dbf";
Connection = Новый COMObject("ADODB.Connection");
RecordSet = Новый COMObject("ADODB.Recordset");
// Строка подключения для провайдера Jet (для 32-битных систем)
// Для 64-битных систем используйте Microsoft.ACE.OLEDB.12.0
ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + КаталогФайла + ";Extended Properties=dBase IV;";
Попытка
Connection.Open(ConnectionString);
// Текст SQL-запроса. Обратите внимание: имя файла указывается как имя таблицы
ТекстЗапроса = "SELECT * FROM [" + ИмяФайла + "]";
RecordSet.Open(ТекстЗапроса, Connection);
Пока RecordSet.EOF = 0 Цикл
// Обработка данных
ЗначениеПоля = RecordSet.Fields("MSG").Value;
Сообщить(ЗначениеПоля);
RecordSet.MoveNext();
КонецЦикла;
RecordSet.Close();
Connection.Close();
Исключение
Сообщить("Ошибка ADO: " + ОписаниеОшибки());
КонецПопытки;
Этот способ является более профессиональным и современным. Он позволяет не только обходить ограничения на длину имени, но и выполнять фильтрацию и сортировку данных средствами SQL еще на этапе чтения файла, что значительно ускоряет работу при больших объемах данных.
Проанализируем ситуацию и выберем оптимальный путь решения задачи. Если ваша задача разовая, а обработка написана на скорую руку для старой конфигурации, то Способ 1 с копированием файла во временную папку будет самым быстрым в реализации. Он требует минимум изменений в логике работы с данными, так как вы продолжаете использовать привычный объект XBase.
Однако, если вы разрабатываете тиражное решение или критически важный механизм обмена данными, лучше один раз потратить время на внедрение Способа 2 (ADO). Это избавит вас от необходимости администрировать настройки Windows на клиентских машинах (включать поддержку 8.3 в реестре) и обеспечит стабильную работу программы вне зависимости от того, как назван файл или папка.
Подведем итог: ошибка XBase — это ограничение старых библиотек, заложенных в платформу. Мы можем либо подстроиться под них, эмулируя среду DOS через временные файлы, либо использовать современные интерфейсы доступа к данным, которые лишены этих пережитков прошлого. Выбор метода зависит от ваших архитектурных задач и требований к надежности системы.