Exportación de tablas de MSAccess como Unicode con delimitador de tilde
Pregunta
Quiero exportar el contenido de varias tablas desde MSAccess2003. Las tablas contienen caracteres japoneses unicode. Quiero almacenarlos como archivos de texto delimitados por tilde.
Puedo hacer esto manualmente usando Archivo / Exportar y, en el cuadro de diálogo 'Avanzado', seleccionando tilde como Delimitador de campo y Unicode como Página de códigos.
Puedo almacenar esto como una especificación de exportación, pero parece ser una tabla específica.
Quiero exportar muchas tablas usando el código VBA.
Hasta ahora he intentado:
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
Fin Sub
Cuando ejecuto esto obtengo una excepción:
Error en tiempo de ejecución '3011': El motor de base de datos Microsoft Jet no pudo encontrar el objeto " Allowance1 # txt '. Asegúrese de que el objeto existe y de que deletrea su nombre y el nombre de la ruta correctamente.
Si depuro en este punto, TableName es 'Allowance1', como se esperaba.
Supongo que mi especificación de exportación de UnicodeTilde es específica de la tabla, por lo que no puedo usarla para varias tablas.
¿Cuál es la solución? ¿Debo usar otra cosa que no sea TransferText, o tal vez crear la especificación de exportación programáticamente?
Cualquier ayuda apreciada.
Solución
Eventualmente he resuelto esto. (Ahora estoy usando Access 2007 pero tuve los mismos problemas que con Access 2003.)
Primero, lo que no funcionó:
TransferText solo haría que la fila de encabezado esté unicode y delimitada por tilde, incluso con un schema.ini correctamente formateado. (No, no lo puse todo en una línea, eso fue solo un problema de formato con el html en stackoverflow).
[MyTable.txt]
CharacterSet = Unicode
Format = Delimited(~)
ColNameHeader = True
NumberDigits = 10
Col1= "Col1" Char Width 10
Col2= "Col2" Integer
Col3= "Col3" Char Width 2
Solo usando una declaración de selección:
SELECT * INTO [Text;DATABASE=c:\export\;FMT=Delimited(~)].[MyTable.txt] FROM [MyTable]
Totalmente ignorado el FMT. Me resultó muy difícil encontrar documentación sobre el formato de los parámetros. Lo que sea que haya escrito en el parámetro FMT, lo único que pude hacer para trabajar fue el de Arreglo. Todo lo demás fue tratado como CSVDelimited. Podría chech esto como la declaración de selección creó un archivo schema.ini como este:
[MyTable.txt]
ColNameHeader=True
CharacterSet=1252
Format=CSVDelimited
Col1=Col1 Char Width 10
Col2=Col2 Integer
Col3=Col3 Char Width 2
Mi solución final fue crear mi propio schema.ini y luego usar la declaración de selección. El código de mi módulo se parece a esto:
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
No pretendo que sea elegante, pero funciona. También tenga en cuenta que al formateador de código de stackoverflow no le gusta mi \ " ;, por lo que no imprime mi código muy bien.
Otros consejos
En relación con este hilo, he encontrado una solución increíblemente simple para poder usar una especificación en todas las exportaciones de tablas, mientras que normalmente tendrías que crear una separada para cada una; o use la sub rutina proporcionada por Richard A.
El proceso es el siguiente:
Cree una especificación, por ejemplo, Pipe |
delimitada con cualquier tabla, luego abra una consulta de dynaset en el acceso usando SQL SELECT * FROM MSysIMEXColumns
y luego simplemente elimine todas las filas resultantes. Ahora, esta especificación no generará el error 3011 cuando intente utilizar una tabla diferente a la que utilizó para crear la especificación original y es esencialmente una especificación de exportación de canalización universal para cualquier tabla / consulta que desee.
Esto se ha descubierto / probado en Access 2003, así que supongo que también funcionará para versiones posteriores.
Saludos cordiales,
Matt Donnan
Tengo dos sugerencias para ti:
-
Asegúrese de colocar cada configuración en su archivo [schema.ini] en una nueva línea. (Lo has incluido aquí en una sola línea, así que pensé que me aseguraría).
-
No olvide proporcionar el argumento CodePage (el último) cuando llame a su TransferText. Aquí hay una lista de valores admitidos si lo necesita:
http://msdn.microsoft.com/en-us/library /aa288104.aspx
Aparte de eso, parece que su enfoque debería funcionar.
Tengo parte de la respuesta:
Estoy escribiendo un archivo schema.ini con VBA, luego hago mi TransferText. Esto está creando un formato de exportación sobre la marcha. El único problema es que, aunque mi schema.ini contiene:
ColNameHeader = True
CharacterSet = Unicode
Format = Delimited(~)
Solo la fila del encabezado sale en unicode con delimitadores de tilde. El resto de las filas son ANSI con comas.