Объект XBase в 1С 8.3: как открыть DBF, прочитать, записать и проиндексировать данные

· 9 мин

Содержание

Для работы с DBF-файлами в 1С 8.3 есть встроенный объект XBase: База = Новый XBase;, затем База.ОткрытьФайл("C:\data\clients.dbf") — и записи читаются циклом Первая() / Следующая(). Внешние драйверы, ODBC и COM для этого не нужны. Индексы объект понимает в формате CDX (FoxPro), кодировку задают свойством Кодировка — ANSI или OEM.

Есть и другие пути: ADO через COM-объект или выгрузка DBF в Excel/CSV. Их выбирают, когда в файле есть мемо-поля или нужен SQL-запрос к таблице. В остальных случаях XBase проще и надёжнее: он работает и в 32-, и в 64-битной платформе, и на сервере под Linux.

Что такое XBase и зачем он нужен в 1С

XBase — общее название семейства форматов dBase, FoxPro и Clipper. Данные лежат в файле .dbf, индексы — в .cdx (или .ntx, .mdx у других диалектов). Формат старый, но до сих пор встречается:

  • 🏦 выгрузки банковских и казначейских программ;
  • 📦 прайс-листы поставщиков из старых складских систем;
  • 🗂 справочник адресов КЛАДР (до перехода на ФИАС и ГАР он распространялся именно в DBF);
  • 🧾 данные из 1С:Предприятия 7.7 файлового варианта — там таблицы хранились в DBF с индексами CDX;
  • 🔧 самописные программы на FoxPro и Clipper, которые всё ещё работают в отделах.

Объект XBase в 1С 8.3 умеет открывать такие таблицы, перемещаться по записям, искать по индексу, добавлять, менять и помечать записи на удаление. Он доступен на сервере, в толстом клиенте и во внешнем соединении. В тонком и веб-клиенте объекта нет — код с ним пишут в процедуре &НаСервере.

Что поддерживается, а что нет

ВозможностьXBase в 1СКомментарий
Типы полей N, S (C), D, L✅число, строка, дата, булево
Мемо-поля (файлы .fpt, .dbt)❌читайте через ADO или конвертируйте
Индексы CDX✅создание, открытие, поиск
Индексы NTX, MDX❌переиндексируйте в CDX или читайте без индекса
КодировкиANSI, OEMчерез КодировкаXBase
SQL-запросы к таблице❌только последовательный обход и поиск по индексу

Имена полей в DBF — до 10 символов, латиница в верхнем регистре. Строковое поле — не длиннее 254 символов.

Как подключить DBF-файл к 1С: открытие и кодировка

Подключение — это три строки кода. Главное — заранее выставить кодировку, иначе русские буквы превратятся в «кракозябры».

  1. Создайте объект: База = Новый XBase;.
  2. Укажите кодировку: База.Кодировка = КодировкаXBase.OEM; для файлов из DOS-программ, FoxPro, Clipper и 1С 7.7; КодировкаXBase.ANSI — для файлов из Windows-программ и Excel.
  3. Откройте файл: База.ОткрытьФайл(ИмяФайла, ИмяИндексногоФайла, ТолькоЧтение). Второй и третий параметры необязательны.
  4. Проверьте результат: База.Открыта() вернёт Истина.
  5. После работы обязательно вызовите База.ЗакрытьФайл().
&НаСервере
Функция ОткрытьDBF(ПутьКФайлу)
    База = Новый XBase;
    База.Кодировка = КодировкаXBase.OEM;
    База.ОткрытьФайл(ПутьКФайлу, , Истина); // только чтение
    Если Не База.Открыта() Тогда
        ВызватьИсключение "Не удалось открыть файл " + ПутьКФайлу;
    КонецЕсли;
    Возврат База;
КонецФункции

Как понять кодировку, не открывая файл в редакторе: откройте DBF с OEM и выведите первое строковое поле. Если вместо текста символы псевдографики — переключите на ANSI.

Если файл у пользователя, а код работает на сервере

Путь C:\Users\... с компьютера бухгалтера сервер 1С не видит. Порядок такой:

  1. На клиенте пользователь выбирает файл, его содержимое помещают во временное хранилище (ПоместитьФайл или НачатьПомещениеФайла).
  2. На сервере получают двоичные данные из хранилища: ПолучитьИзВременногоХранилища(Адрес).
  3. Записывают их во временный файл: ИмяФайла = ПолучитьИмяВременногоФайла("dbf"); ДД.Записать(ИмяФайла);.
  4. Открывают этот файл через XBase, обрабатывают и удаляют: УдалитьФайлы(ИмяФайла).

Если к DBF прилагается индекс .cdx, передайте на сервер и его, сохранив с тем же именем.

Чтение и запись данных DBF: примеры кода

Поле читается как свойство объекта: База.INN, База.NAME. Строки приходят дополненными пробелами справа, поэтому их почти всегда обрезают СокрП().

Обход всех записей

База = ОткрытьDBF(ИмяФайла);
Таблица = Новый ТаблицаЗначений;
Таблица.Колонки.Добавить("ИНН");
Таблица.Колонки.Добавить("Наименование");
Таблица.Колонки.Добавить("Сумма");

ЕстьЗапись = База.Первая();
Пока ЕстьЗапись Цикл
    Если Не База.ЗаписьУдалена() Тогда
        Стр = Таблица.Добавить();
        Стр.ИНН          = СокрЛП(База.INN);
        Стр.Наименование = СокрП(База.NAME);
        Стр.Сумма        = База.SUMMA;
    КонецЕсли;
    ЕстьЗапись = База.Следующая();
КонецЦикла;

База.ЗакрытьФайл();

Первая() и Следующая() возвращают Ложь, когда записей больше нет. Альтернатива — условие Пока Не База.ВКонце() Цикл, но тогда на пустом файле нужна отдельная проверка База.КоличествоЗаписей() > 0.

Записи, помеченные на удаление, по умолчанию не показываются. Если нужны и они — поставьте База.ОтображатьУдаленные = Истина и проверяйте ЗаписьУдалена(), как в примере.

Создание нового DBF-файла

Структуру описывают до создания файла: сначала поля, потом индексы, затем СоздатьФайл().

База = Новый XBase;
База.Кодировка = КодировкаXBase.ANSI;

// Имя, тип, длина, точность
База.Поля.Добавить("INN",   "S", 12, 0);
База.Поля.Добавить("NAME",  "S", 100, 0);
База.Поля.Добавить("SUMMA", "N", 15, 2);
База.Поля.Добавить("DOCDT", "D", 8, 0);
База.Поля.Добавить("PAID",  "L", 1, 0);

База.Индексы.Добавить("BYINN", "INN");

База.СоздатьФайл("C:\exchange\pay.dbf", "C:\exchange\pay.cdx");

Добавление и изменение записей

База.Добавить();
База.INN   = "7701234567";
База.NAME  = "ООО Ромашка";
База.SUMMA = 15400.50;
База.DOCDT = '20261005';
База.PAID  = Ложь;
База.Записать();

Чтобы изменить существующую запись, встаньте на неё (обходом, через Найти() или Перейти(НомерЗаписи)), присвойте новые значения полям и вызовите Записать().

Удаление записей

  • Удалить() только ставит пометку — запись остаётся в файле.
  • Восстановить() снимает пометку.
  • Сжать() физически убирает помеченные записи и перестраивает файл.

Сжать() переписывает файл целиком. Сделайте копию DBF и CDX и убедитесь, что файл не открыт другой программой.

Индексы CDX и поиск записи

Без индекса найти запись можно только полным обходом. На файле в 200 000 строк это ощутимо долго, особенно если искать много раз. Индекс решает задачу.

Открыть готовый индекс — передать его вторым параметром: База.ОткрытьФайл("pay.dbf", "pay.cdx", Истина).

Создать индекс к существующему файлу:

База.Индексы.Добавить("BYINN", "INN");
База.СоздатьИндексныйФайл("C:\exchange\pay.cdx");

Поиск:

База.ТекущийИндекс = База.Индексы.BYINN;
Если База.Найти("7701234567", "=") Тогда
    Сумма = База.SUMMA;
КонецЕсли;

Второй параметр Найти() — режим сравнения: "=", ">", ">=", "<", "<=". Режим ">=" удобен для поиска по началу диапазона: найти первую запись не меньше ключа, а дальше идти Следующая(), пока значение поля подходит.

Ключ поиска должен совпадать с полем по длине и формату. Если поле INN длиной 12, а ИНН организации — 10 цифр, в индексе он хранится с двумя пробелами справа. Ищите "=" по строке, дополненной до длины поля, или ищите ">=" и сравнивайте СокрП(База.INN).

Как ускорить обработку больших DBF

Сам по себе XBase быстрый. Медленными обычно бывают сетевая папка и запись в базу 1С внутри цикла.

ПриёмЧто даёт
Скопировать файл с сетевого диска во временный каталог сервераЧтение по сети построчно — самое узкое место
Открывать с ТолькоЧтение = ИстинаНет блокировок файла для других программ
Сначала собрать данные в ТаблицаЗначений, потом писать в 1СОбход DBF не ждёт записи документов
Записывать регистры через НаборЗаписей пакетамиОдна запись набора вместо тысяч мелких
Искать соответствия через запрос с временной таблицейОдин запрос вместо НайтиПоРеквизиту на каждую строку
Индекс для повторяющегося поискаПоиск по ключу вместо полного обхода

Пример: загрузка прайса на 50 000 позиций. Если для каждой строки искать номенклатуру через НайтиПоРеквизиту("Артикул", ...), получится 50 000 обращений к базе. Если же выгрузить DBF в таблицу значений, передать её в запрос как временную таблицу и соединить с номенклатурой по артикулу — обращение одно.

Транзакцию на всю загрузку целиком не открывайте: при большом объёме она долго держит блокировки и мешает другим пользователям. Разумнее фиксировать порциями, например по 1000 записей.

XBase в 64-битной 1С и на сервере

Здесь у встроенного объекта главное преимущество. XBase — часть платформы, ему не нужны внешние драйверы. Поэтому он одинаково работает:

  • 🖥 в 32- и 64-битном толстом клиенте;
  • 🗄 на 64-битном сервере 1С под Windows;
  • 🐧 на сервере под Linux (пути пишите в формате /var/exchange/pay.dbf, имена файлов чувствительны к регистру).

Проблемы с разрядностью возникают, когда вместо XBase используют ADO. Провайдер Microsoft.Jet.OLEDB.4.0 и драйвер Visual FoxPro OLE DB существуют только в 32-битном варианте. На 64-битном сервере 1С строка подключения с ними не сработает. Выход — провайдер Microsoft.ACE.OLEDB.12.0 нужной разрядности или переход на XBase.

Учётная запись, под которой работает служба сервера 1С (по умолчанию USR1CV8), должна иметь права на чтение и запись каталога с DBF. Если файл лежит в сетевой папке, права нужны этой учётной записи, а не пользователю, который нажал кнопку.

Ошибки при работе с DBF в 1С и что с ними делать

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

Список полей неизвестного файла удобно вывести так:

Для Каждого Поле Из База.Поля Цикл
    Сообщить(Поле.Имя + " | " + Поле.Тип + " | " + Формат(Поле.Длина, "ЧГ=0"));
КонецЦикла;

Примеры реальных задач с DBF в 1С

Загрузка выписки или реестра из банковской программы

Старые клиент-банки и зарплатные проекты до сих пор отдают реестры в DBF в кодировке OEM. Схема загрузки:

  1. Пользователь выбирает файл, он уходит на сервер через временное хранилище.
  2. На сервере файл открывается только на чтение, записи собираются в таблицу значений.
  3. Запросом сопоставляют ИНН контрагентов или табельные номера с данными 1С.
  4. Несопоставленные строки показывают пользователю отдельным списком, а не теряют молча.

Перенос справочников из 1С:Предприятия 7.7

В файловой базе 7.7 справочники и документы лежат в DBF, а имена таблиц зашифрованы (SC123.DBF для справочников, DH456.DBF для шапок документов). Соответствие имён и реквизитов описано в файле 1Cv7.DD.

Для разового переноса проще стандартных средств миграции ничего не придумать. Прямое чтение DBF через XBase оправдано, когда нужно вытащить данные из базы, которую уже не открыть в 7.7, например из архива без рабочей конфигурации.

Выгрузка для внешней программы

Обратная задача: сторонняя система принимает данные только в DBF. Создайте файл с нужной структурой (Поля.Добавить → СоздатьФайл), уточните у получателя кодировку и формат дат. Именно на кодировке такие выгрузки обычно и ломаются.

Перед отправкой DBF во внешнюю программу
Выполнено: 0 / 6

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

Можно ли работать с XBase в тонком клиенте?
Нет. Объект доступен на сервере, в толстом клиенте и во внешнем соединении. В управляемой форме код пишут в серверной процедуре, а файл передают через временное хранилище.
Чем XBase лучше чтения DBF через ADO?
Не нужны драйверы, нет проблем с разрядностью, код работает и на Linux. ADO выигрывает, когда нужны SQL-запросы или мемо-поля.
Можно ли открыть DBF из 1С, пока он открыт в другой программе?
Только на чтение и только если другая программа не держит файл монопольно. Для записи файл должен быть свободен.
Почему после Удалить() размер файла не меняется?
Удаление только помечает запись. Физически записи убирает метод Сжать().
Как открыть DBF в Excel для проверки?
Современный Excel открывает DBF только на чтение. Для быстрой проверки содержимого этого достаточно; для правки удобнее отдельный просмотрщик DBF.