前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >VBA: 单元格区域基于指定列重新排序(4)

VBA: 单元格区域基于指定列重新排序(4)

作者头像
Exploring
发布2024-04-22 11:01:17
2430
发布2024-04-22 11:01:17
举报
文章被收录于专栏:数据处理与编程实践

文章背景: 在数据处理时,有时需要根据指定列的内容进行重新排序。

针对品号这一列,希望借助字符串末尾的序号,

(1)先按字母的个数升序,一个字母的在前,两个字母的在后;

(2)当字母个数相同时,按字母升序;

(3)当字母相同时,按数字大小升序。

数据源如下:

解决思路:

借助正则表达式,分别提取字符串末尾的字母和数字,然后通过三个辅助列(字母,数字,字母个数)进行排序。排序结束后,删除这三个辅助列。

VBA代码如下:

代码语言:javascript
复制
Option Explicit

Sub SampleNo_Reordering()

    '基于单号,重新排序
    
    Dim row_final As Integer
    
    Dim tarSheet As Worksheet
    
    Set tarSheet = ThisWorkbook.Worksheets("test")

    tarSheet.Activate
    
    row_final = tarSheet.Range("A65535").End(xlUp).Row
    
    Application.Calculation = xlCalculationAutomatic   'Formula自动计算

    '添加三个辅助列
    Columns("B:D").Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
    
    Columns("B:D").NumberFormatLocal = "G/通用格式"
    
    '字母
    Range("B2").FormulaR1C1 = "=GetLetters(RC[-1])"
    
    Range("B2").AutoFill Destination:=Range("B2:B" & row_final)
    
    '数字
    Range("C2").FormulaR1C1 = "=GetNumbers(RC[-2])"

    Range("C2").AutoFill Destination:=Range("C2:C" & row_final)
    
    '字母个数
    Range("D2").FormulaR1C1 = "=LEN(RC[-2])"

    Range("D2").AutoFill Destination:=Range("D2:D" & row_final)
    
    '设定筛选条件
    With tarSheet.Sort.SortFields
        .Clear
        .Add2 Key:=Range("D2:D" & row_final) _
            , SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
        .Add2 Key:=Range("B2:B" & row_final) _
            , SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
        .Add2 Key:=Range("C2:C" & row_final) _
            , SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal

    End With

    ' 排序
    With tarSheet.Sort
    
        .SetRange Rows("2:" & row_final)
        .Header = xlNo
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
        
    End With

    '删除辅助列
    Range("B:D").Delete Shift:=xlToLeft
    
    MsgBox "Done!"

    Exit Sub

End Sub

Function GetLetters(ByVal str As String) As String

    '提取单号末尾的字母
    
    '如BYD24-0001001-AA1, 提取AA
    
    Dim regEx As Object, matches As Object
    
    Set regEx = CreateObject("VBScript.RegExp")
    
    With regEx
    
        .Global = True
        
        .IgnoreCase = False
        
        .Pattern = "-([A-Za-z]+)\d+$"
        
    End With
    
    Set matches = regEx.Execute(str)
    
    If matches.Count > 0 Then
    
        GetLetters = matches(0).SubMatches(0)
        
    Else
    
        GetLetters = "A"        '默认值为A
        
    End If
    
End Function

Function GetNumbers(ByVal str As String) As String

    '提取单号末尾的数字
    
    '如BYD24-0001001-AA3, 提取3

    Dim regEx As Object, matches As Object
    
    Set regEx = CreateObject("VBScript.RegExp")
    
    With regEx
    
        .Global = True
        
        .IgnoreCase = False
        
        .Pattern = "-[A-Za-z]+(\d+)$"
        
    End With
    
    Set matches = regEx.Execute(str)
    
    If matches.Count > 0 Then
    
        GetNumbers = Format(matches(0).SubMatches(0), "0000")
        
    Else
    
        GetNumbers = "0001"     '默认值为0001
        
    End If
    
End Function

在上述代码中,程序临时添加三个辅助列(B:D列),借助这三个辅助列进行排序。排序结束后,将这三个辅助列删去。

排序后的结果如下:

相关资料:

[1] VBA: 单元格区域基于指定列重新排序(3)

[2] 讯飞星火大语言模型

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-04-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据处理与编程实践 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档