【问题标题】:Removing Any Non-Specified Characters from an Excel Spreadsheet using a Macro使用宏从 Excel 电子表格中删除任何非指定字符
【发布时间】:2017-08-10 11:05:20
【问题描述】:

我正在尝试通过删除任何非标准字符来清理 Excel 中的 .CSV 文件。我关心的唯一字符是 A-Z、0-9 和一些标准的标点符号。任何其他字符,我想删除。

当我找到一个包含我未指定的任何字符的单元格时,我得到了以下宏来删除整行,但我不确定如何让它真正删除字符本身。

Sub Replace()
Dim sCharOK As String, s As String
Dim r As Range, rc As Range
Dim j As Long

sCharOK = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789, `~!@#$%^&*()_+-=[]\{}|;':"",./<>?™®"

Set r = Worksheets("features").UsedRange.SpecialCells(xlCellTypeConstants, xlTextValues)

' loop through all the cells with text constant values and deletes the rows with characters not in sCharOK
For Each rc In r
    s = rc.Value
    For j = 1 To Len(s)
        If InStr(sCharOK, Mid(s, j, 1)) = 0 Then
            rc.EntireRow.Delete
            Exit For
        End If
    Next j
Next rc

End Sub

我认为有一种相当简单的方法可以使这段代码适应那个函数,但我对 VBA 不够熟悉,无法真正知道如何去做。非常感谢任何见解!

【问题讨论】:

    标签: excel character vba


    【解决方案1】:

    另一种方式是Range.Replace,例如:

    Sub test()
      Dim sCharOK As String
      sCharOK = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789, `~!@#$%^&*()_+-=[]\{}|;':"",./<>?™®" & Chr(1)
      Dim i As Long
      For i = 0 To 255
        If InStr(sCharOK, Chr(i)) = 0 Then
          ActiveSheet.Cells.Replace What:=Chr(i), Replacement:="", LookAt:=xlPart, MatchCase:=True, SearchFormat:=False, ReplaceFormat:=False
        End If
      Next
    End Sub
    

    编辑

    如果只需要删除不可打印的字符,查看@ryguy72 的答案也提供了另一种方法(在问题中,µ²äöüßÉõ 之类的内容将被删除,但此代码不会)也假设没有公式

    Sub test()
      With ActiveSheet.UsedRange
        .Value = Evaluate("TRIM(CLEAN(" & .Address & "))")
      End With
    End Sub
    

    或者直接在即时窗口中运行这一行:

    ActiveSheet.UsedRange.Value = Evaluate("TRIM(CLEAN(" & ActiveSheet.UsedRange.Address & "))")
    

    【讨论】:

    • 光滑。更少的代码并利用应该更快的内置代码。
    • 码大于FF的Unicode字符怎么办?
    • @RonRosenfeld 他们不能在那里,因为“我正在尝试清理 .CSV 文件...”和“THIS
    • 我是您的答案的赞成票之一,因为它的简单性和速度。只指出一个可能的限制,甚至可能不适用于这种特殊情况。但是,csv 文件可以包含那些讨厌的字符,并且可以在适当的设置下将它们导入 Excel。
    • @RonRosenfeld 如果我的 cmets 听起来很粗鲁或类似的话,我很抱歉。我是一个很好的人,但英语口语(写作)不太好。我也赞成您的回答,因为它完全符合 OP 的要求。
    【解决方案2】:

    您还可以使用正则表达式,从而避免在循环中检查每个字符。 (尽管正则表达式引擎必须这样做)。

    下面解释的正则表达式模式包含您的字符列表,使用的字符类表示匹配未列出的所有内容。

    如果速度成为问题,您可以使用 vba 数组来加快速度。

    Option Explicit
    Sub ReplaceNonStdChars()
        Const sPat As String = "[^\x20-\x7E\x99\xAE]"
        Dim RE As Object
        Dim R As Range, C As Range
    
    Set R = Worksheets("features").UsedRange.SpecialCells(xlCellTypeConstants, xlTextValues)
    
    Set RE = CreateObject("vbscript.regexp")
    With RE
        .Global = True
        .Pattern = sPat
        For Each C In R
            C.Value = .Replace(C.Text, "")
        Next C
    End With
    End Sub
    

    正则表达式说明

    [^\x20-\x7E\x99\xAE]

    [^\x20-\x7E\x99\xAE]
    

    使用RegexBuddy创建

    【讨论】:

    • 但是为每个单元运行,最后可能会更慢。但是,这主要取决于细胞数。
    • @DirkReichel 绝对正确。如果有很多单元格,我会使用 VBA 数组。但是使用正则表达式模式也会删除所有未列出的字符,包括 Unicode 字符。
    • 意外删除了我的评论:如果 OP 真的想要它(或者只是很无聊),他可以使用 ChrW 从 -32768 到 65535 运行我的代码。:P
    • @DirkReichel 我们甚至不知道是否有必要。但我确实喜欢您发布的解决方案的简单性。
    【解决方案3】:

    如果是我,我会在每次找到无效字符时对原始字符串使用替换命令,将无效字符更改为 null。然后将原始单元格值替换为修改后的字符串。像这样的...

    一种可能的方法(已测试)

    Sub RemoveInvalidCharacters()
    Dim sCharOK As String, s As String
    Dim r As Range, rc As Range
    Dim j As Long
    Dim badchar As Boolean
    
    sCharOK = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789, `~!@#$%^&*()_+-=[]\{}|;':"",./<>?™®"
    
    Set r = Worksheets("features").UsedRange.SpecialCells(xlCellTypeConstants, xlTextValues)
    
    ' loop through all the cells with text constant values and
    ' deletes the invalid characters not in sCharOK from each Value property
    For Each rc In r
        badchar = False
        s = rc.Value
        For j = 1 To Len(s)
            If InStr(sCharOK, Mid(s, j, 1)) = 0 Then
                badchar = True
                s = Replace(s, Mid(s, j, 1), "")
            End If
        Next j
        If badchar Then
            rc.Value = s
        End If
    Next rc
    
    End Sub
    

    【讨论】:

    • sCharOK 都是可以的字符。 Mid(s, j, 1) 是要检查的字符串中的实际字符。 InStr(sCharOK, Mid(s, j, 1)) = 0 => 位置j 的字符无效。然后replace(s, j, "") 将替换字符串s 中的数值j...我确定你想运行s = replace(s, Mid(s, j, 1), "") ;)
    • 谢谢 Dirk,我对格式问题非常着迷,我的大脑在错误的道路上向左走。逻辑很好,缺少语法:)
    【解决方案4】:

    从字面上看,我今天必须这样做。下面的脚本非常适合我。

    Sub Clean_and_Trim_Cells()
        Application.ScreenUpdating = False
        Application.Calculation = xlCalculationManual
        Dim s As String
        For Each c In ActiveSheet.UsedRange
            s = c.Value
            If Trim(Application.Clean(s)) <> s Then
                s = Trim(Application.Clean(s))
                c.Value = s
            End If
        Next
        Application.ScreenUpdating = True
        Application.Calculation = xlCalculationAutomatic
    End Sub
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多