ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
楼主: 伶俐的毛豆

[求助] 二维数组多条件排序

[复制链接]

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-1-18 21:55 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
剑指E 发表于 2024-1-18 12:43
是,你用工作表排序功能验证下

老师,能标注一下在哪里改升降序和参照列吗

TA的精华主题

TA的得分主题

发表于 2024-1-18 22:01 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
Sub 排序二维()
    arr = Range("A2:F" & Cells(Rows.Count, "A").End(xlUp).Row) '不要含标题
    二维数组排序 arr, Array(6, 3, 4, 5), Array(2, 2, 2, 2) '为数字排序不要文本 依次按主次顺序排序 1为升序 其余为降序
    Range("I2").Resize(UBound(arr), 6) = arr
End Sub
Function 二维数组排序(ByRef arr, ByVal toSortCols_arr, ByVal orders_ASC_or_DESC_arr)
    If LBound(toSortCols_arr) = 0 Then ReDim Preserve toSortCols_arr(1 To UBound(toSortCols_arr) + 1)
    If LBound(orders_ASC_or_DESC_arr) = 0 Then ReDim Preserve orders_ASC_or_DESC_arr(1 To UBound(orders_ASC_or_DESC_arr) + 1)
    For i = UBound(toSortCols_arr) To LBound(toSortCols_arr) Step -1
        sortArr arr, toSortCols_arr(i), orders_ASC_or_DESC_arr(i)
    Next
End Function
Function sortArr(ByRef arr, ByVal sort_which_col_bgn_from1 As Integer, ByVal ASC_or_DESC)
    l = LBound(arr)
    u = UBound(arr)
    If u = 0 Then Exit Function
    sort_which_col_bgn_from1 = IIf(LBound(arr, 2) = 0, sort_which_col_bgn_from1 - 1, sort_which_col_bgn_from1)
    Dim data(), result()
    '读数组
    If l = 0 Then
        ReDim result(0 To u, 0 To 1): ReDim data(0 To u, 0 To 1)
        For i = 0 To u
            data(i, 0) = arr(i, sort_which_col_bgn_from1)
            data(i, 1) = i
        Next
    ElseIf l = 1 Then
        ReDim result(0 To u - 1, 0 To 1): ReDim data(0 To u - 1, 0 To 1)
        For i = 0 To u - 1
            data(i, 0) = arr(i + 1, sort_which_col_bgn_from1)
            data(i, 1) = i + 1
        Next
        u = u - 1
    Else
        Exit Function
    End If
    '排序
    数据段长 = 1
    For 趟数 = 0 To Fix(Log(u) / Log(2)) Step 1
        数据段长 = 数据段长 * 2
        For 数据段首 = 0 To u Step 数据段长
            If 数据段首 + 数据段长 - 1 > u Then
                数据段尾 = u
            Else
                数据段尾 = 数据段首 + 数据段长 - 1
            End If
            If 数据段首 + 数据段长 / 2 - 1 > u Then
                分割点 = u
            Else
                分割点 = 数据段首 + 数据段长 / 2 - 1
            End If
            Call Merge(data, result, 数据段首, 分割点, 数据段尾, ASC_or_DESC)
        Next
        For i = 0 To u
            data(i, 0) = result(i, 0)
            data(i, 1) = result(i, 1)
        Next
    Next
    '输出
    tempArr = arr
    If l = 0 Then
        For i = 0 To u
            For j = LBound(arr, 2) To UBound(arr, 2)
                arr(i, j) = tempArr(data(i, 1), j)
            Next
        Next
    Else
        For i = 0 To u
            For j = LBound(arr, 2) To UBound(arr, 2)
                arr(i + 1, j) = tempArr(data(i, 1), j)
            Next
        Next
    End If
End Function
Function Merge(data(), result(), ByVal 数据段首, ByVal 分割点, ByVal 数据段尾, ByVal ASC_or_DESC)
    i = 分割点 + 1: j = 数据段首
    Do While 数据段首 <= 分割点 And i <= 数据段尾
        If ASC_or_DESC = 1 Then
            If data(数据段首, 0) <= data(i, 0) Then
                result(j, 0) = data(数据段首, 0)
                result(j, 1) = data(数据段首, 1)
                数据段首 = 数据段首 + 1
            Else
                result(j, 0) = data(i, 0)
                result(j, 1) = data(i, 1)
                i = i + 1
            End If
        Else
            If data(数据段首, 0) >= data(i, 0) Then
                result(j, 0) = data(数据段首, 0)
                result(j, 1) = data(数据段首, 1)
                数据段首 = 数据段首 + 1
            Else
                result(j, 0) = data(i, 0)
                result(j, 1) = data(i, 1)
                i = i + 1
            End If
        End If
        j = j + 1
    Loop
    For rest = 数据段首 To 分割点
        result(j, 0) = data(rest, 0)
        result(j, 1) = data(rest, 1)
        j = j + 1
    Next
    For rest = i To 数据段尾
        result(j, 0) = data(rest, 0)
        result(j, 1) = data(rest, 1)
        j = j + 1
    Next
End Function

TA的精华主题

TA的得分主题

发表于 2024-1-18 22:02 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
简单 我给你一个 有模版写法说明

TA的精华主题

TA的得分主题

发表于 2024-1-18 22:06 | 显示全部楼层

你这是固定写法 没有什么用处 我给的是内存二维数组通用函数 只需要用时调用即可 多少列 升降序自由组合

TA的精华主题

TA的得分主题

发表于 2024-1-18 22:15 来自手机 | 显示全部楼层
本帖最后由 剑指E 于 2024-1-19 08:42 编辑
伶俐的毛豆 发表于 2024-1-18 21:55
老师,能标注一下在哪里改升降序和参照列吗

就是最后的三级嵌套for循环,顺着循环就是升序,倒着循环就是降序。
image.png

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-6-17 20:16 | 显示全部楼层
剑指E 发表于 2024-1-18 22:15
就是最后的三级嵌套for循环,顺着循环就是升序,倒着循环就是降序。

image.png
老师您这个程序怎么修改适应大于3列的数据排序呢,假设现在有5列数据,以a列升序,c列降序,e列降序,怎么修改呢

TA的精华主题

TA的得分主题

发表于 2024-6-17 22:20 | 显示全部楼层
还是老实放工作表排序吧,搞那么麻烦做什么,放临时工作表又不影响啥,排序完删除就是了,这么高效率简单的事情不去做,而非要用什么高大上的代码,又慢又没有应用价值

TA的精华主题

TA的得分主题

发表于 2024-6-17 22:30 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
_二维数组排序_多KEY_已验证.rar (1.42 MB, 下载次数: 11)

香川群子的

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-6-18 08:15 | 显示全部楼层

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-6-18 17:16 | 显示全部楼层
剑指E 发表于 2024-1-18 22:15
就是最后的三级嵌套for循环,顺着循环就是升序,倒着循环就是降序。

可以帮忙改成大于3列的排序吗(假设我的目标数据是7列,分别参照a,d,f 列降序)
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-6-26 23:20 , Processed in 0.042576 second(s), 8 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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