删除Access数据库中所有表中所有字符串字段中的所有控制字符
Posted
技术标签:
【中文标题】删除Access数据库中所有表中所有字符串字段中的所有控制字符【英文标题】:Remove All Control Characters In All String Fields In All Tables In Access Database 【发布时间】:2016-11-18 21:56:56 【问题描述】:我需要清理定期接收的 Access 数据库,以便可以将其所有表导出为“干净”的 CSV,然后由 Base SAS 通过 PROC IMPORT 导入。
我对 Access VBA 或一般编程没有经验,但我尝试使用 kitbash 脚本循环遍历每个表中的每个字段并替换某些字符。它似乎不起作用,并且在运行时出现几个“类型转换失败”错误。
Public Sub ReplaceCharAllTables()
Dim strSQL As String
Dim fld As DAO.Field
Dim db As DAO.Database
Set db = CurrentDb()
Dim obj As AccessObject, dbs As Object
Set dbs = Application.CurrentData
' Cycle through all tables in database
For Each obj In dbs.AllTables
' Cycle through all fields in the table
For Each fld In db.TableDefs("[" & obj.Name & "]").Fields
If fld.Type = dbText And Not IsNull(fld) Then
strSQL = "Update [" & obj.Name & "] Set [" & fld.Name & "]= Replace([" & fld.Name & "],Chr(10),'. ')"
DoCmd.RunSQL strSQL
strSQL = "Update [" & obj.Name & "] Set [" & fld.Name & "]= Replace([" & fld.Name & "],Chr(13),'. ')"
DoCmd.RunSQL strSQL
End If
Next
Next obj
End Sub
请注意,此特定代码当前仅尝试删除两个字符。这只是一个临时试验台。
编辑 2016.11.30:只是想说安德烈的解决方案是完美的。我最终需要做一些小的调整,特别是除了文本字段之外还要查看“备忘录”字段,并将有用的调试信息写入文本文件而不是大小受限的即时窗口。循环遍历一系列字符代码看似聪明。
Public Sub ReplaceCharAllTables()
Dim strSQL As String
Dim fld As DAO.Field
Dim db As DAO.Database
Dim td As DAO.TableDef
Dim strFld As String
Dim arCharCodes As Variant
Dim code As Variant
Dim strFolder As String
Dim n As Integer
Dim strUpdate As String
' Get stuff setup save debug.print log file
strFolder = Application.CurrentProject.Path & "\" & Application.CurrentProject.Name & "_RemoveCharLog.txt"
n = FreeFile()
Open strFolder For Output As #n
' all charcodes to replace
arCharCodes = Array(10, 13, 44)
Set db = CurrentDb()
' Cycle through all tables in database
For Each td In db.TableDefs
' Ignore system tables
If Not (td.Name Like "MSys*" Or td.Name Like "USys*") Then
' Cycle through all fields in the table
For Each fld In td.Fields
If fld.Type = dbText Or fld.Type = dbMemo Then ' Check if field is text or memo
' Cycle through all character codes to remove
For Each code In arCharCodes
strFld = "[" & fld.Name & "]"
strSQL = "UPDATE [" & td.Name & "] " & _
"SET " & strFld & " = Replace(" & strFld & ", Chr(" & code & "), '. ') " & _
"WHERE " & strFld & " LIKE '*" & Chr(code) & "*'"
db.Execute strSQL
strUpdate = "Updated " & db.RecordsAffected & " records."
'Start printing logs
Debug.Print strSQL
Debug.Print strUpdate
Print #n, strSQL
Print #n, strUpdate
Next code
End If
Next fld
End If
Next td
End Sub
【问题讨论】:
酷,感谢您的反馈! 【参考方案1】:据我所知,您的代码原则上没有问题。主要问题可能是它还尝试更新所有系统表 - 检查导航窗格的导航选项中的“系统对象”以查看它们。 它们以 MSys 或 USys 开头。
还有一些需要改进的地方:
无论如何您都需要 TableDef 对象,因此您可以直接循环它们而不是AllTables
表格字段不能为 Null,因此不需要此检查
为了提高效率,您只想更新列实际包含搜索字符的行,因此我添加了 WHERE 子句
为避免重复代码,请将要替换的所有字符代码放入一个数组中以进行额外循环。
使用db.Execute
而不是DoCmd.RunSQL
:这样可以避免使用DoCmd.SetWarnings False
,并为您提供受影响记录的数量。
我的建议:
Public Sub ReplaceCharAllTables()
Dim strSQL As String
Dim fld As DAO.Field
Dim db As DAO.Database
Dim td As DAO.TableDef
Dim strFld As String
Dim arCharCodes As Variant
Dim code As Variant
' all charcodes to replace
arCharCodes = Array(10, 13)
Set db = CurrentDb()
' Cycle through all tables in database
For Each td In db.TableDefs
' Ignore system tables
If Not (td.Name Like "MSys*" Or td.Name Like "USys*") Then
' Cycle through all fields in the table
For Each fld In td.Fields
If fld.Type = dbText Then
For Each code In arCharCodes
strFld = "[" & fld.Name & "]"
strSQL = "UPDATE [" & td.Name & "] " & _
"SET " & strFld & " = Replace(" & strFld & ", Chr(" & code & "), '. ') " & _
"WHERE " & strFld & " LIKE '*" & Chr(code) & "*'"
Debug.Print strSQL
db.Execute strSQL
Debug.Print "Updated " & db.RecordsAffected & " records."
Next code
End If
Next fld
End If
Next td
End Sub
如果这仍然给出错误,请检查特定的 SQL(Ctrl+g 显示 Debug.Print
的输出) - 它要更新什么列数据类型?
【讨论】:
是的,我猜是And Not IsNull(fld) Then
而不是不更新具有 Null 值的字段,导致了错误。以上是关于删除Access数据库中所有表中所有字符串字段中的所有控制字符的主要内容,如果未能解决你的问题,请参考以下文章
无法通过 C# 中的 OleDB 从 Microsoft Access 中删除表的所有行