使用Tilde定界符将MSAccess表导出为Unicode
我想从MSAccess2003导出几个表的内容。
这些表包含unicode日语字符。
我想将它们存储为波浪号分隔的文本文件。
我可以使用"文件/导出"手动执行此操作,然后在"高级"对话框中选择"代字号"作为"字段分隔符",并选择" Unicode"作为"代码页"。
我可以将其存储为"导出规范",但这似乎是特定于表的。
我想使用VBA代码导出许多表。
到目前为止,我已经尝试过:
子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以外的其他方式,还是以编程方式创建导出规范?
任何帮助表示赞赏。
解决方案
我有部分答案:
我正在用VBA编写schema.ini文件,然后执行TransferText。这是在动态创建导出格式。唯一的问题是,尽管我的schema.ini包含:
ColNameHeader = True CharacterSet = Unicode Format = Delimited(~)
只有标头行以带波浪号分隔符的unicode出现。其余的行是带有逗号的ANSI。
我有两个建议给我们:
- 确保将每个设置都放在[schema.ini]文件中的新行中。 (我们已将其全部列在此处,所以我想确定。)
- 调用TransferText时,请不要忘记提供CodePage参数(最后一个)。如果需要,这是受支持的值的列表:
http://msdn.microsoft.com/en-us/library/aa288104.aspx
除此之外,看来方法应该可行。
我终于解决了这个问题。 (我现在正在使用Access 2007,但与Access 2003一样有同样的问题。)
首先,什么不起作用:
即使使用正确格式的schema.ini,TransferText也只会使Header Row Unicode和代字号分隔。 (不,我没有将所有内容放在一行上,那只是stackoverflow上的html的格式问题。)
[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代码格式化程序不喜欢我的",因此它不会很好地打印我的代码。