Экспорт таблиц MSAccess в формате Unicode с разделителем в виде тильды
Вопрос
Я хочу экспортировать содержимое нескольких таблиц из MSAccess2003.Таблицы содержат японские символы в формате Юникод.Я хочу сохранить их в виде текстовых файлов с разделителями в виде тильды.
Я могу сделать это вручную, используя File / Export и в диалоговом окне "Дополнительно" выбрав тильду в качестве разделителя полей и Юникод в качестве кодовой страницы.
Я могу сохранить это как спецификацию экспорта, но, похоже, это зависит от конкретной таблицы.
Я хочу экспортировать много таблиц, используя код VBA.
До сих пор я пытался:
Вложенные экспортируемые таблицы ()
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 database engine не удалось найти объект "Allowance1#txt".Убедитесь, что объект существует и что вы правильно написали его имя и путь к нему.
Если я выполняю отладку на этом этапе, TableName будет 'Allowance1', как и ожидалось.
Я предполагаю, что моя спецификация экспорта UnicodeTilde зависит от конкретной таблицы, поэтому я не могу использовать ее для нескольких таблиц.
Каково же решение?Должен ли я использовать что-то другое, отличное от TransferText, или, возможно, создать спецификацию экспорта программно?
Любая помощь приветствуется.
Решение
В конце концов я решил эту проблему.(Сейчас я использую 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:
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 не нравится мой \ ", поэтому он не очень хорошо печатает мой код.
Другие советы
В связи с этим потоком я наткнулся на невероятно простое решение, позволяющее использовать одну спецификацию для всего экспорта таблиц, тогда как обычно вам пришлось бы создавать отдельную спецификацию для каждой;или воспользуйтесь подпрограммой, предоставленной Ричардом А.
Этот процесс заключается в следующем:
Создайте спецификацию, например, трубы |
разделенный любой таблицей, затем откройте запрос dynaset в access с помощью SQL SELECT * FROM MSysIMEXColumns
а затем просто удалите все результирующие строки.Теперь эта спецификация не выдаст ошибку 3011 при попытке использовать таблицу, отличную от той, которую вы использовали для создания исходной спецификации, и, по сути, является универсальной спецификацией экспорта канала для любой таблицы / запроса, которые вы пожелаете.
Это было обнаружено / протестировано в access 2003, поэтому я предполагаю, что это будет работать и для более поздних версий.
С наилучшими пожеланиями,
Мэтт Доннан
У меня есть для вас два предложения:
Убедитесь, что вы помещаете каждый параметр в свой файл [schema.ini] с новой строки.(Вы перечислили все это здесь в одной строке, так что я подумал, что должен убедиться.)
Не забудьте указать аргумент CodePage (последний) при вызове вашего TransferText.Вот список поддерживаемых значений, если вам это нужно:
http://msdn.microsoft.com/en-us/library/aa288104.aspx
В остальном, похоже, что ваш подход должен сработать.
У меня есть часть ответа:
Я пишу файл schema.ini с помощью VBA, затем выполняю свой TransferText.Это создание формата экспорта "на лету".Единственная проблема заключается в том, что, хотя мой schema.ini содержит:
ColNameHeader = True
CharacterSet = Unicode
Format = Delimited(~)
Только строка заголовка выводится в юникоде с разделителями в виде тильды.Остальные строки - это ANSI с запятыми.