При интеграции 1С со сторонними информационными системами, банками или государственными реестрами часто возникает требование формировать файлы выгрузки в формате DBF определенной спецификации — например, dBase IV. Разберем, почему штатные средства не всегда позволяют получить нужный формат и какими способами можно сформировать файл dBase IV программно.
Проанализируем частую ошибку разработчиков: попытку изменить строку фильтра в объекте ДиалогВыбораФайла.
Свойство Фильтр объекта ДиалогВыбораФайла управляет исключительно маской отображения файлов в графическом интерфейсе операционной системы для пользователя. Строка "Файлы DBASE IV (*.dbf)|*.dbf" не передает никаких параметров низкоуровневым процедурам записи и не способна изменить внутреннюю структуру генерируемого файла.
Выясним причину, по которой штатный механизм платформы формирует файлы устаревшей версии. Встроенный объект XBase ориентирован исключительно на спецификацию dBase III (или dBase III+ при наличии memo-полей). При создании новой таблицы методом СоздатьФайл() платформа 1С автоматически записывает в нулевой байт заголовка сигнатуру 0x03 (или 0x83). Встроенный язык 1С не содержит штатных свойств или методов в объекте XBase для переключения версии формата на dBase IV, FoxPro или Clipper.
Версия структуры таблицы DBF всегда жестко зафиксирована в самом первом байте файла (смещение 0 в заголовке):
Посмотрим на пример функции, которая считывает первый байт файла средствами встроенного языка 1С без сторонних утилит:
Функция ПолучитьКодВерсииDBF(ПутьКФайлу)
Файл = Новый Файл(ПутьКФайлу);
Если Не Файл.Существует() Тогда
Возврат Неопределено;
КонецЕсли;
Чтение = Новый ЧтениеДанных(ПутьКФайлу);
БайтВерсии = Чтение.ПрочитатьБайт();
Чтение.Закрыть();
Возврат БайтВерсии;
КонецФункции
Рассмотрим основной и наиболее корректный способ создания файла dBase IV на платформе Windows — использование провайдера OLE DB через объект ADODB.Connection. В строке подключения явно передается параметр Extended Properties="dBASE IV;".
Разберем реализацию по шагам:
Процедура СоздатьИЗаполнитьDBF4(КаталогФайла, ИмяТаблицы)
// Создаем COM-объект соединения с базой данных
Соединение = Новый COMОбъект("ADODB.Connection");
// Формируем строку подключения к каталогу с указанием драйвера dBASE IV
СтрокаПодключения = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + КаталогФайла + ";Extended Properties=""dBASE IV;"";";
Попытка
Соединение.Open(СтрокаПодключения);
Исключение
// При работе на 64-разрядном сервере может потребоваться провайдер ACE
СтрокаПодключения = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + КаталогФайла + ";Extended Properties=""dBASE IV;"";";
Соединение.Open(СтрокаПодключения);
КонецПопытки;
// Создаем структуру таблицы SQL-запросом
ТекстСоздания = "CREATE TABLE " + ИмяТаблицы + " (
| CODE CHAR(10),
| NAME CHAR(50),
| SUMMA NUMERIC(15, 2)
|)";
Соединение.Execute(ТекстСоздания);
// Добавляем запись в созданную таблицу
ТекстВставки = "INSERT INTO " + ИмяТаблицы + " (CODE, NAME, SUMMA) VALUES ('001', 'Тестовая строка', 1500.50)";
Соединение.Execute(ТекстВставки);
Соединение.Close();
КонецПроцедуры
Если принимающая программа не требует специфических типов полей dBase IV, а лишь валидирует сигнатуру формата в заголовке файла, можно сформировать файл через штатный XBase, а затем изменить сигнатурный байт с 0x03 на 0x04.
Посмотрим на пример реализации данного алгоритма:
XBase.ЗакрытьФайл(), чтобы освободить дескриптор.
Процедура ИсправитьСигнатуруНаDBase4(ПутьКФайлу)
// Читаем все двоичные данные файла
Двоичные = Новый ДвоичныеДанные(ПутьКФайлу);
Размер = Двоичные.Размер();
Чтение = Новый ЧтениеДанных(Двоичные);
// Пропускаем первый байт (версию dBase III)
Чтение.ПрочитатьБайт();
// Считываем оставшуюся часть файла
ОстатокДанных = Чтение.Прочитать();
Чтение.Закрыть();
// Записываем обновленные данные обратно
Запись = Новый ЗаписьДанных(ПутьКФайлу);
// Пишем байт 0x04 (dBase IV без memo)
Запись.ЗаписатьБайт(4);
// Дописываем исходное тело файла
Запись.Записать(ОстатокДанных);
Запись.Закрыть();
КонецПроцедуры
Рассмотрим еще один практичный подход, исключающий необходимость генерации DDL-скриптов на стороне 1С:
INSERT INTO) либо через сторонние консольные утилиты.