Объект XBase в 1С 8.3: как открыть DBF, прочитать, записать и проиндексировать данные
Содержание
Для работы с 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С: открытие и кодировка
Подключение — это три строки кода. Главное — заранее выставить кодировку, иначе русские буквы превратятся в «кракозябры».
- Создайте объект:
База = Новый XBase;. - Укажите кодировку:
База.Кодировка = КодировкаXBase.OEM;для файлов из DOS-программ, FoxPro, Clipper и 1С 7.7;КодировкаXBase.ANSI— для файлов из Windows-программ и Excel. - Откройте файл:
База.ОткрытьФайл(ИмяФайла, ИмяИндексногоФайла, ТолькоЧтение). Второй и третий параметры необязательны. - Проверьте результат:
База.Открыта()вернётИстина. - После работы обязательно вызовите
База.ЗакрытьФайл().
&НаСервере
Функция ОткрытьDBF(ПутьКФайлу)
База = Новый XBase;
База.Кодировка = КодировкаXBase.OEM;
База.ОткрытьФайл(ПутьКФайлу, , Истина); // только чтение
Если Не База.Открыта() Тогда
ВызватьИсключение "Не удалось открыть файл " + ПутьКФайлу;
КонецЕсли;
Возврат База;
КонецФункции
Как понять кодировку, не открывая файл в редакторе: откройте DBF с OEM и выведите первое строковое поле. Если вместо текста символы псевдографики — переключите на ANSI.
Если файл у пользователя, а код работает на сервере
Путь C:\Users\... с компьютера бухгалтера сервер 1С не видит. Порядок такой:
- На клиенте пользователь выбирает файл, его содержимое помещают во временное хранилище (
ПоместитьФайлилиНачатьПомещениеФайла). - На сервере получают двоичные данные из хранилища:
ПолучитьИзВременногоХранилища(Адрес). - Записывают их во временный файл:
ИмяФайла = ПолучитьИмяВременногоФайла("dbf"); ДД.Записать(ИмяФайла);. - Открывают этот файл через
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С.
- Несопоставленные строки показывают пользователю отдельным списком, а не теряют молча.
Перенос справочников из 1С:Предприятия 7.7
В файловой базе 7.7 справочники и документы лежат в DBF, а имена таблиц зашифрованы (SC123.DBF для справочников, DH456.DBF для шапок документов). Соответствие имён и реквизитов описано в файле 1Cv7.DD.
Для разового переноса проще стандартных средств миграции ничего не придумать. Прямое чтение DBF через XBase оправдано, когда нужно вытащить данные из базы, которую уже не открыть в 7.7, например из архива без рабочей конфигурации.
Выгрузка для внешней программы
Обратная задача: сторонняя система принимает данные только в DBF. Создайте файл с нужной структурой (Поля.Добавить → СоздатьФайл), уточните у получателя кодировку и формат дат. Именно на кодировке такие выгрузки обычно и ломаются.