删除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 中删除表的所有行

如何计算 Access 2010 表中所有列中的所有 NULL 值?

单击按钮时从 Access 数据库中删除特定记录

怎么删除ACCESS中的重复记录 只保留一条

mysql怎样查询一个表中所有数据

sql 删除表中的字段的最后一个字符