Экспорт таблиц MSAccess в формате Unicode с разделителем тильды

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

Я могу сделать это вручную с помощью File / Export и в диалоговом окне «Advanced» выбрать тильду в качестве разделителя полей и 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

Конец подписки

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

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

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

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

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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
5 599
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

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

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

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

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

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

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

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

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

В остальном, похоже, ваш подход должен работать.

Ответ принят как подходящий

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

Во-первых, что не сработало:

TransferText сделает только строку заголовка разделенной в кодировке Unicode и тильдой, даже при правильно отформатированном файле 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 не нравится мой \ ", поэтому он не очень хорошо печатает мой код.

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

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

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

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

С уважением,

Мэтт Доннан

Спасибо, Мэтт. Прошло много времени с тех пор, как я этим занимался, но я попробую, когда у меня будет минутка.

Richard A 25.05.2011 02:41

Другие вопросы по теме