ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[求助] 排序问题

[复制链接]

TA的精华主题

TA的得分主题

发表于 2013-12-1 21:09 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖最后由 hyefeifei 于 2013-12-1 21:20 编辑

中间可以不是P,但必须是一位,右边数字在一到四位之间
简单解释一下,就是把你的字符串,转换为数字,加上一个小数,保证唯一
再用快速排序法排序,然后用字典取回,不用字典,在快递排序法里加个输出数组参数
存储位置也可,这里用字典法
  1. Sub Test()
  2.     Dim arr, i&, str As String, strte, d, brr()
  3.     Set d = CreateObject("Scripting.Dictionary")
  4.     arr = Range("a2:a" & Cells(Rows.Count, "a").End(xlUp).Row)
  5.     For i = 1 To UBound(arr)
  6.         str = Val(Right(arr(i, 1), Len(arr(i, 1)) - 2))
  7.         str = str & Format(Right(arr(i, 1), Len(arr(i, 1)) - 3 - Len(str)), "0000")
  8.         strte = Asc(Left(arr(i, 1), 1)) * Asc(Mid(arr(i, 1), 1, 1)) & Format(str, "0000000")   '至此把字符串转为数字
  9.         strte = CDbl(strte)                     '转为双精度数字
  10.         strte = strte + i / 10000              '加上一小数,保证数字唯一性
  11.         d(strte) = arr(i, 1)                          '存到字典里
  12.         arr(i, 1) = strte                              '把数组转为数值数组
  13.     Next
  14.     QSort arr                                        '快速排序
  15.     ReDim brr(1 To UBound(arr), 0)
  16.     For i = 1 To UBound(arr)              '取回排序结果
  17.         brr(i, 0) = d(arr(i, 1))
  18.     Next
  19.     Range("c2").Resize(UBound(arr)) = brr
  20. End Sub
  21. '快速排序法(当然可用其他如冒泡之类),如主程序不用字典,可在此排序法上加一输出参数,存储元素位置
  22. Sub QSort(var As Variant, Optional iLeft As Long, Optional iRight As Long)
  23.     Dim i&, j&, vTemp1, vTemp2, iMid&, Temp
  24.     If IsMissing(iLeft) Then iLeft = LBound(var)
  25.     If IsMissing(iRight) Then iRight = UBound(var)
  26.     If iLeft < iRight Then
  27.         iMid = (iLeft + iRight) \ 2
  28.         vTemp1 = var(iMid, 1)
  29.         i = iLeft
  30.         j = iRight
  31.         Do
  32.             vTemp2 = var(i, 1)
  33.             Do While vTemp2 < vTemp1
  34.                 i = i + 1
  35.                 vTemp2 = var(i, 1)
  36.             Loop
  37.             vTemp2 = var(j, 1)
  38.             Do While vTemp2 > vTemp1
  39.                 j = j - 1
  40.                 vTemp2 = var(j, 1)
  41.             Loop
  42.             If i <= j Then
  43.                 Temp = var(i, 1): var(i, 1) = var(j, 1): var(j, 1) = Temp
  44.                 i = i + 1
  45.                 j = j - 1
  46.             End If
  47.         Loop Until i > j
  48.         Call QSort(var, iLeft, j)
  49.         Call QSort(var, i, iRight)
  50.     End If
  51. End Sub
复制代码
排序.rar (12.49 KB, 下载次数: 12)

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-12-2 18:28 | 显示全部楼层
hyefeifei 发表于 2013-12-1 21:09
中间可以不是P,但必须是一位,右边数字在一到四位之间
简单解释一下,就是把你的字符串,转换为数字,加上 ...

好象是原列复制,,没有做任何排序操作!!!

TA的精华主题

TA的得分主题

发表于 2013-12-3 08:15 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
呵,不好意思,没做测试就传了上去,错在那个排序程序(Qsort),已经修正好了。
简单再说几句,思路很简单,主程序就是把:
                                       
HH12P132
HH12P32
HH141P21
HH36-12
JH17P32
JH22-42
这6个字符串,转化为:
51840120132.0001
51840120032.0002
51841410021.0003
51840360012.0004
54760170032.0005
54760220042.0006
这6个数字,至此,对6个数排序,你应该没问题了吧
如果数据不多,你可换个容易理解的冒泡排序,对数字排序。
附件如下:
排序.rar (11.33 KB, 下载次数: 7)






TA的精华主题

TA的得分主题

 楼主| 发表于 2013-12-3 10:21 | 显示全部楼层
hyefeifei 发表于 2013-12-3 08:15
呵,不好意思,没做测试就传了上去,错在那个排序程序(Qsort),已经修正好了。
简单再说几句,思路很简单, ...

过程我可能还需要学习理解一下,
现在结果依然是复制,没有操作!

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-12-3 10:29 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
hyefeifei 发表于 2013-12-3 08:15
呵,不好意思,没做测试就传了上去,错在那个排序程序(Qsort),已经修正好了。
简单再说几句,思路很简单, ...

不好意思,我看错了,还是做了排序,,
但我的意思是,大分为两类,
即P在前,-在后,
在此基础上P类按升序排,-类也按升序排
排后的结果是:
HH12P132
HH12P32
HH141P21
JH17P32
HH36-12
JH22-42

TA的精华主题

TA的得分主题

发表于 2013-12-3 11:08 | 显示全部楼层
  1. Sub test()
  2. Dim a(), w() As Long
  3. r = Range("a2", [a65536].End(3))
  4. ReDim a(1 To UBound(r), 1 To 4)
  5. With CreateObject("VBSCRIPT.REGEXP")
  6.   .Pattern = "(\D+)(\d+)(\D+)(\d+)"
  7.   For i = 1 To UBound(r)
  8.     t = Split(.Replace(r(i, 1), "$1 $2 $3 $4"))
  9.     a(i, 1) = t(0)
  10.     a(i, 2) = Val(t(1))
  11.     a(i, 3) = (t(2))
  12.     a(i, 4) = (t(3))
  13.   Next
  14. End With
  15. ZSort a, w, 3, 1, 1, 0, 2, 0, 4, 0
  16. ReDim a(1 To UBound(r), 1 To 1)
  17. For i = 1 To UBound(r)
  18.   a(i, 1) = r(w(i), 1)
  19. Next
  20. [c2].Resize(UBound(r)) = a
  21. End Sub
复制代码

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-12-3 12:00 | 显示全部楼层
Zamyi 发表于 2013-12-3 11:08

子过程或函数未定义

TA的精华主题

TA的得分主题

发表于 2013-12-3 12:23 | 显示全部楼层
czr0373 发表于 2013-12-3 12:00
子过程或函数未定义

在6L 啊。
~~

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-12-3 12:49 | 显示全部楼层
Zamyi 发表于 2013-11-26 10:42
二维数组排序的精髓只是对其记录的位置进行排序,排序过程中原数组都没有动,可以称之为“虚拟排序”吧。 ...

这里面没有把“P”和“-”分成两类来排,我意思是“P”类在前,“-”类的在后

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-12-3 12:53 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
yjh_27 发表于 2013-12-3 12:23
在6L 啊。
~~

没有问题的,万分感谢!!
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-11-15 07:39 , Processed in 0.034756 second(s), 9 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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