ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[原创] 通过一题十解谈拓宽编程思路

  [复制链接]

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-3-28 16:03 | 显示全部楼层
本帖已被收录到知识树中,索引项:数据类型和基本语句
本帖最后由 doitbest 于 2013-4-3 15:15 编辑

方法9
此方案是用单元格读取实现的,1234的分组序号与A列数字共同构成了D列的数据,这里1234的分组序号起到了辅助列的作用,为此后的FIND查找打下基础。在完成其使命后,通过REPLACE替换,将分组序号删除。从十个示例的展示可以看出,单元格操作相比数组,尽管速度比较慢是主要缺点,但其能够充分借助函数、VBA方法、属性,表现出高度的灵活性,而数组一般只能借助循环、判断和少量的数组函数。因此,在解决实际问题时,并不一定唯数组马首是瞻,而要视具体情况灵活应用各种手段。一般来说,高手们往往固执于数组的应用,就有些僵化了。
Public Sub p9()
Dim rng As Range, i, max, x As Range, n
[d:e] = ""
Set rng = Range([a2], [a65536].End(3))
max = Evaluate("MAX(COUNTIF(" & rng.Address & "," & rng.Address & "))")
For i = 1 To max
    IIf([d1] = "", [d1], [d65536].End(3).Offset(2)).Resize(4) = Application.Transpose(Array(i & "," & 1, i & "," & 2, i & "," & 3, i & "," & 4)) ‘将1234与组序号连接起来,读入D列
Next
n = 1
For i = 2 To [a65536].End(3).Row
    If Cells(i, 1) <> (Val(Cells(i - 1, 1)) + 1) Then n = n + 1 ‘如果A列单元格数字不连续
    Set x = [d:d].Find(n & "," & Cells(i, 1), , , 1) ‘在D列查找确定行号,查找值为1234与组序号的连接字符串
    x.Offset(, 1) = Cells(i, 2)
Next
[d:d].Replace "*,", "", 2  ‘用替换删除组序号
End Sub

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-3-28 16:04 | 显示全部楼层
方法10
此方案明显是方法9的数组版。方法8、9、10的思路基本一致,差别在于分别用字典、单元格操作及数组实现。
Public Sub p10()
Dim rng As Range, i, j, max, ar, br(), cr, n, r
[d:e] = ""
Set rng = Range([a2], [a65536].End(3))
ar = Range([a1], [b65536].End(3))
max = Evaluate("MAX(COUNTIF(" & rng.Address & "," & rng.Address & "))")
ReDim br(1 To max * 5, 1 To 2)
For i = 1 To max ‘通过双层循环将组序号与1234的连接字符串读入数组第一列
    n = n + 5
    For j = 4 To 1 Step -1
        br(n - j, 1) = n / 5 & "," & 5 - j
    Next
Next
cr = Application.Index(br, , 1)
n = 1
For i = 2 To UBound(ar)
    If ar(i, 1) <> (Val(ar(i - 1, 1)) + 1) Then n = n + 1 ‘如果数组相邻值不连接,则组序号加1
    r = Application.Match(n & "," & ar(i, 1), cr, 0) ‘用MATCH查找确定行号,查找值为组序号与1234的连接字符串
    br(r, 2) = ar(i, 2)
Next
[d1].Resize(UBound(br), 2) = br
[d:d].Replace "*,", "", 2 ‘用替换删除组序号
End Sub

TA的精华主题

TA的得分主题

发表于 2013-3-28 16:20 | 显示全部楼层
本帖最后由 zhaogang1960 于 2013-3-28 16:22 编辑

直看得是眼花缭乱,还不知道原要求是什么,凑了一个数组的,看看是否符合要求:
  1. Sub Macro1()
  2.     Dim arr, brr(), i&, j&, m&
  3.     arr = Range("A2:B" & Range("A65536").End(xlUp).Row)
  4.     ReDim brr(1 To UBound(arr) * 2, 1 To 2)
  5.     For i = 1 To UBound(arr) Step 3
  6.         For j = i To i + 2
  7.             brr(arr(j, 1) + m, 2) = arr(j, 2)
  8.         Next
  9.         For j = 1 To 4
  10.             m = m + 1
  11.             brr(m, 1) = j
  12.         Next
  13.         m = m + 1
  14.     Next
  15.     Columns("D:F").ClearContents
  16.     [d2].Resize(m, 2) = brr
  17. End Sub
复制代码

点评

这个代码可以处理附件例子,但可能不具备足够的通用性。 比如,每一组不是4个而是5个、6个、7个数据,或者每一组内可能有的值个数分别为1个、2个、3个、4个……  发表于 2013-4-4 13:13

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-3-28 16:30 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
谢谢版主关注,代码完全符合要求!第11种解法出来了,新的解法还会远吗?
另外,代码加格式总出错,索性就直接贴上来了,有些乱,非常不方便观看,也请大家谅解。

TA的精华主题

TA的得分主题

发表于 2013-3-28 20:39 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖最后由 yjh_27 于 2013-3-28 20:42 编辑

第12种解法

  1. Public Sub p12() Dim arr, brr(), i, m, n
  2. arr = Range("a2:b" & [a65536].End(3).Row)
  3. ReDim brr(1 To UBound(arr) * 5, 1 To 3)
  4. n = 1
  5. Do While n <= UBound(arr)
  6.     For i = 1 To 4
  7.         m = m + 1
  8.         brr(m, 1) = i
  9.         If n <= UBound(arr) Then
  10.             If arr(n, 1) = i Then
  11.                 brr(m, 2) = arr(n, 2)
  12.                 brr(m, 3) = n + 1   'a2  +1
  13.                 n = n + 1
  14.             End If
  15.         End If
  16.     Next
  17.     m = m + 1
  18. Loop
  19. Range("d2").Resize(m, 3) = brr
  20. Erase arr, brr
  21. End Sub
复制代码

点评

这个是目前最好的数组算法。 还略有改进余地。  发表于 2013-4-4 14:26

TA的精华主题

TA的得分主题

发表于 2013-4-3 19:57 | 显示全部楼层
感觉像看天书,差句太大了

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-4-3 20:01 | 显示全部楼层
xminli 发表于 2013-4-3 19:57
感觉像看天书,差句太大了

都这这么过来的,一句句啃完后,就长胖了

TA的精华主题

TA的得分主题

发表于 2013-4-3 20:12 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
留个脚印,下次来学

TA的精华主题

TA的得分主题

发表于 2013-4-3 20:25 | 显示全部楼层

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-4-3 20:28 | 显示全部楼层
抱歉,我以为要求简单就没有特别说明,看一下二楼图片右侧即为结果和要求
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-4-27 16:54 , Processed in 0.041893 second(s), 7 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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