Как создать файл dbf и определить кодировку в Блокноте или VBA

что такое основной формат файла DBF4 (dBase IV)(*.dbf)? И как создать этот файл в том же текстовом редакторе, что и Notepad, с вводом текста? (Обновление: или Excel VBA?)

Что это за спецификации формата:

  • Delimiter (то же, что: , или tab и т. д.)
  • Separator (может То же, что и выше!) (Если эти два слова не являются синонимами)
  • Row End символ: (то же, что vbCrLf)
  • Определение заголовков столбцов (полей).
  • Code-Page из encoding: (то же, что: Unicode - 1256 и т. д.)
  • и другие...

Пожалуйста, представьте алгоритм для создания этого формата файла DB, который позволил нам легко создать тот же файл с помощью метода VBA, который создает текстовый файл. (Обновите или используйте встроенные методы VBA или его ссылки.)

Я использую ниже для создания текстового файла.

Sub CsvExportRange(rngRange As Object, strFileName As String, strCharset, strSeparator As String, strRowEnd As String, NVC As Boolean) 'NVC: _
Null Value Control (If cell contain Null value, suppose reached end of range), d: delimiter

Dim rngRow As Range
Dim objStream As Object
Dim i, lngFR, lngLR As Long 'lngFR: First Row, lngLR: Last Row

lngFR = rngRange.SpecialCells(xlCellTypeVisible).Rows(1).row - rngRange.Rows(1).row + 1
lngLR = rngRange.End(xlDown).row - rngRange.Rows(1).row + 1

Set objStream = CreateObject("ADODB.Stream")
objStream.Type = 2
objStream.Charset = strCharset
objStream.Open

For i = lngFR To lngLR
    If Not (rngRange.Rows(i).EntireRow.Hidden) Then
        If IIf(NVC, (Cells(i + rngRange.Rows(1).row - 1, _
            rngRange.SpecialCells(xlCellTypeVisible).Columns(1).column).Value = vbNullString), False) Then Exit For
        objStream.WriteText CsvFormatRow(rngRange.Rows(i), strSeparator, strRowEnd)
    End If
Next i

objStream.SaveToFile strFileName, 2
objStream.Close
End Sub
Function CsvFormatRow(rngRow As Variant, strSeparator As String, strRowEnd As String) As String

Dim arrCsvRow() As String

ReDim arrCsvRow(rngRow.SpecialCells(xlCellTypeVisible).Cells.Count - 1)
Dim rngCell As Range
Dim lngIndex As Long

lngIndex = 0

For Each rngCell In rngRow.SpecialCells(xlCellTypeVisible).Cells
    arrCsvRow(lngIndex) = CsvFormatString(rngCell.Value, strSeparator)
    lngIndex = lngIndex + 1
Next rngCell

CsvFormatRow = Join(arrCsvRow, strSeparator) & strRowEnd

End Function
Function CsvFormatString(strRaw, strSeparator As String) As String

Dim boolNeedsDelimiting As Boolean

Dim strDelimiter, strDelimiterEscaped As String

strDelimiter = """"
strDelimiterEscaped = strDelimiter & strDelimiter

boolNeedsDelimiting = InStr(1, strRaw, strDelimiter) > 0 _
    Or InStr(1, strRaw, chr(10)) > 0 _
    Or InStr(1, strRaw, strSeparator) > 0

CsvFormatString = strRaw

If boolNeedsDelimiting Then
    CsvFormatString = strDelimiter & _
        Replace(strRaw, strDelimiter, strDelimiterEscaped) & _
        strDelimiter
End If

End Function

(забытый источник)

Потому что я пришел к этому: я должен создать файл dbf из моего Excel Range вручную! После поиска найденных веб-источников.

Обновлено:

Как объявить кодировку DBF?

Что касается необходимой кодировки, то здесь довольно часто встречается кодировка Иранская система.

Как я могу хранить данные в подходящей кодировке как Иранская система в записях таблицы БД?


person mgae2m    schedule 31.08.2017    source источник
comment
Блокнот может сохранять файлы только как обычный текст. Почему вы хотите создать файл DBF с помощью Блокнота ?? И какое это имеет отношение к VBA?   -  person YowE3K    schedule 31.08.2017
comment
FWIW — помогает ли эта страница узнать, что такое формат файла?   -  person YowE3K    schedule 31.08.2017
comment
Вы изучили свой вопрос в Интернете? вы не .... я сделал поиск, и первое попадание - это описание формата.   -  person jsotola    schedule 31.08.2017
comment
Я создаю с помощью Блокнота, потому что: я экспортировал свой Excel Range в DBF этап, и меня обескуражило получение кода для создания этого макроса экспортера. Итак, я пытаюсь найти структуру и алгоритм внутри DBF для создания этого файла из моего excel Range вручную с помощью макроса VBA.   -  person mgae2m    schedule 31.08.2017
comment
вы не можете использовать блокнот ... формат двоичный .... выполните поиск в Интернете   -  person jsotola    schedule 31.08.2017
comment
Блокнот не является частью пакета Office — в нем нет VBA.   -  person YowE3K    schedule 31.08.2017
comment
Исправление вопроса: это означает, что из-за приведенного выше кода, который может создать CSV с помощью настраиваемых Delimiter и Row end и Charset, мне нужно создать файл DBF с контролируемым вводом данных в приведенном выше примере макроса. Фактически, обращение к слову «Блокнот» было примером или сравнением для моей цели.   -  person mgae2m    schedule 31.08.2017
comment
Зачем вам нужно создавать файл DBF? Почему бы просто не создать текстовый файл (или другой формат, который принимает dBASE), а затем загрузить данные в dBASE? (А затем пусть dBASE сама создаст файл DBF, если он у вас должен быть.)   -  person YowE3K    schedule 31.08.2017
comment
Я должен создать отчет в DBF и загрузить за каждый месяц. Этот отчет создается из файла Excel Range.   -  person mgae2m    schedule 31.08.2017
comment
Файл DBF находится в двоичном формате (как вы можете видеть, если вы перейдете по ссылке, которую я предоставил ранее, или если вы сами погуглили). Это не текстовый файл в формате значений, разделенных запятыми, или в формате с разделителями табуляции, или в любом другом текстовом формате.   -  person YowE3K    schedule 31.08.2017
comment
Но почему вы хотите создать отчет в виде файла базы данных? Куда вы загружаете отчет?   -  person YowE3K    schedule 31.08.2017
comment
Таким образом, я не могу создать этот файл с помощью обычного алгоритма и вставить Chars в вышеуказанный метод, алгоритмический?   -  person mgae2m    schedule 31.08.2017
comment
зависит от того, что вы подразумеваете под обычным алгоритмом .... при этом вы можете сделать это с помощью VBA, но, судя по вашему вопросу, это выходит за рамки вашего опыта. .... кроме того, я сомневаюсь, что кто-либо здесь готов потратить время, необходимое для разработки чего-то подобного.   -  person jsotola    schedule 31.08.2017
comment
Да, вы можете использовать функцию VBA Chr для записи файла, содержащего соответствующие коды, и, таким образом, создать свою собственную функцию экспорта DBF. Это, безусловно, выполнимо, и я желаю вам удачи, если вы решите попробовать.   -  person YowE3K    schedule 31.08.2017
comment
Я загружаю этот отчет для государственного учреждения, и это обязанность моей компании. Мы создавали этот отчет с их приложением. Но из-за того, что нам нужно подготовить несколько отчетов, я собираюсь создать этот отчет из нашей электронной таблицы Excel. Этот институт получает наш страховой отчет в формате DBF.   -  person mgae2m    schedule 31.08.2017
comment
Почему бы вам не загрузить данные в Access (вы можете сделать это из Excel), а затем получить доступ для экспорта в виде файла DBF (опять же, этим можно управлять из Excel). Это будет намного, намного, намного, намного проще, чем пытаться написать свой собственный генератор файлов DBF.   -  person YowE3K    schedule 01.09.2017
comment
Или вы проверили, имеет ли приложение, которое правительство предоставило вам для использования, функцию импорта. (В моей стране я должен отправлять формы в APRA, но вместо того, чтобы использовать их приложение для ввода чисел, я использую функцию импорта приложения для чтения данных, а затем мне просто нужно нажать кнопку отправки.)   -  person YowE3K    schedule 01.09.2017
comment
@YowE3k@: я пробовал в Этот вопрос, но не удалось. Таким образом, я изменил свой подход.   -  person mgae2m    schedule 01.09.2017
comment
Да, я видел этот ответ, и я думаю, что он сделает то, что вы хотите.   -  person YowE3K    schedule 01.09.2017
comment
@YowE3k@: Пожалуйста, напишите код, чтобы тихо и тихо (не сохранять файл на диске) создать объект доступа, который включает мой диапазон в таблице, а затем создать пункт назначения DBF. Я не могу найти этот путь после попытки поиска в течение дня. Поэтому я думаю о разработке создателя DBF с помощью VBA.   -  person mgae2m    schedule 01.09.2017
comment
@YowE3K@: Наше правительственное приложение основано на DBF4 (dBase IV)(*.dbf) и имеет внутреннюю базу данных. Я не могу импортировать свой диапазон Excel в эту базу данных, поэтому, возможно, у них не было функции import. Я должен создать макрос в Excel VBA, чтобы экспортировать мой отчетный диапазон в DBF.   -  person mgae2m    schedule 01.09.2017
comment
@jsotola@: Подтверждая ваше письмо, я сосредоточился на ключевых словах VBA+Excel+Range+DBF, а не на исследованиях по этому вопросу. Потому что я заглянул внутрь DBF, и все заголовки и значения полей можно было прочитать как текстовый файл. Так что я, хотя формат DBF представляет собой простой текстовый файл в виде текстового файла с разделителями табуляции или запятыми (тот же CSV). ;-(   -  person mgae2m    schedule 01.09.2017
comment
Если вы хотите создать свой собственный макрос для создания файла DBF, я не могу вас остановить. Все, что я могу сделать, это пожелать вам удачи. (Если бы у меня был свободный день или два, я мог бы бросить себе вызов, чтобы попробовать это тоже — это сложнее, чем обычные вещи, которые я делаю, поэтому это может быть интересно и может потребовать много исследований. Но у меня нет свободного дня. или два, так что я не собираюсь пробовать.)   -  person YowE3K    schedule 01.09.2017
comment
если вы используете Notepad++, вы можете переключиться на отображение HEX. это покажет вам истинную структуру файла. .... или загрузите его и используйте для просмотра содержимого файла sourceforge.net/projects/hexeditorvb   -  person jsotola    schedule 01.09.2017
comment
Поскольку то, что я видел внутри файла DBF, я подумал, что это текстовый файл ANSI. Все заголовки столбцов и значения данных безусловно читабельны. Почему этот файл двоичный, но внутренние значения читаются так же, как текстовый файл кодовой страницы Unicode 1256 или ANSI?   -  person mgae2m    schedule 01.09.2017
comment
Если вы посмотрите на спецификацию формата файла, вы увидите, что определенные типы данных хранятся в виде строк. (Они будут доступны для чтения в текстовом редакторе.) Но другие типы данных (например, Double) не хранятся в виде строк, поэтому они и вся управляющая информация являются двоичными значениями. Ваш макрос должен правильно генерировать всю эту управляющую информацию. (Одна небольшая ошибка, и весь файл будет поврежден.) Я делал подобные вещи раньше, и, по моим оценкам, это займет у меня пару дней. Прежде чем приступить к работе, оцените, сколько времени вам потребуется, чтобы закончить.   -  person YowE3K    schedule 01.09.2017
comment
Комментарии, которые вы делаете в этом вопросе (например, непонимание того, что файлы могут содержать читаемые значения, а также другие нечитаемые символы), заставляют меня предположить, что ваша оценка времени для завершения макроса должна быть порядка нескольких месяцев. . Это задача не для новичка.   -  person YowE3K    schedule 01.09.2017
comment
Я понял проблему и обнаружил, что DBF не является текстовым файлом. Надеюсь найти ответ на правильный подход к этому вопросу.   -  person mgae2m    schedule 01.09.2017
comment
есть это... dbf2002.com/csv-converter/ convert-csv-to-dbf.html   -  person jsotola    schedule 01.09.2017
comment
@jsotola Ааа, но ОП не хочет создавать какие-либо временные файлы в процессе, иначе ответ на их предыдущий вопрос решил бы проблему. (Я не уверен, почему это требование - операционная система и даже Excel постоянно создают временные файлы. И операционная система часто даже не удаляет их, когда заканчивает работу с ними. !)   -  person YowE3K    schedule 01.09.2017
comment
я сделал больше проверки.... это выглядит многообещающе..... stackoverflow.com/questions/322792/   -  person jsotola    schedule 01.09.2017
comment
@YowE3K, к вашему сведению. добавлен код, создающий файл dbf.   -  person jsotola    schedule 01.09.2017
comment
@YowE3k@: Меня беспокоит акцент на макрос, выполняемый в памяти, потому что процесс был тихим. Почему Access объект (Set App = CreateObject("Access.Application")) не может задействовать БД и Таблицы в памяти? Итак, если бы этот подход был тихим, у меня не было проблем с временными файлами. Наконец, метод @jsotola@ точен и краток.   -  person mgae2m    schedule 01.09.2017


Ответы (2)


у нас радость .... лол

этот тестовый код создает файл dbf из данных на листе Excel

создает таблицу и вставляет одну запись

Sub dbfTest()

' NOTE:  put this test data at top of worksheet (A1:F2)

' Name    Date        Code    Date2       Description    Amount
' frank  11/12/2017  234.00  11/20/2018   paint          $1.34



'   ref: microsoft activex data objects

    Dim path As String
    Dim fileName As String

    filePath = "C:\database\"
    fileName = "test"


    Dim dc As Range
    Dim typ As String
    Dim fieldName As String
    Dim createSql As String

    createSql = "create table " + fileName + " ("          ' the create table query produces the file in directory

    Dim a As Variant

    For Each dc In Range("a1:e1")

        fieldName = dc.Value
        a = dc.offset(1).Value

        Select Case VarType(a)
            Case vbString:   typ = "varchar(100)"
            Case vbBoolean:  typ = "varchar(10)"
            Case vbInteger:  typ = "int"
            Case vbLong:     typ = "Double"
            Case vbDate:     typ = "TimeStamp"
            Case Else:       typ = "varchar(5)"            ' default for undefined types
        End Select

        createSql = createSql + " [" + fieldName + "]" + " " + typ + ","

    Next dc

    createSql = Left(createSql, Len(createSql) - 1) + ")"

    Debug.Print createSql

    Dim conn As ADODB.connection
    Set conn = CreateObject("ADODB.Connection")

    conn.Open "DRIVER={Microsoft dBase Driver (*.dbf)};" & "DBQ=" & filePath                                    ' both work
'   conn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & filePath & ";Extended Properties=dBASE IV"

    Dim cmd As ADODB.Command
    Set cmd = CreateObject("ADODB.Command")

    cmd.ActiveConnection = conn

    cmd.CommandText = createSql
    cmd.Execute

    Dim insertSql As String
    insertSql = "insert into " + fileName + " values("

    For Each dc In Range("a2:e2")
        insertSql = insertSql + "'" + CStr(dc.Value) + "',"
    Next dc

    insertSql = Left(insertSql, Len(insertSql) - 1) + ")"

    Debug.Print insertSql

    cmd.CommandText = insertSql

    cmd.Execute

    conn.Close
    Set conn = Nothing

End Sub
person jsotola    schedule 01.09.2017
comment
Ваш ответ краток, хорош, ясен и полезен; и точно этот вопрос нужен. @jsotola@: Я разрабатываю ваш код, чтобы он был готов к публикации, и покажу вам его загруженный путь здесь. Пожалуйста, оставьте его в Этот вопрос как ответ. - person mgae2m; 01.09.2017
comment
@jsotola@: Как в приведенном выше коде определить Code-Page или Encoding как Unicode? - person mgae2m; 01.09.2017
comment
проверка в нем - person jsotola; 01.09.2017
comment
@jsotola@: Мне нужны значения записи (CStr(dc.Value)) в кодировке Unicode. Какой тип данных может определить Unicode для полей для этого? Например, я пробовал typ = "nvarchar(100)", но nvarchar не одобрен и возвращает ошибку. - person mgae2m; 02.09.2017
comment
@jsotola@: С помощью приведенной выше процедуры я могу экспортировать Excel в DBF. Но это не полное. Мне нужно определить кодировку в DBF назначения. Я достиг таблицы кодирования для подходящей кодировки, но как определить кодировку DBF? - person mgae2m; 03.09.2017
comment
вы упомянули в другом посте, что вам нужна системная кодировка Ирана. Я посмотрел на него, и оказалось, что это не юникод. это способ кодирования символов Юникода в ascii. .... у вас есть пример файла dbf, который считается хорошим? может быть, только с одним текстовым полем и только с одной записью. - person jsotola; 03.09.2017
comment
кстати, есть проблема с сохранением фактического текста юникода в dbf при использовании ADODB. нет способа сохранить символ пробела как текст Unicode в поле. .... проблема возникает в том, что символы юникода состоят из двух байтов. .... в символе пробела один из байтов равен нулю (0x00), что является недопустимым символом в строке VBA. - person jsotola; 03.09.2017
comment
Конечно, завтра (примерно через 8 часов) я поделюсь примером файла dbf с системной кодировкой Ирана, который был сгенерирован правительственным приложением. Пожалуйста, взгляните на эти вопросы: 1 и 2< /а>. Я представил некоторые идеи. - person mgae2m; 03.09.2017
comment
В моем регионе весь опыт, который я нашел в этом вопросе, был сосредоточен на кодировании системы Ирана и в классе CS -A, который включает Dictionary общий список для сопоставления символов-. (Как представлено в этом вопросе ). К сожалению, не нашел никакого опыта в кодировке Unicode или языке VBA, и кажется, что это может быть уникальный подход, который я пытаюсь программировать в VBA и Excel. - person mgae2m; 03.09.2017
comment
Строки @jsotola VBA не заканчиваются нулем, поэтому они могут включать символ 0x00. (Другой вопрос, может ли файл DBF справиться с этим.) - person YowE3K; 04.09.2017
comment
@ YowE3K YowE3K похоже, что ADODB не нравится оператор SQL insert into ..., который включает нуль в строку данных. - person jsotola; 04.09.2017
comment
@jsotola Это, безусловно, звучит правдоподобно. Хотя VBA использует строковый тип, который явно отслеживает длину строки и, следовательно, может иметь нулевые значения внутри строки, большинству вещей не нравятся нулевые значения, поскольку они были построены с использованием строковых типов с завершающим нулем. - person YowE3K; 04.09.2017
comment
@jsotola здесь я загрузил example.zip, который содержит 2 файла: 1- DSKWOR00.dbf создается с помощью государственной программы и 2- example.xlsx, который я создал с использованием 4 элементов, был сравнен с кодировкой windows по умолчанию и кодировкой системы Ирана, которую я даю из DSKWOR00.dbfи моей базы данных в example.xlsx, поэтому все соответствующие значения (в строке) эквивалент, для их оценки. - person mgae2m; 04.09.2017
comment
проверка... это формат версии 5.... исх. oocities.org/geoff_wass/dBASE/GaryWhite/dBASE/FAQ/ qformt.htm .... предыдущая ссылка, которую я разместил, относится к версии 7, поэтому игнорируйте ее - person jsotola; 04.09.2017
comment
вы можете открыть файл с помощью notepad++ ..... notepad-plus-plus.org .. .. у него есть шестнадцатеричный просмотрщик ..... я не знаю, сможете ли вы его скачать - person jsotola; 04.09.2017
comment
Я установил Notepad++ без дополнительных плагинов (как Hex-Editor) и открыл DSKWOR00.dbf (Print Screen) Предполагая, что с createSql и insertSql все в порядке из-за этот вопрос и dBASE Документ формата файла DBF III,IV,5, как я могу установить кодировку символов DBF (как Иранская система или Unicode, учитывая описанный выше подход к созданию DBF.( cmd.Execute - ADO) - person mgae2m; 04.09.2017
comment
@jsotola Как я могу установить кодировку DBF как iran System или Unicode при использовании этого полезного ответа? - person mgae2m; 04.09.2017

мое исследование завершено. Кодировка системы Ирана на самом деле ascii, а не unicode. он использует значения ascii для представления части персидского алфавита.

проблема с преобразованием из юникода в кодировку иранской системы заключается в том, что любая буква пишется совершенно по-разному в зависимости от того, где в слове она расположена. у вас есть «изолированные», «начальные», «средние» и «конечные» формы большинства букв.

это как верхний и нижний регистр на стероидах... лол

ссылка: https://www.math.nmsu.edu/~mleisher/Software/csets/IRANSYSTEM.TXT

поэтому потребуется дополнительный процесс для преобразования текста Unicode в Excel в эквивалентную строку кодировки системы Ирана перед сохранением в базе данных.

код создает таблицу с одним текстовым полем и хранит 3 записи

Sub dbfTestWork()

'   ref: microsoft activex data objects

    Dim filePath As String
    Dim fileName As String

    filePath = "C:\database\"
    fileName = "test"

    Dim conn As ADODB.Connection
    Set conn = CreateObject("ADODB.Connection")

    conn.Open "Driver={Microsoft dBase Driver (*.dbf)};Dbq=" + filePath + ";"

    'conn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & filePath & ";Extended Properties=dBASE IV;"

    Dim fil As String
    fil = filePath & fileName & ".dbf"
    If Not Dir(fil, vbDirectory) = vbNullString Then Kill fil  ' delete file if it exists

    Dim cmd As ADODB.Command
    Set cmd = CreateObject("ADODB.Command")

    cmd.ActiveConnection = conn

    cmd.CommandText = "create table test ([testTextData] char(20))"
    cmd.Execute

    Dim nFileNum As Integer
    nFileNum = FreeFile                                                           ' Get an available file number from the system
    Open filePath & fileName & ".dbf" For Binary Lock Read Write As #nFileNum     ' Open the file in binary mode.  Locks are optional
    Put #nFileNum, 30, CByte(1)                                                   ' set language driver id (LDID)   0x01 = ascii encoding
    Close #nFileNum

'   Debug.Print Range("e2").Value

    Dim aaa As String
    aaa = StrConv(Range("e2").Value, vbUnicode)
'   Debug.Print aaa

    Dim cmdStr As String
    cmdStr = "insert into test values ('"

    Dim ccc As Variant
    For Each ccc In Array("ac", "92", "9e", "20", "93", "a1", "fe", "a4")   ' one of these two should store
        cmdStr = cmdStr & Chr(CDec("&h" & ccc))                             ' "good morning" in persian
    Next ccc
    cmdStr = cmdStr & "');"
    cmd.CommandText = cmdStr
    cmd.Execute

    cmdStr = "insert into test values ('"
    For Each ccc In Array("a4", "fe", "a1", "93", "20", "9e", "92", "ac")
        cmdStr = cmdStr & Chr(CDec("&h" & ccc))
    Next ccc
    cmdStr = cmdStr & "');"
    cmd.CommandText = cmdStr
    cmd.Execute

    cmd.CommandText = "insert into test values ('abc123');"
    cmd.Execute

    conn.Close
    Set conn = Nothing

End Sub
'
person jsotola    schedule 04.09.2017
comment
Что использует aaa = StrConv(Range("e2").Value, vbUnicode)? - person mgae2m; 05.09.2017
comment
В приведенном выше полезном ответе, используя эту ссылку с использованием CDec(), я собираюсь создать массив map для соответствующих эквивалентных кодов Unicode и Iran System ASCII, а затем преобразовать эти две текстовые строки с соответствующей функцией записи, используя приведенный выше сопоставленный словарь. и характер распознать. затем отправьте вам этот результат (когда мне это удастся). - person mgae2m; 05.09.2017
comment
С большой благодарностью, готовьтесь представить результаты вышеупомянутого обсуждения, и я посылаю вам готовые процедуры. НАСТОЯЩЕЕ Объясните, что в Иране существует ежемесячное периодическое правительственное задание для подстроителей по подготовке отчета о страховом списке. Я запрограммировал генератор списков для государственного страхового списка Ирана, с декодированием их указанных кодов символов, таким же, как кодирование системы Ирана, с некоторыми отличиями в коде символов ASCW. Я запрограммировал некоторые из моих последних связанных вопросов с вашим руководством для публикации в качестве ответа. с уважением и благодарностью. - person mgae2m; 21.09.2017
comment
@, Пожалуйста, я должен тебе. - person mgae2m; 22.09.2017