ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 863|回复: 22

[分享] 归并算法对二维数组的多列依次排序

[复制链接]

TA的精华主题

TA的得分主题

发表于 2024-7-31 10:42 | 显示全部楼层 |阅读模式
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖已被收录到知识树中,索引项:排序
本帖最后由 cgzn 于 2024-8-1 15:26 编辑

Option Compare Text '放模块最顶部

'排序规则SortRule的格式为"1,-2,3"...,其中-2的-表示降序排列,2表示对arr的2列排序,顺序从1-3列依次排序

Sub ColsPX(arr, SortRule, Optional lt = -1, Optional rt = -1, Optional px = 0)
    If lt = -1 Then lt = LBound(arr)
    If rt = -1 Then rt = UBound(arr)
    If px = 0 Then MergSort1 arr, SortRule, lt, rt: px = 1
    pxr = Split(SortRule, ","): j1 = pxr(px - 1): j = Abs(j1): If px <= UBound(pxr) Then j0 = pxr(px)
    If lt < rt And px <= UBound(pxr) Then
        For i = lt + 1 To rt
            If arr(i, j) = arr(i - 1, j) Then n = n + 1 Else n0 = n: n = 0
            If n0 > 0 And n = 0 Then
                rtn = i - 1: ltn = i - 1 - n0: MergSort1 arr, j0, ltn, rtn: ColsPX arr, SortRule, ltn, rtn, px + 1
            ElseIf i = rt And n > 0 Then rtn = rt: ltn = i - n: MergSort1 arr, j0, ltn, rtn: ColsPX arr, SortRule, ltn, rtn, px + 1
            End If
        Next
    End If
End Sub

Sub MergSort1(arr, SortRule, Optional lt = -1, Optional rt = -1)
    pxr = Split(SortRule, ","): subsize = 1: Dim tmprr(): Dim jd As Long: jd = pxr(0)
    If lt = -1 Then lt = LBound(arr)
    If rt = -1 Then rt = UBound(arr)
    ci = LBound(arr, 2): cend = UBound(arr, 2): ReDim tmprr(lt To rt, ci To cend)
    While subsize < rt - lt + 1
        lf = lt
        While lf < rt
            md = Application.Min(lf + subsize - 1, rt): rg = Application.Min(lf + 2 * subsize - 1, rt)
            For i = lf To rg
                For j = ci To cend
                    tmprr(i, j) = arr(i, j)
                Next
            Next
            i = lf: j = md + 1: k = lf
            While i <= md And j <= rg
                If tmprr(i, Abs(jd)) < tmprr(j, Abs(jd)) And jd > 0 Or tmprr(i, Abs(jd)) > tmprr(j, Abs(jd)) And jd < 0 Then
2:                      arr(k, ci) = tmprr(i, ci): If ci < cend Then ci = ci + 1: GoTo 2 Else ci = LBound(arr, 2)
                    i = i + 1
                Else
7:                      arr(k, ci) = tmprr(j, ci): If ci < cend Then ci = ci + 1: GoTo 7 Else ci = LBound(arr, 2)
                    j = j + 1
                End If
                k = k + 1
            Wend
            While i <= md
5:                  arr(k, ci) = tmprr(i, ci): If ci < cend Then ci = ci + 1: GoTo 5 Else ci = LBound(arr, 2)
                i = i + 1: k = k + 1
            Wend
            While j <= rg
6:                  arr(k, ci) = tmprr(j, ci): If ci < cend Then ci = ci + 1: GoTo 6 Else ci = LBound(arr, 2)
                j = j + 1: k = k + 1
            Wend
            lf = lf + 2 * subsize
        Wend
        subsize = subsize * 2
    Wend
End Sub

工作簿3.zip

834.01 KB, 下载次数: 35

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-7-31 10:44 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖最后由 cgzn 于 2024-7-31 14:17 编辑

对二维数组多列依此排序,我找了好久没有找到。自己花一天时间参照归并排序的方法写了一个,欢迎大佬指正。
效率还是没法和excel自带的排序方法比较,不知道这家伙用的什么排序方法。不过这个归并算法的速度也能接受了,16万行4列依次排序,10秒左右,1万行以内基本1秒不到。


使用时直接调用ColsPX arr,SortRule

TA的精华主题

TA的得分主题

发表于 2024-7-31 20:51 | 显示全部楼层

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-8-1 15:26 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2024-8-1 16:05 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
老师!后面的几个参数(lt,rt,px)是什么意思呢?

TA的精华主题

TA的得分主题

发表于 2024-8-1 16:08 | 显示全部楼层
cgzn 发表于 2024-8-1 15:26
已上传实例,请测试。

挺好的。
有实例主要是为了能更好的理解你这个数组的排序使用方法,便于推广。

TA的精华主题

TA的得分主题

发表于 2024-8-1 16:20 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
楼主最好解释一下几个参数的含义,lt应该是数组的下标,rt应该是数组的上标,px的含义不清楚。

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-8-1 17:00 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
songshihai 发表于 2024-8-1 16:05
老师!后面的几个参数(lt,rt,px)是什么意思呢?

lt是排序的二维数组的起始位置,rt是终点位置。
或者说,仅对二维数组的第lt行到第rt行排序。

TA的精华主题

TA的得分主题

发表于 2024-8-1 17:06 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
cgzn 发表于 2024-8-1 17:00
lt是排序的二维数组的起始位置,rt是终点位置。
或者说,仅对二维数组的第lt行到第rt行排序。

px是干啥的?

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-8-1 17:09 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
ykcbf1100 发表于 2024-8-1 16:20
楼主最好解释一下几个参数的含义,lt应该是数组的下标,rt应该是数组的上标,px的含义不清楚。

pxr是sortrule按英文逗号拆分的数组
比如:sortrule=”-1,-2,3,4"  是依此按arr的第一列降序,第二列降序,第三列升序,第四列升序排列
pxr=split(sortrule,",")
px就是pxr的下标,例如:px=1,pxr(px)=-2;px=2,pxr(px)=3
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-11-18 16:36 , Processed in 0.044432 second(s), 10 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表