Формат DBF (dBase) исторически остается популярным средством интеграции систем, особенно когда одной из сторон обмена выступает старое унаследованное ПО (legacy-системы) или специализированное оборудование. Однако, будучи по своей природе плоской двумерной таблицей, DBF плохо подходит для передачи иерархических и реляционных структур данных, таких как документы 1С с их табличными частями и ссылочными реквизитами (контрагенты, номенклатура со своими свойствами и т.д.).
В рамках этой статьи мы подробно разберем, как спроектировать надежный, быстрый и удобный обмен данными через DBF, избежав создания «таблиц-монстров» с сотнями колонок. Мы рассмотрим архитектуру разделения файлов, порядок загрузки данных, а также важные технические нюансы работы с объектом XBase в платформе 1С:Предприятие.
---
При проектировании выгрузки документов (например, накладных) вместе со справочной информацией (данные контрагентов, реквизиты номенклатуры) у разработчика часто возникает соблазн упаковать все данные в одну строку одного DBF-файла. В этом случае строка таблицы выглядит следующим образом:
НомерДокумента | Дата | Контрагент | ИННКонтрагента | Номенклатура | Артикул | Количество | Цена
Недостатки «плоского» подхода:
Рекомендуемое решение — реляционный подход (несколько файлов).
Правильным решением является разделение выгрузки на несколько специализированных DBF-файлов, которые связаны между собой по ключевым полям (кодам или уникальным идентификаторам GUID). Это классическая схема, по которой строились базы данных в 1С:Предприятии версии 7.7.
Для обмена документами нам понадобятся следующие файлы:
ID, NAME, INN, KPP).ID, NAME, ARTICLE, UNIT).DOC_ID, NUMBER, DATE, CONTR_ID).DOC_ID, GOODS_ID, QUANTITY, PRICE, SUM).---
Чтобы гарантировать ссылочную целостность данных в базе 1С, загрузку необходимо выполнять строго в определенной последовательности. Разберем этот процесс по шагам.
Перед тем как приступать к созданию документов, мы должны убедиться, что все объекты, на которые ссылается документ, уже существуют в информационной базе 1С. Поэтому первыми мы открываем и обрабатываем файлы справочников: сначала contr.dbf, затем goods.dbf.
При обходе строк файлов справочников мы выполняем поиск элементов в базе 1С по ключевому полю (например, по Коду, Артикулу или ИНН). Если элемент найден — обновляем его реквизиты, если не найден — создаем новый.
После того как справочники загружены, мы приступаем к обработке документов. Чтение документов происходит в связке файлов docs.dbf и doc_lines.dbf:
docs.dbf.CONTR_ID (которое мы гарантированно загрузили на Шаге 1).DOC_ID находим все строки в файле табличных частей doc_lines.dbf.GOODS_ID, заполняем количество, цену и добавляем строку в документ 1С.---
Для работы с файлами DBF в платформе 1С:Предприятие используется встроенный объект XBase. Рассмотрим пример кода, который реализует чтение справочника номенклатуры и создание элементов в базе данных 1С.
// Функция загружает номенклатуру из указанного DBF-файла
Процедура ЗагрузитьНоменклатуруИзDBF(ПутьКФайлу) Экспорт
ФайлDBF = Новый XBase;
// Важно: Указываем кодировку файла.
// Обычно сторонние системы выгружают в OEM (DOS-кодировка) или ANSI (Windows-кодировка).
ФайлDBF.Кодировка = КодировкаXBase.ANSI;
Попытка
ФайлDBF.ОткрытьФайл(ПутьКФайлу);
Исключение
ЗаписьЖурналаРегистрации("Обмен данными", УровеньЖурналаРегистрации.Ошибка, , ,
"Не удалось открыть файл DBF: " + ОписаниеОшибки());
Возврат;
КонецПопытки;
Если Не ФайлDBF.Открыт() Тогда
Возврат;
КонецЕсли;
// Переходим к первой записи файла
ФайлDBF.Первая();
НачатьТранзакцию();
Попытка
Пока Не ФайлDBF.ВКонце() Цикл
// Чтение значений полей текущей записи.
// Имена свойств объекта соответствуют именам колонок в DBF.
КодИсточник = СокрЛП(ФайлDBF.ID);
Наименование = СокрЛП(ФайлDBF.NAME);
Артикул = СокрЛП(ФайлDBF.ARTICLE);
// Поиск существующего элемента в справочнике 1С
СсылкаНаТовар = Справочники.Номенклатура.НайтиПоРеквизиту("КодИсточника", КодИсточник);
Если СсылкаНаТовар.Пустая() Тогда
НовыйТовар = Справочники.Номенклатура.СоздатьЭлемент();
НовыйТовар.КодИсточника = КодИсточник;
Иначе
НовыйТовар = СсылкаНаТовар.ПолучитьОбъект();
КонецЕсли;
НовыйТовар.Наименование = Наименование;
НовыйТовар.Артикул = Артикул;
// Записываем элемент справочника
НовыйТовар.Записать();
// Переходим к следующей строке DBF
ФайлDBF.Следующая();
КонецЦикла;
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ФайлDBF.ЗакрытьФайл();
ВызватьИсключение "Ошибка при загрузке данных: " + ОписаниеОшибки();
КонецПопытки;
// Обязательно закрываем файл после завершения работы
ФайлDBF.ЗакрытьФайл();
КонецПроцедуры
---
При разработке реальных промышленных обменов данными через DBF программист 1С обязательно столкнется со специфическими ограничениями формата и платформы. Разберем наиболее важные из них.
В базах данных типа FoxPro или Clipper для хранения длинных строк (более 254 символов) или бинарных данных используются так называемые Memo-поля. Физически они хранятся в сопутствующих файлах с расширениями .FPT или .DBT.
Внимание: Встроенный объект 1С XBase не поддерживает чтение и запись Memo-полей. Попытка прочесть такое поле вернет пустую строку или вызовет аппаратную ошибку. Если система-источник выгружает важные данные в Memo-поля (например, длинные описания товаров или адреса контрагентов), вам придется отказаться от XBase и использовать альтернативные методы чтения:
VFPOLEDB (Visual FoxPro OLE DB Provider).Текстовые данные в DBF часто загружаются в виде «кракозябр». Это происходит из-за несовпадения кодировки при записи и чтении. Обязательно согласуйте кодировку с разработчиками выгружающей системы. Перед открытием файла в 1С всегда явно устанавливайте свойство Кодировка:
ФайлDBF.Кодировка = КодировкаXBase.OEM; — если файл выгружен в DOS-кодировке (CP866).ФайлDBF.Кодировка = КодировкаXBase.ANSI; — если файл выгружен в Windows-кодировке (CP1251).Если вам необходимо выполнять частые поиски внутри больших DBF-файлов (например, при обходе файла табличных частей искать строки, соответствующие текущему документу), последовательный перебор файла с самого начала превратит загрузку в крайне медленный процесс. Для решения этой проблемы используются индексы.
Объект XBase позволяет создавать индексные файлы и осуществлять быстрый поиск методом Найти(). Однако индексы, созданные сторонними программами, часто несовместимы с 1С и вызывают ошибки чтения. Рекомендуется передавать файлы без индексов, а сами индексные файлы создавать программно силами 1С непосредственно перед началом чтения:
ФайлDBF = Новый XBase;
ФайлDBF.ОткрытьФайл("C:\Exchange\doc_lines.dbf");
// Создаем индекс по полю DOC_ID для быстрого поиска строк документа
ФайлDBF.СоздатьИндексныйФайл("C:\Exchange\doc_lines.cdx");
ФайлDBF.ДобавитьИндекс("DocIndex", "DOC_ID", Ложь, Ложь, "");
ФайлDBF.УстановитьИндекс("DocIndex");
Файловый обмен подвержен сбоям: во время копирования или чтения файлов может пропасть сеть, отключиться питание компьютера или заблокироваться файл другим процессом. Если загрузка прервется на середине, в базе 1С останутся «полузагруженные» документы или справочники без подчиненных данных.
Для предотвращения этой ситуации используйте двухфазный импорт:
ТаблицаЗначений) в оперативной памяти 1С. На этом этапе база данных 1С не изменяется. Если на этом шаге произошел сбой чтения, процесс прерывается без последствий для информационной базы.НачатьТранзакцию(). Быстро запишите все подготовленные данные из таблиц значений в справочники и документы 1С. В случае успешного завершения зафиксируйте транзакцию (ЗафиксироватьТранзакцию()), при любой ошибке — откатите изменения (ОтменитьТранзакцию()).---
Если перед вами стоит задача регулярного и сложного анализа DBF-файлов, хорошей альтернативой ручному написанию кода на базе XBase является механизм платформы 1С:Предприятие 8 — Внешние источники данных.
Вы можете настроить подключение к каталогу с файлами DBF через ODBC. В этом случае таблицы DBF будут выглядеть в конфигураторе 1С как обычные таблицы базы данных. Вы сможете:
ЛЕВОЕ СОЕДИНЕНИЕ для связывания таблиц документов и справочников прямо в тексте запроса.