【问题标题】:Sort and ignore leading quotation marks排序并忽略前导引号
【发布时间】:2021-11-27 21:35:24
【问题描述】:

此 VBA 代码通过双击列标题按任意列对我的黑胶唱片收藏目录进行排序。

在我的古典黑胶唱片中,将近一半的歌曲标题都用引号引起来,因此当对该列进行排序时,它会按字母顺序对标题进行排序, 先是引号,然后是标题没有 em> 引号。

有没有办法添加一行代码,以便在排序时忽略前导引号,使"ac" 出现在ab 之后等等?

我现在的解决方法是使用隐藏的帮助列来去除引号,但我希望有一个更简洁的解决方案。

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
    Dim KeyRange    As Range
    Dim ColumnCount As Integer
    
    'Clear previous sorts
    ActiveSheet.Sort.SortFields.Clear
    
    'Clear contents of hidden helper column
    Columns("K").ClearContents
    
    'Copy and Paste songname column to helper column
    Range("F:F").Copy Range("K:K")
    
    'Strip quotes from helper column
    Application.ScreenUpdating = FALSE
    ActiveSheet.Columns("K").Replace What:="""", Replacement:="", LookAt:=xlPart, MatchCase:=False
    Application.ScreenUpdating = TRUE
    
    'Set range of header columns that will sort on double-click
    ColumnCount = Range("A1:J1").Columns.Count
    Cancel = FALSE
    If Target.Row = 1 And Target.Column <= ColumnCount Then
        Cancel = TRUE
        
        'Get cell address of double-clicked header cell
        Set SortColumn = Range(Target.Address)
        
        'Set fill color of currently sorted column header
        Rows(1).Interior.Color = xlNone
        SortColumn.Interior.ColorIndex = 15
        
        With ActiveSheet
            'Sort by hidden column if songname column is double-clicked
            If SortColumn = Range("F1") Then
                Range("K1").Select
            Else
                SortColumn.Select
            End If
            'Sort by selected column followed by album, disc, then track
            .Sort.SortFields.Add Key:=Selection, _
            SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
            .Sort.SortFields.Add Key:=Range("E1"), _
                                 SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
            .Sort.SortFields.Add Key:=Range("B1"), _
                                 SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
            .Sort.SortFields.Add Key:=Range("C1"), _
                                 SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
        End With
        
        With ActiveSheet.Sort
            'Set flexible sort range to all data before reaching entirely empty row or column
            .SetRange Range("A1").CurrentRegion
            .Header = xlYes
            .MatchCase = FALSE
            .Orientation = xlTopToBottom
            .SortMethod = xlPinYin
            .Apply
        End With
        
    End If
End Sub

【问题讨论】:

  • 不幸的是,这不仅仅是一行代码。
  • 您能详细说明一下吗?为我指明正确的方向?
  • 为什么不删除所有的",一个简单的查找/替换就可以了?
  • 含义 - 排序按字母顺序进行,引号按字母顺序排在第一位。没有简单的单线来做你想做的事。一种解决方法可能是去掉引号的帮助列。
  • @ScottCraner 我不想删除引号,因为它们应该存在,因为这些歌曲名称通常是戏剧作品或歌剧的标题,应该用引号引起来。

标签: excel vba sorting special-characters


【解决方案1】:

Excel 在对数据进行排序时一直存在这个问题。这是因为它使用 ASCII 字符代码来确定排序顺序(更多详细信息:https://exceljet.net/excel-functions/excel-char-function)。特殊字符和标点符号的 ASCII 值低于字母,因此它们排在最前面。这是设计使然。

排序时没有真正的“忽略”引号的方法,但解决此问题的一种方法是从您尝试排序的单元格中删除所有引号。您可以尝试在 SET 语句之后立即添加此代码:

ActiveSheet.KeyRange.Cells.Replace _
    What:="""", _
    Replacement:="", _
    LookAt:=xlPart, _
    MatchCase:=False

警告!!!这实际上会修改您所有的歌曲标题(它将删除该列中的双引号),因此请在尝试之前备份您的文件。

【讨论】:

  • 谢谢 Andrea,但正如我在 cmets 中告诉 Scott Craner 的那样,我想要歌曲标题中的引号。他们属于那里。我希望我可以“告诉” excel 忽略一个字符,但我接受了 BigBen 的建议并使用辅助列进行排序。
【解决方案2】:

一种方法是用F数据添加一个虚拟列K,清除“,排序,擦除K列...

我相应地修复了代码

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
    Dim KeyRange As Range
    Dim ColumnCount As Integer
    Dim dstRng as Range               ' placeholder 2 add column "K"
    
    ActiveSheet.Sort.SortFields.Clear
    
    ColumnCount = Range("A1:J281").Columns.Count
    Cancel = False
    
    If Target.Row = 1 And Target.Column <= ColumnCount Then
        Cancel = True
    
        Set KeyRange = Range(Target.Address)
        Set dstRng = KeyRange.Resize(, 1).Offset(, KeyRange.Columns.Count - 1) 'Added column K
        KeyRange.Resize(,1).Offset(,5).copy    ' copy column F
        dstRng.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
    :=False, Transpose:=False
        dstRng.Replace What:="""", Replacement:="", LookAt:=xlPart, _
    SearchOrder:=xlByColumns, MatchCase:=False, SearchFormat:=False, _
    ReplaceFormat:=False

        With ActiveSheet  ' columns F,B,C >> K,B,C
            .Sort.SortFields.Add Key:=KeyRange, _
              SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
            .Sort.SortFields.Add Key:=Range("K1"), _
              SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
            .Sort.SortFields.Add Key:=Range("B1"), _
              SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
            .Sort.SortFields.Add Key:=Range("C1"), _
              SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
        End With
    
        With ActiveSheet.Sort
            .SetRange Range("A1:K281")
            .Header = xlYes
            .MatchCase = False
            .Orientation = xlTopToBottom
            .SortMethod = xlPinYin
            .Apply
        End With
        dstRng.ClearContents

    End If
End Sub

始终在副本上运行 1st,保护原始 Excel 文件。

注意:我使用 KeyRange 进行处理,但可能需要一些 set SrcRng = Range("A1:J281")

【讨论】:

  • 我猜你没有注意到问题中的 cmets 和 UPDATE ?不过谢谢。
  • 嗨,第一次我在 Google 表格中实现了它,由于滞后,我不得不花几个小时才能看到我的代码......然后意识到它是 Excel,所以我又做了一次。在这两者之间,我没有检查所有的编辑和 cmets。无论如何,你有一个可行的建议实施,这里没有伤害......
猜你喜欢
  • 2015-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-21
  • 2012-10-02
  • 1970-01-01
  • 1970-01-01
  • 2021-08-17
相关资源
最近更新 更多