何谓自定义排序,就是按指定的顺序对数据源进行排序呗。
 
共分享了三种方法:
第1种方法是系统自带的OrderCustom,优点是代码简洁,缺点是自定义序列有字符长度限制(255个)。
第2种方法是字典+数组设置序列号,再使用了辅助列进行排序。优点是不会破坏单元格的形式和结构,比如单元格中存在的公式、背景等。
第3种方法是只使用字典+数组,借助简单桶排序的技巧,直接对数据在数组中进行排序。优点是效率较高,缺点是会破坏单元格的结构,比如消除公式等。
(第1种建议掌握,第2种建议了解,第3种……能懂就懂,不懂先放着吧~)
 
举个例子。
如下图所示,A:C列是数据源。
现需要根据E列所指定的部门先后顺序,对数据源进行重新排序,如果部门不在指定序列内,则排放在数据源末尾。
Sub 自定义排序1()
    'eh技术论坛 VBA编程学习与实践 看见星光
    Dim n&, rng As Range
    Set rng = Range("e2:e" & Cells(Rows.Count, "e").End(xlUp).Row)
   Application.AddCustomList (rng)
   '增加一个自定义序列,该参数除了支持单元格对象,也支持数组。
    n = Application.CustomListCount
    '自定义序列的数目
    Range("a:c").Sort key1:=[a1], order1:=xlAscending, HEADER:=xlYes, ordercustom:=n + 1
   '使用自定义排序,ordercustom指定使用哪个自定义序列排序。
   '当使用自定义排序时,需要将OrderCustom参数设置为指定的序列在自定义列表中的顺序加1
   Application.DeleteCustomList n
    '删除新增的自定义序列
End Sub
 
Sub 自定义排序2()
    Dim d As Object, r, i&, arr, brr
    Set d = CreateObject("ing.dictionary")
    r = Range("e2:e" & Cells(Rows.Count, "e").End(xlUp).Row).Value
    For i = 1 To UBound(r)
       d(r(i, 1)) = i '目标序列循环装入字典,序号作为item
    Next
    arr = Range("a2:c" & Cells(Rows.Count, 1).End(xlUp).Row)
    '数据源装入数组arr
    ReDim brr(1 To UBound(arr), 1 To 1)
   '声明数组brr装原部门在指定序列中的序号
    For i = 1 To UBound(arr)
       If d.exists(arr(i, 1)) Then
           brr(i, 1) = d(arr(i, 1)) '将原部门在指定序列中的序列号装入brr
       Else
           brr(i, 1) = "指定序列不存在"
       End If
    Next
    [d:d].Insert
    '在D列插入一列
    [d2].Resize(UBound(brr), 1) = brr
    '新的序列号放入D列
    Range("a:d").Sort key1:=[d1], order1:=xlAscending, Header:=xlYes 'D列升序排序
    [d:d].Delete '删除D列
    Set d = Nothing
End Sub
 
Sub 自定义排序3()
    'eh技术论坛公众号 VBA编程学习与实践 看见星光
    Dim d As Object, i&, n&, x&, k&, j&
    Dim r, arr, brr, crr
    Set d = CreateObject("ing.dictionary")
    '后期绑定字典
    r = Range("e2:e" & Cells(Rows.Count, "e").End(xlUp).Row).Value
    For i = 1 To UBound(r)
       d(r(i, 1)) = i '目标序列循环装入字典,序号作为item
    Next
    arr = Range("a2:c" & Cells(Rows.Count, 1).End(xlUp).Row)
    '数据源装入数组
    ReDim brr(1 To d.Count + 1, 1 To 1)
   'brr数组用于按序号装数组arr的行号,类似于桶排序的桶
    For i = 1 To UBound(arr)
       If d.exists(arr(i, 1)) Then
          '如果字典中存在相关部门……
           n = d(arr(i, 1))
          '该部门在指定序列中的序号
           brr(n, 1) = brr(n, 1) & "," & i
          '将该部门在arr中的行号装入数组brr对应的序号行
       Else
          brr(UBound(brr), 1) = brr(UBound(brr), 1) & "," & i
          '如果字典中不存在,放入数组brr最后一行
       End If
    Next
    ReDim crr(1 To UBound(arr), 1 To UBound(arr, 2))
    '数组crr放排序后的结果
    For i = 1 To UBound(brr)
       If brr(i, 1) <> "" Then
          '如果不为空,则有符合指定排序条件的关键词
           r = Split(brr(i, 1), ",")
          '将brr该位置储存的行号取出
           For x = 1 To UBound(r)
              k = k + 1 '累加行
              For j = 1 To UBound(arr, 2)
                 crr(k, j) = arr(r(x), j)
                 '遍历指定行位置数组arr的值移到crr
              Next
           Next
       End If
    Next
    Range("a2:c" & Cells(Rows.Count, 1).End(xlUp).Row) = crr
   '将数组crr排序后的结果放回单元格区域
    Set d = Nothing '释放字典
    Erase arr: Erase brr: Erase crr
    '释放数组
End Sub

【转载】EXCEL VBA 自定义排序的三种方法的更多相关文章

  1. 转载:WinForm中播放声音的三种方法

    转载:WinForm中播放声音的三种方法 金刚 winForm 播放声音 本文是转载的文章.原文出处:http://blog.csdn.net/jijunwu/article/details/4753 ...

  2. Qt 自定义事件(三种方法:继承QEvent,然后Send Post就都可以了,也可以覆盖customEvent函数,也可覆盖event()函数)

    Qt 自定义事件很简单,同其它类库的使用很相似,都是要继承一个类进行扩展.在 Qt 中,你需要继承的类是 QEvent. 继承QEvent类,你需要提供一个QEvent::Type类型的参数,作为自定 ...

  3. linux之在当前目录下按照文件大小进行排序的三种方法

    当前目录下按照文件大小排序 [root@test23 script]# ls -lSh 总用量 44K -rw-r--r-- 1 root root 2.4K 12月 8 17:24 test.con ...

  4. Qt下存储读写应用程序设置的三种方法

    一.简介 用户对应用程序经常有这样的要求:要求它能记住它的settings,比如窗口大小.位置和密码等等.有三种方法可以实现: 使用注册表: 使用配置文件(.ini): 使用自定义文件(例如.txt) ...

  5. 【转】asp.net导出数据到Excel的三种方法

    来源:http://www.cnblogs.com/lishengpeng1982/archive/2008/04/03/1135490.html 原文出处:http://blog.csdn.net/ ...

  6. 三种方法实现Hadoop(MapReduce)全局排序(1)

    我们可能会有些需求要求MapReduce的输出全局有序,这里说的有序是指Key全局有序.但是我们知道,MapReduce默认只是保证同一个分区内的Key是有序的,但是不保证全局有序.基于此,本文提供三 ...

  7. 服务器文档下载zip格式 SQL Server SQL分页查询 C#过滤html标签 EF 延时加载与死锁 在JS方法中返回多个值的三种方法(转载) IEnumerable,ICollection,IList接口问题 不吹不擂,你想要的Python面试都在这里了【315+道题】 基于mvc三层架构和ajax技术实现最简单的文件上传 事件管理

    服务器文档下载zip格式   刚好这次项目中遇到了这个东西,就来弄一下,挺简单的,但是前台调用的时候弄错了,浪费了大半天的时间,本人也是菜鸟一枚.开始吧.(MVC的) @using Rattan.Co ...

  8. vue自定义指令,比onerror更优雅的方式实现当图片加载失败时使用默认图,提供三种方法

    首先,来看下效果图(演示一下图片正常加载与加载失败时的效果) 在线体验地址:https://hxkj.vip/demo/vueImgOnerror/ 一.常规方法解决 我们都知道,img标签支持one ...

  9. 【朝花夕拾】Android自定义View篇之(四)自定义View的三种实现方式及自定义属性使用介绍

    前言 转载请声明,转自[https://www.cnblogs.com/andy-songwei/p/10979161.html],谢谢! 尽管Android系统提供了不少控件,但是有很多酷炫效果仍然 ...

随机推荐

  1. 关于vmware虚拟机的ova/ovf转换成aws上的AMI镜像

    很多时候,我们会有这样的需求,需要将DC中vmware虚拟化的服务器,迁移到aws上,我们就得先将vmware虚拟机导出,然后转换 关于vmvare虚拟的导出备份,一般有ova(Open Virtua ...

  2. Docker | redis安装及测试

    此篇文章目的是熟悉一下redis的下载安装使用,为后面部署redis集群做准备. 下载安装 linux上,我在/download目录下,执行下载的命令 root@--- ~]# wget http:/ ...

  3. [C#]SourceGenerator实战: 对任意对象使用await吧!!!

    [C#]SourceGenerator实战: 对任意对象使用await吧!!! 前言 本文记录一次简单的 SourceGenerator 实战,最终实现可以在代码中 await 任意类型对象,仅供娱乐 ...

  4. LeetCode------合并两个有序数组(4)【数组】

    来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/merge-sorted-array 1.题目 给你两个按 非递减顺序 排列的整数数组 nums ...

  5. 『现学现忘』Git分支 — 39、Git中分支与对象的关系

    目录 1.Git对象之间的关系 2.提交对象与分支的关系 (1)提交对象与分支的关系 (2)分支说明 (3)HEAD与分支的关系 1.Git对象之间的关系 我们之前学了Git的三个对象:提交对象.树对 ...

  6. 1.Python面向对象基础

    面向对象(OOP) 面向对象编程--object oriented programming 简写 OOP   面向过程和面向对象的区别: 面向过程: 1.把完成某一个需求的所有步骤从头到尾逐步实现 2 ...

  7. Golang 加密方法

    如果想直接使用我下列的库 可以直接go get 我的github go get -u github.com/hybpjx/InverseAlgorithm md5 加密--不可逆 MD5信息摘要算法是 ...

  8. Python基础部分:8、for循环和range的使用

    目录 一.while循环补充说明 1.死循环 2.嵌套及全局标志位 二.for...循环 1.for...循环特点 2.for...循环语法结构 三.range方法 1.什么是range 2.不同版本 ...

  9. 检测轮廓 获取其最值的坐标 opencv-python

    一.基础知识 图像清晰度评价算法有多种 空域中,主要考察图像的邻域对比度,即相邻像素间灰度特征的 梯度差: 频域中,主要考察图像的频率分量,清晰的图像高频分量多,模糊的图像低频分量多. 灰度值 把白色 ...

  10. Day03.1:初学者安装IDEA后需要知道的小技巧

    初学者安装IDEA后需要知道的小技巧 1.输入psvm直接生成 main方法 2.输入sout可以直接生成输出语句 3.代码放大设置 4.注释颜色更改 5.代码字体大小通过Ctrl+鼠标滑轮控制的设置 ...