ExcelTip.Net留存知识帖 ---【注:附件之前被网盘供应商清空后,现已修复-现已修复-现已修复为本地下载!】
现在位置:首页 > E问E答 > Excel VBA > 如何用vba代码实现数据区依指定单元格命令文本排序(含自定义排序)?

如何用vba代码实现数据区依指定单元格命令文本排序(含自定义排序)?

作者:绿色风 分类: 时间:2022-08-17 浏览:92
楼主
kevinchengcw
Q: 如何用vba代码实现数据区依指定单元格命令文本排序(含自定义排序)?
A: 代码如下:
  1. Private Sub Worksheet_Change(ByVal Target As Range)   '利用工作表change事件进行处理
  2. If Not Intersect(Target, [n1]) Is Nothing Then  '判断变化了的单元格范围是否包含指定单元格,本例为N1单元格
  3.     Application.EnableEvents = False  '关闭事件响应
  4.     Dim Rng As Range
  5.     Set Rng = Range("b2:l" & Cells(Rows.Count, 3).End(3).Row)  '取得数据区范围,赋值给变量,便于后期引用
  6.     Select Case [n1].Value  '判断命令单元格的文本内容(注:文本内容以数据有效性方式存在及选择,防止输错)
  7.         Case Is = "按班主任排列"  '如果是"按班主任排列",该排序为自定义序列排序
  8.             Dim Rules, Arr, Result, N&, I&, T&, C&, Dic As Object
  9.             Rules = Split("周老师,梁老师,何老师,江老师", ",")  '定义序列,并赋值给数组
  10.             Set Dic = CreateObject("scripting.dictionary")  '创建字典,用于装载已处理过的自定义序列字段,方便后期判断
  11.             Arr = Rng.Value  '将数据源赋值给数组
  12.             ReDim Result(LBound(Arr) To UBound(Arr), LBound(Arr, 2) To UBound(Arr, 2))  '定义结果数组与源数组一致
  13.             T = LBound(Arr)     '取得数组行的最小下标值,即初始化结果数组行数值
  14.             For N = LBound(Rules) To UBound(Rules)  '循环自定义序列各项
  15.                 Dic.Add Rules(N), ""  '添加当前循环到的项到字典中
  16.                 For I = LBound(Arr) To UBound(Arr)  '循环数据源各行
  17.                     If Arr(I, 1) = Rules(N) Then  '如果当前行第一列的值与自定义序列当前循环到的值一致,则
  18.                         For C = LBound(Arr, 2) To UBound(Arr, 2)  '循环将当前行对应各列的值从源数据数组写入结果数据数组当前行
  19.                             Result(T, C) = Arr(I, C)
  20.                         Next C
  21.                         T = T + 1  '行值下移一行
  22.                     End If
  23.                 Next I
  24.             Next N
  25.             For I = LBound(Arr) To UBound(Arr)  '二次循环数据源各行,用于找出有班主任名但未出现在自定义序列里的数据项,同样写入结果数组中
  26.                 If Not Dic.exists(Arr(I, 1)) And Trim(Arr(I, 1)) <> "" Then
  27.                     For C = LBound(Arr, 2) To UBound(Arr, 2)
  28.                         Result(T, C) = Arr(I, C)
  29.                     Next C
  30.                     T = T + 1
  31.                 End If
  32.             Next I
  33.             For I = LBound(Arr) To UBound(Arr)  '第三次循环数据源各行,找出未写班主任名的数据项,写入结果数组(这样,未写班主任名的数据项就排到了数据的最后面)
  34.                 If Trim(Arr(I, 1)) = "" Then
  35.                     For C = LBound(Arr, 2) To UBound(Arr, 2)
  36.                         Result(T, C) = Arr(I, C)
  37.                     Next C
  38.                     T = T + 1
  39.                 End If
  40.             Next I
  41.             Rng = Result   '将结果数组写入数据区
  42.             Set Dic = Nothing  '清空字典项目
  43.         Case Is = "按姓氏排列"  '如果是"按姓氏排列"则将数据源区利用excel自有功能根据姓名列进行排序
  44.             Rng.Sort Rng.Cells(1, 2)
  45.         Case Is = "语文成绩升序排列"  '如果是"语文成绩升序排列"则将数据源区利用excel自有功能根据语文成绩列进行升序排序
  46.             Rng.Sort Rng.Cells(1, 5), xlAscending
  47.         Case Is = "总分降序排列"  '如果是"总分降序排列"则将数据源区利用excel自有功能根据总分列进行降序排序
  48.             Rng.Sort Rng.Cells(1, 11), xlDescending
  49.         Case Else  '其他可能出现的情况进行提醒
  50.             MsgBox "排序依据无效"  
  51.     End Select
  52.     Application.EnableEvents = True  '打开事件响应
  53. End If
  54. End Sub
详见附件及素材源帖.
EXCEL中单元格发生变化时,触发事件。。。.rar
2楼
海洋之星
这么长的VBA代码,
3楼
纵鹤擒龙水中月
学习了

免责声明

有感于原ExcelTip.Net留存知识的价值及部分知识具有的时间限定性因素, 经与ExcelTip.Net站长Apolloh商议并征得其同意, 现将原属ExcelTip.Net的知识帖采集资料于本站点进行展示, 供有需要的人士查询使用,也慰缅曾经的论坛时代。 所示各个帖子的原作者如对版权有异议, 可与本人沟通提出,或于本站点留言,我们会尽快处理。 在此,感谢ExcelTip.Net站长Apolloh的支持,感谢本站点所有人**绿色风(QQ:79664738)**的支持与奉献,特此鸣谢!
------本人网名**KevinChengCW(QQ:1210618015)**原ExcelTip.Net总版主之一

评论列表
sitemap