При работе с выгрузкой данных во внешние файлы формата DBF (dBase) разработчики часто сталкиваются с неприятной ситуацией: в коде 1С всё написано верно, типы полей заданы корректно, но при открытии готового файла в Microsoft Excel даты выглядят «перепутанными» (например, вместо 1 мая отображается 5 января) или вовсе превращаются в длинную строку цифр. Разберем детально, почему так происходит, как на самом деле хранятся даты в DBF и какие инструменты использовать для диагностики.
Для начала проанализируем, как формат DBF (стандарт dBase) обрабатывает тип данных Date. В отличие от современных баз данных, где дата может храниться в бинарном виде, в классическом DBF поле типа "D" всегда имеет фиксированную длину — 8 символов. Внутри файла данные записываются в виде простой строки цифр в формате ГГГГММДД (YYYYMMDD).
Рассмотрим пример: если мы записываем дату 1 мая 2050 года (01.05.2050), то внутри файла физически будет записана последовательность 20500501. Если мы откроем такой файл обычным «Блокнотом», мы увидим именно эти цифры. Любые разделители (точки, слэши) или изменение порядка (ДД.ММ.ГГГГ) — это лишь результат визуализации данных программой, которой вы открыли файл.
Выясним причину, по которой автор темы столкнулся с «подменой» месяца и дня. Проблема кроется не в платформе 1С, а в механизмах импорта Microsoft Excel. Рассмотрим ситуацию по шагам:
ММ.ДД.ГГГГ (американский стандарт), Excel при чтении строки 20500501 может ошибочно интерпретировать число 05 как месяц, а 01 как день.20500519), Excel понимает, что 19-го месяца не существует. В этом случае его алгоритм «сдается», и он отображает данные как обычную строку текста — 20500519. Именно это и наблюдал автор вопроса.Важный вывод: никогда не используйте Microsoft Excel для проверки корректности структуры DBF-файла. Для этих целей необходимо использовать специализированные утилиты, такие как DBF Viewer, плагины для Total Commander или простые просмотрщики, которые показывают «сырые» данные заголовка и записей.
Посмотрим на пример кода, который правильно инициализирует структуру файла и записывает данные. Для работы с DBF в 1С используется объект XBase. Проанализируем правильный алгоритм создания поля даты:
НовыйФайл = Новый XBase;
// Добавляем поле типа "Дата". Длина для типа "D" всегда должна быть 8.
НовыйФайл.Поля.Добавить("GDATE", "D", 8);
НовыйФайл.СоздатьФайл("C:\Exports\data.dbf");
// Заполнение данных
НовыйФайл.Добавить();
НовыйФайл.GDATE = Дата(2050, 5, 1); // 1 мая 2050 года
НовыйФайл.Записать();
НовыйФайл.ЗакрытьФайл();
Обратите внимание на длину поля. В некоторых советах (как в сообщении №7 форума) предлагается указывать длину 10 символов. Однако для системного типа "D" в объекте XBase это избыточно. Платформа 1С жестко придерживается стандарта dBase, где под дату отводится 8 байт. Использование длины 10 может привести к тому, что поле будет воспринято как строковое (Character), что нарушит логику работы принимающих программ.
В процессе обсуждения возник вопрос: что записывать в поле, если дата неизвестна (например, срок годности не ограничен)? В 1С пустая дата — это 01.01.0001. В формате DBF стандартом «пустой» даты является строка из 8 пробелов.
При использовании объекта XBase вам не нужно вручную записывать пробелы. Если вы передадите в поле значение '00010101', объект автоматически сконвертирует его в нужный формат пробелов в файле. Использование «искусственных» дат вроде 2050 года (как делал автор) допустимо, но может вызвать вопросы у систем автоматизированного контроля на принимающей стороне.
Если стандартный объект XBase не подходит по специфическим причинам (например, нужно выполнить сложный SQL-запрос к DBF), можно воспользоваться механизмом ADO (ActiveX Data Objects). Разберем, как это помогает избежать проблем с типами:
При использовании провайдера Microsoft.Jet.OLEDB.4.0 вы работаете с DBF как с таблицей базы данных. В этом случае типизация происходит на уровне драйвера. Рассмотрим пример логики подключения:
Connection = Новый COMОбъект("ADODB.Connection");
// Указываем путь к папке, где лежит файл, как к базе данных
ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Exports\;Extended Properties=dBase IV";
Connection.Open(ConnectionString);
// Выполняем вставку данных через SQL
Command = Новый COMОбъект("ADODB.Command");
Command.ActiveConnection = Connection;
Command.CommandText = "INSERT INTO data.dbf (GDATE) VALUES ('2050/05/01')";
Command.Execute();
Connection.Close();
Этот метод более громоздкий, но он позволяет гарантированно передавать данные в том формате, который ожидает драйвер, исключая ошибки визуализации.
Хотя даты состоят из цифр, не стоит забывать о кодировке всего файла. В 1С при создании файла через XBase важно явно указывать кодировку. Если принимающая программа ожидает старый формат DOS, используйте КодировкаXBase.OEM, если современный Windows — КодировкаXBase.ANSI. Неверная кодировка заголовка файла может привести к тому, что Excel или другой просмотрщик «сдвинет» таблицу и начнет читать данные не из тех колонок, что также приведет к искажению дат.
Проанализировав проблему, мы можем составить краткий чек-лист для корректной выгрузки дат в DBF:
"D" и длиной 8.Дата, не пытайтесь преобразовать его в строку самостоятельно.'00010101').Соблюдение этих правил гарантирует совместимость ваших файлов с большинством государственных и банковских систем, использующих формат DBF для обмена данными.