Экспорт таблиц MSAccess в формате Unicode с разделителем тильды - PullRequest
2 голосов
/ 02 октября 2008

Я хочу экспортировать содержимое нескольких таблиц из MSAccess2003. Таблицы содержат Unicode японские символы. Я хочу сохранить их как текстовые файлы с разделителями тильды.

Я могу сделать это вручную, используя Файл / Экспорт и в диалоговом окне «Дополнительно» выбрав тильду в качестве разделителя полей и Юникод в качестве кодовой страницы.

Я могу сохранить это как Спецификацию экспорта, но это, похоже, зависит от таблицы.

Я хочу экспортировать множество таблиц с использованием кода VBA.

Пока я пробовал:

Sub ExportTables ()

Dim lTbl As Long
Dim dBase As Database
Dim TableName As String

Set dBase = CurrentDb

For lTbl = 0 To dBase.TableDefs.Count
     'If the table name is a temporary or system table then ignore it
    If Left(dBase.TableDefs(lTbl).Name, 1) = "~" Or _
    Left(dBase.TableDefs(lTbl).Name, 4) = "MSYS" Then
         '~ indicates a temporary table
         'MSYS indicates a system level table
    Else
      TableName = dBase.TableDefs(lTbl).Name
      DoCmd.TransferText acExportDelim, "UnicodeTilde", TableName, "c:\" + TableName + ".txt", True
    End If
Next lTbl
Set dBase = Nothing

End Sub

Когда я запускаю это, я получаю исключение:

Ошибка времени выполнения «3011»: Механизму базы данных Microsoft Jet не удалось найти объект «Allowance1 # txt». Убедитесь, что объект существует и что вы правильно написали его имя и путь.

Если я отлаживаюсь на этом этапе, TableName будет «Allowance1», как и ожидалось.

Полагаю, моя спецификация экспорта в UnicodeTilde зависит от таблицы, поэтому я не могу использовать ее для нескольких таблиц.

Какое решение? Должен ли я использовать что-то еще, кроме TransferText, или, возможно, программно создать спецификацию экспорта?

Любая помощь приветствуется.

Ответы [ 4 ]

2 голосов
/ 06 октября 2008

Я в конце концов решил это. (Я сейчас использую Access 2007, но у меня были те же проблемы, что и с Access 2003).

Первое, что не сработало:

TransferText сделает разделитель заголовка только разделителем и тильдой, даже с правильно отформатированным schema.ini. (Нет, я не поместил все это в одну строку, это была проблема форматирования с html в stackoverflow.)

[MyTable.txt]
CharacterSet = Unicode
Format = Delimited(~)
ColNameHeader = True
NumberDigits = 10
Col1= "Col1" Char Width 10
Col2= "Col2" Integer
Col3= "Col3" Char Width 2

Просто используя оператор выбора:

SELECT * INTO [Text;DATABASE=c:\export\;FMT=Delimited(~)].[MyTable.txt] FROM [MyTable]

Полностью игнорируется FMT. Мне было очень трудно найти документацию по формату параметров. Что бы я ни набирал в параметре FMT, единственное, что я мог заставить работать, было исправлено. Все остальное рассматривалось как CSVDelimited. Я мог бы проверить это, так как оператор select создал файл schema.ini, например так:

[MyTable.txt]
ColNameHeader=True
CharacterSet=1252
Format=CSVDelimited
Col1=Col1 Char Width 10
Col2=Col2 Integer
Col3=Col3 Char Width 2

Мое возможное решение состояло в том, чтобы создать мой собственный schema.ini, а затем использовать оператор select. Код моего модуля выглядит примерно так:

Option Compare Database
Option Explicit

    Public Function CreateSchemaFile(bIncFldNames As Boolean, _
                                       sPath As String, _
                                       sSectionName As String, _
                                       sTblQryName As String) As Boolean


         Dim Msg As String
         On Local Error GoTo CreateSchemaFile_Err
         Dim ws As Workspace, db As Database
         Dim tblDef As TableDef, fldDef As Field
         Dim i As Integer, Handle As Integer
         Dim fldName As String, fldDataInfo As String
         ' -----------------------------------------------
         ' Set DAO objects.
         ' -----------------------------------------------
         Set db = CurrentDb()
         ' -----------------------------------------------
         ' Open schema file for append.
         ' -----------------------------------------------
         Handle = FreeFile
         Open sPath & "schema.ini" For Output Access Write As #Handle
         ' -----------------------------------------------
         ' Write schema header.
         ' -----------------------------------------------
         Print #Handle, "[" & sSectionName & "]"
         Print #Handle, "CharacterSet = Unicode"
         Print #Handle, "Format = Delimited(~)"
         Print #Handle, "ColNameHeader = " & _
                         IIf(bIncFldNames, "True", "False")
         Print #Handle, "NumberDigits = 10"
         ' -----------------------------------------------
         ' Get data concerning schema file.
         ' -----------------------------------------------
         Set tblDef = db.TableDefs(sTblQryName)
         With tblDef
            For i = 0 To .Fields.Count - 1
               Set fldDef = .Fields(i)
               With fldDef
                  fldName = .Name
                  Select Case .Type
                     Case dbBoolean
                        fldDataInfo = "Bit"
                     Case dbByte
                        fldDataInfo = "Byte"
                     Case dbInteger
                        fldDataInfo = "Short"
                     Case dbLong
                        fldDataInfo = "Integer"
                     Case dbCurrency
                        fldDataInfo = "Currency"
                     Case dbSingle
                        fldDataInfo = "Single"
                     Case dbDouble
                        fldDataInfo = "Double"
                     Case dbDate
                        fldDataInfo = "Date"
                     Case dbText
                        fldDataInfo = "Char Width " & Format$(.Size)
                     Case dbLongBinary
                        fldDataInfo = "OLE"
                     Case dbMemo
                        fldDataInfo = "LongChar"
                     Case dbGUID
                        fldDataInfo = "Char Width 16"
                  End Select
                  Print #Handle, "Col" & Format$(i + 1) _
                                  & "= """ & fldName & """" & Space$(1); "" _
                                  & fldDataInfo
               End With
            Next i
         End With
         CreateSchemaFile = True
CreateSchemaFile_End:
         Close Handle
         Exit Function
CreateSchemaFile_Err:
         Msg = "Error #: " & Format$(Err.Number) & vbCrLf
         Msg = Msg & Err.Description
         MsgBox Msg
         Resume CreateSchemaFile_End
      End Function

Public Function ExportATable(TableName As String)
Dim ThePath As String
Dim FileName As String
Dim TheQuery As String
Dim Exporter As QueryDef
ThePath = "c:\export\"
FileName = TableName + ".txt"
CreateSchemaFile True, ThePath, FileName, TableName
On Error GoTo IgnoreDeleteFileErrors
FileSystem.Kill ThePath + FileName
IgnoreDeleteFileErrors:
TheQuery = "SELECT * INTO [Text;DATABASE=" + ThePath + "].[" + FileName + "] FROM [" + TableName + "]"
Set Exporter = CurrentDb.CreateQueryDef("", TheQuery)
Exporter.Execute
End Function


Sub ExportTables()

    Dim lTbl As Long
    Dim dBase As Database
    Dim TableName As String

    Set dBase = CurrentDb

    For lTbl = 0 To dBase.TableDefs.Count - 1
         'If the table name is a temporary or system table then ignore it
        If Left(dBase.TableDefs(lTbl).Name, 1) = "~" Or _
        Left(dBase.TableDefs(lTbl).Name, 4) = "MSYS" Then
             '~ indicates a temporary table
             'MSYS indicates a system level table
        Else
          TableName = dBase.TableDefs(lTbl).Name
          ExportATable (TableName)
        End If
    Next lTbl
    Set dBase = Nothing
End Sub

Я не утверждаю, что это элегантно, но работает. Также обратите внимание, что средство форматирования кода stackoverflow не любит мой \ ", поэтому он не очень красиво печатает мой код.

1 голос
/ 24 мая 2011

В отношении этого потока я наткнулся на невероятно простое решение, позволяющее использовать одну спецификацию для всех экспортов таблиц, тогда как обычно вам придется создавать отдельную для каждой; или используйте подпрограмму, предоставленную Ричардом А.

Процесс выглядит следующим образом:

Создайте спецификацию, например, Pipe |, разделенную любой таблицей, затем откройте запрос dynaset в доступе, используя SQL SELECT * FROM MSysIMEXColumns, а затем просто удалите все результирующие строки. Теперь эта спецификация не выдаст ошибку 3011 при попытке использовать таблицу, отличную от той, которую вы использовали для создания исходной спецификации, и, по сути, является универсальной спецификацией экспорта в Pipe для любой таблицы / запроса, которую вы хотите.

Это было обнаружено / протестировано в Access 2003, поэтому я предполагаю, что оно будет работать и для более поздних версий.

С уважением,

Мэтт Доннан

0 голосов
/ 04 октября 2008

У меня есть два предложения для вас:

  1. Убедитесь, что вы помещаете каждый параметр в свой файл [schema.ini] в новую строку. (Вы перечислили все это в одной строке, поэтому я подумал, что обязательно.)

  2. Не забудьте указать аргумент CodePage (последний) при вызове вашего TransferText. Вот список поддерживаемых значений, если вам это нужно:

http://msdn.microsoft.com/en-us/library/aa288104.aspx

Кроме этого, похоже, ваш подход должен работать.

0 голосов
/ 02 октября 2008

У меня есть часть ответа:

Я пишу файл schema.ini с помощью VBA, а затем выполняю свой TransferText. Это создает формат экспорта на лету. Единственная проблема, хотя мой schema.ini содержит:

ColNameHeader = True
CharacterSet = Unicode
Format = Delimited(~)

Только строка заголовка выходит в юникоде с разделителями тильды. Остальные строки - ANSI с запятыми.

...