ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[Excel 程序开发] [第94期_1]▲VBA、函数大比拼:提取订单号▲[已总结评分]

[复制链接]

TA的精华主题

TA的得分主题

发表于 2013-5-8 20:57 | 显示全部楼层 |阅读模式
本帖最后由 delete_007 于 2013-6-25 10:23 编辑

[题目分类]题目主题
正式竞赛题









答题要求:
以CODE提交答案

提示:


是否参与点评与总结:
本人愿意参与点评(PS:前期评分点评,如遇解题思路超出本人能力范围,提交版主)




补充内容 (2013-5-30 11:16):
后期数据更新有误,函数题应排序

补充内容 (2013-6-21 20:09):
由于VBA题目较简单,1技术分还是很容易拿到的

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?免费注册

x

点评

开始!竞赛时间 2013-5-13至2013-6-20  发表于 2013-5-13 14:11

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-5-8 21:10 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册

  1. Sub xiaofx11()
  2. Dim str As String, arr, brr(), spr, sbr
  3. Dim match, matches
  4. Dim i As Long, j As Long, m As Integer, n As Integer
  5. Dim str9 As String, str10 As String
  6. j = Sheet1.Range("a65536").End(xlUp).Row
  7. arr = WorksheetFunction.Transpose(Sheet1.Range("a1:a" & j))
  8. ReDim brr(1 To j)
  9. For i = 1 To j
  10.     str = arr(i)
  11.     With CreateObject("VBSCRIPT.REGEXP")
  12.         .Global = True
  13.         .Pattern = ""
  14.         .Pattern = "\d{9}([/-]\d{2,9})*"
  15.         Set matches = .Execute(str)
  16.         For Each match In matches
  17.             str9 = Left(match, 7)
  18.             str10 = Right(match, Len(match) - 7)
  19.             spr = Split(str10, "/")
  20.             For m = 0 To UBound(spr)
  21.                 If IsNumeric(spr(m)) Then
  22.                     If Len(brr(i)) = 0 Then
  23.                         If Len(spr(m)) = 9 Then
  24.                             brr(i) = spr(m)
  25.                         Else
  26.                             brr(i) = str9 & spr(m)
  27.                         End If
  28.                     Else
  29.                         If Len(spr(m)) = 9 Then
  30.                             brr(i) = brr(i) & " " & spr(m)
  31.                         Else
  32.                             brr(i) = brr(i) & " " & str9 & spr(m)
  33.                         End If
  34.                     End If
  35.                 Else
  36.                     sbr = Split(spr(m), "-")
  37.                         For n = sbr(0) To sbr(1)
  38.                             If Len(brr(i)) = 0 Then
  39.                                 brr(i) = str9 & n
  40.                             Else
  41.                                 brr(i) = brr(i) & " " & str9 & n
  42.                             End If
  43.                         Next
  44.                 End If
  45.             Next
  46.         Next
  47.     End With
  48. Next
  49. Sheet1.Range("b1").Resize(j, 1) = WorksheetFunction.Transpose(brr)
  50. End Sub

复制代码

补充内容 (2013-6-21 19:57):
此题为群里一工作中实际用到的,当时写的答案,后期没有修改

TA的精华主题

TA的得分主题

发表于 2013-5-13 19:30 | 显示全部楼层
本帖最后由 delete_007 于 2013-6-25 09:32 编辑

函数解:
定义名称:Y
  1. =TRIM(MID(SUBSTITUTE('第二题(函数)'!$A1,"/",REPT(" ",200)),COLUMN('第二题(函数)'!$A:$J)*200-199,200))
复制代码
名称:Z
  1. =LOOKUP(COLUMN('第二题(函数)'!$A:$J),IF(LEN(Y)>8,COLUMN('第二题(函数)'!$A:$J)),LEFT(Y,7))
复制代码
C1单元格公式右拉下拉:
  1. =TEXT(SMALL(--(Z&TEXT((0&MID(Y,8^(LEN(Y)>8),2))+ROW($1:$9)-1,"[=]000;[<="&RIGHT(Y,2)&"]00;000")),COLUMN()-2),"[<1E9];")
复制代码


以A1数据为例:“755725187/89/96-97/755878720-21”
先通过“/”把数据源分隔开得到数组Y={"755725187","89","96-97","755878720-21","","","","","",""}
如果Y的长度小于9,那么表明此订单号为简写,其前7位编号应该与前一个完整订单号一致,于是通过LOOKUP来得到每个数据的前7位订单号数组
Z={"7557251","7557251","7557251","7558787","7558787","7558787","7558787","7558787","7558787","7558787"}
最后单元格的公式用来处理“-”的情况。MID提取“-”前的两个数字,然后加上0到8的数组,再使用TEXT与“-”后的两位数字比较,如果小于等于后两位数字则保持不变,否则使其变成三位数。
与订单号的前7位Z连接,然后升序排序,如果长度大于9则为无效订单号,隐藏即可。


——delete_007


TA的精华主题

TA的得分主题

发表于 2013-5-13 21:00 | 显示全部楼层
本帖最后由 leroy 于 2013-5-13 21:32 编辑

限于个人水平,这里借助VBA中的普通数组和循环来解(没有对计算结果排序,不知道行不行?{:soso_e103:}),

  1. Sub OrderNumber_Collection()
  2.     Dim i&, j&, k&, arr, result
  3.     Dim temp
  4.     With Sheets("第一题(VBA)")
  5.         arr = .Range(.[A1], .[A65536].End(3))
  6.         ReDim result(1 To UBound(arr), 1 To 1)
  7.         For i = 1 To UBound(arr)
  8.             '第一步,解决"-"
  9.             If InStr(arr(i, 1), "-") > 0 Then
  10.                 Do
  11.                     j = InStr(arr(i, 1), "-")
  12.                     temp = ""
  13.                     If Mid(arr(i, 1), j - 2, 2) Like "##" And Mid(arr(i, 1), j + 1, 2) Like "##" Then
  14.                         For k = Mid(arr(i, 1), j - 2, 2) To Mid(arr(i, 1), j + 1, 2)
  15.                             temp = temp & k & "/"
  16.                         Next
  17.                         arr(i, 1) = Replace(Replace(arr(i, 1), Mid(arr(i, 1), j - 2, 5), temp), "//", "/")
  18.                     End If
  19.                 Loop While InStr(arr(i, 1), "-") > 0
  20.             End If
  21.             '第二步,解决"/"
  22.             If InStr(10, arr(i, 1), "/") > 0 Then
  23.                 j = 9
  24.                 Do
  25.                     j = InStr(j + 1, arr(i, 1), "/")
  26.                     If Mid(arr(i, 1), j + 1, 2) Like "##" And Mid(arr(i, 1), j - 9, 9) Like "#########" Then
  27.                         If Mid(arr(i, 1), j + 3, 1) Like "#" = False Or Len(arr(i, 1)) = j + 2 Then
  28.                             arr(i, 1) = Left(arr(i, 1), j) & Mid(arr(i, 1), j - 9, 7) & Mid(arr(i, 1), j + 1, Len(arr(i, 1)))
  29.                             j = j + 7
  30.                         End If
  31.                     End If
  32.                 Loop While InStr(j + 1, arr(i, 1), "/") > 0
  33.             End If
  34.             '第三步,提取连续的9位数字
  35.             For j = 1 To Len(arr(i, 1)) - 8
  36.                 If Mid(arr(i, 1), j, 9) Like "#########" Then
  37.                     If Len(result(i, 1)) = 0 Then
  38.                         result(i, 1) = Mid(arr(i, 1), j, 9)
  39.                     Else
  40.                         result(i, 1) = result(i, 1) & " " & Mid(arr(i, 1), j, 9)
  41.                     End If
  42.                 End If
  43.             Next
  44.         Next
  45.         .[B:B].ClearContents
  46.         .[B1].Resize(UBound(arr)) = result
  47.     End With
  48. End Sub
复制代码

评分

2

查看全部评分

TA的精华主题

TA的得分主题

发表于 2013-5-14 15:22 | 显示全部楼层
本帖最后由 lzyamo3057 于 2013-5-19 10:07 编辑


  1. Sub test()
  2.     Dim RgExp, Arr, k%, brr, crr, drr(1 To 100), Err, frr(), s, i, j, m, y, x, temp
  3.     Set RgExp = CreateObject("vbScript.RegExp")
  4.     Arr = Range("A1", [A65536].End(3))
  5.     ReDim brr(1 To UBound(Arr))
  6.     For k = 1 To UBound(Arr)
  7.         With RgExp
  8.             .Global = True
  9.             .Pattern = "[\u4e00-\u9fa5 A-Za-z]|\(.*?\)"
  10.             brr(k) = .Replace(Arr(k, 1), "")
  11.         End With
  12.     Next
  13.     For i = LBound(brr) To UBound(brr)
  14.         m = 0
  15.         crr = Split(brr(i), "/")
  16.         s = Left(crr(0), 7)
  17.         For j = LBound(crr) To UBound(crr)
  18.             If Len(crr(j)) = 9 Then
  19.                 m = m + 1
  20.                 drr(m) = crr(j)
  21.             ElseIf Len(crr(j)) = 2 Then
  22.                 m = m + 1
  23.                 drr(m) = s & crr(j)
  24.             ElseIf InStr(crr(j), "-") Then
  25.                 Err = Split(crr(j), "-")
  26.                 If Len(Err(0)) >= 9 Then
  27.                     s = Left(Err(0), 7)
  28.                     For x = Right(Err(0), 2) To Err(1)
  29.                         m = m + 1
  30.                         drr(m) = s & x
  31.                     Next
  32.                 Else
  33.                     For x = Err(0) To Err(1)
  34.                         m = m + 1
  35.                         drr(m) = s & x
  36.                     Next
  37.                 End If
  38.             End If
  39.         Next
  40.         For x = 1 To UBound(drr) - 1
  41.             For y = x + 1 To UBound(drr)
  42.               If drr(x) <> "" And drr(y) <> "" Then
  43.                 If drr(x) > drr(y) Then
  44.                     temp = drr(x)
  45.                     drr(x) = drr(y)
  46.                     drr(y) = temp
  47.                 End If
  48.                 End If
  49.             Next y
  50.         Next x
  51.         t = t + 1
  52.         ReDim Preserve frr(1 To t)
  53.         frr(t) = Join(drr, " ")
  54.         Erase drr
  55.     Next
  56.     [b1].Resize(UBound(frr)) = Application.WorksheetFunction.Transpose(frr)
  57. End Sub
复制代码


评分

2

查看全部评分

TA的精华主题

TA的得分主题

发表于 2013-5-14 16:18 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖最后由 smlee 于 2013-5-15 14:52 编辑
  1. Sub auto()    'smlee
  2.     Dim arr, temp
  3.     Dim i As Byte, reStr As String, j As Byte, k As Byte, temp1 As String
  4.     arr = Range("a1:a8")
  5.     For i = 1 To UBound(arr)
  6.         reStr = reStr & arr(i, 1) & Chr(10)
  7.     Next
  8.     With CreateObject("VBScript.RegExp")
  9.         .Global = True
  10.         .Pattern = "\(.+\)"
  11.         reStr = .Replace(reStr, "")
  12.         .Pattern = "\D+[^chr(10)]\s"
  13.         reStr = .Replace(reStr, Chr(10))
  14.     End With
  15.         arr = Split(reStr, Chr(10))
  16.         For i = 1 To UBound(arr) - 1
  17.             temp = Split(arr(i), "/")
  18.             For j = 0 To UBound(temp)
  19.                 If Len(temp(j)) = 2 Then
  20.                     temp(j) = Mid$(temp(j - 1), 1, 7) & temp(j) & ","
  21.                 ElseIf Len(temp(j)) > 9 Then
  22.                     For k = Mid$(temp(j), 8, 2) To Mid$(temp(j), 11, 2)
  23.                         temp1 = temp1 & Mid$(temp(j), 1, 7) & k & ","
  24.                     Next
  25.                     temp(j) = temp1: temp1 = ""
  26.                 ElseIf Len(temp(j)) = 5 Then
  27.                     For k = Mid$(temp(j), 1, 2) To Mid$(temp(j), 4, 2)
  28.                         temp1 = temp1 & Mid$(temp(j - 1), 1, 7) & k & ","
  29.                     Next
  30.                     temp(j) = temp1: temp1 = ""
  31.                 End If
  32.             Next
  33.             arr(i) = Join(temp, ",")
  34.         Next
  35.         For i = 0 To UBound(arr)
  36.             arr(i) = Replace((Replace(arr(i), ",", " ")), "  ", " ")
  37.             If arr(i) <> "" Then arr(i - 1) = arr(i): arr(i) = ""
  38.         Next
  39.     [b1].Resize(UBound(arr), 1) = Application.Transpose(arr)
  40. End Sub
复制代码
错了请给我机会改过啊。。。为了这一点技术分,俺豁出去了
  1. Sub auto()    'smlee
  2.     Dim arr, temp1, temp2 As String
  3.     Dim reStr As String, i As Byte, j As Byte, k As Byte
  4.     arr = Range("a1:a8")
  5.     With CreateObject("VBScript.RegExp")
  6.         For i = 1 To UBound(arr)
  7.             .Pattern = "\D*\(\d.*\)\s|\(\D\d*\)"
  8.             arr(i, 1) = .Replace(arr(i, 1), "")
  9.             temp1 = Split(arr(i, 1), "/")
  10.             For j = 0 To UBound(temp1)
  11.                 Select Case Len(temp1(j))
  12.                 Case 2
  13.                     temp1(j) = Mid$(temp1(j - 1), 1, 7) & temp1(j)
  14.                 Case 5
  15.                     For k = Left$(temp1(j), 2) To Right$(temp1(j), 2)
  16.                         temp2 = temp2 & Mid$(temp1(j - 1), 1, 7) & k & ","
  17.                     Next
  18.                     temp1(j) = temp2: temp2 = ""
  19.                 Case Is > 9
  20.                     For k = Mid(temp1(j), InStr(1, temp1(j), "-") - 2, 2) To Right$(temp1(j), 2)
  21.                         temp2 = temp2 & Mid$(temp1(j), 1, 7) & k & ","
  22.                     Next
  23.                     temp1(j) = temp2: temp2 = ""
  24.                 End Select
  25.             Next
  26.             arr(i, 1) = Replace(Replace(Join(temp1, ","), ",", " "), "  ", " ")
  27.         Next
  28.     End With
  29.     [b1].Resize(UBound(arr), 1) = arr
  30. End Sub
复制代码

代码再优化到30行,哈哈。

评分

2

查看全部评分

TA的精华主题

TA的得分主题

发表于 2013-5-15 15:12 | 显示全部楼层
本帖最后由 sunya_0529 于 2013-5-18 10:00 编辑

先贴一个VBA的,看楼主模拟的结果不像是排过序的,题目说明里也没要求,就先不管了。
  1. Function getCode(str$) As String
  2. Dim regExp As Object, arr1, i%, s$, arr2, j%, strTemp$
  3. Set regExp = CreateObject("VBScript.RegExp")
  4. With regExp
  5.   .Pattern = "\d{9}((/|-)\d+)*"
  6.   If .Test(str) Then
  7.     getCode = .Execute(str)(0)
  8.   Else
  9.     getCode = "#N/A"
  10.   End If
  11. End With
  12. Set regExp = Nothing

  13. arr1 = Split(getCode, "/")
  14. For i = 0 To UBound(arr1)
  15.   If Len(arr1(i)) > 7 Then s = Left(arr1(i), 7)
  16.   If InStr(arr1(i), "-") > 0 Then
  17.     arr2 = Split(arr1(i), "-")
  18.     For j = Val(Right(arr2(0), 2)) To Val(arr2(1))
  19.       strTemp = strTemp & " " & s & j
  20.     Next j
  21.   Else
  22.     strTemp = strTemp & " " & s & Right(arr1(i), 2)
  23.   End If
  24. Next i
  25. getCode = Trim(strTemp)
  26. End Function
复制代码

评分

2

查看全部评分

TA的精华主题

TA的得分主题

发表于 2013-5-16 20:48 | 显示全部楼层
  1. Option Explicit
  2. Sub l()
  3.     Dim R As Object, js As Object
  4.     Dim arr As Variant, tmp As String, ff As String
  5.     Dim brr As Variant, crr As Variant
  6.     Dim i As Integer, j As Integer, k As Integer
  7.     Dim jg(), jgtmp As String
  8.     arr = Sheet1.[a1:a8]
  9.     ReDim jg(1 To UBound(arr), 1 To 1)
  10.     Set R = CreateObject("VBScript.RegExp")
  11.     With R
  12.         .Pattern = "\(.+\)|[A-Za-z\u4e00-\u9fa5 ]"
  13.         .Global = True
  14.         For i = 1 To UBound(arr)
  15.             tmp = .Replace(arr(i, 1), "")
  16.             If Len(tmp) > 9 Then
  17.                 brr = Split(tmp, "/")
  18.                 For j = 0 To UBound(brr)
  19.                     If Len(brr(j)) > 7 Then ff = Left$(brr(j), 7)
  20.                     If InStr(brr(j), "-") > 0 Then
  21.                         crr = Split(brr(j), "-")
  22.                         For k = Val(Right$(crr(0), 2)) To Val(crr(1))
  23.                             jg(i, 1) = jg(i, 1) & " " & ff & k
  24.                         Next
  25.                     Else
  26.                         jg(i, 1) = jg(i, 1) & " " & ff & Right$(brr(j), 2)
  27.                     End If
  28.                 Next
  29.             End If
  30.             If Len(tmp) = 9 Then jg(i, 1) = tmp
  31.             Set js = CreateObject("msscriptcontrol.scriptcontrol")
  32.             js.Language = "javascript"
  33.             jgtmp = Mid$(jg(i, 1), 2)
  34.             js.addcode "function s(x){js=x.split(' ');js.sort(function(a,b){return a-b;});return js;}"
  35.             jg(i, 1) = Replace(js.eval("s('" & jgtmp & "')"), ",", " ")
  36.         Next
  37.     End With
  38.     Set R = Nothing: Set js = Nothing
  39.     Sheet1.[b1].Resize(i - 1).Value = jg
  40. End Sub
复制代码
VBA竞赛题很久没有过了, 参与一下。

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2013-5-28 13:13 | 显示全部楼层
本帖最后由 doryan 于 2013-5-29 10:19 编辑

函数的估计做不来 先上一个VBA的 原理是:正则过滤
点评就算了 函数完全菜鸟级^^
21行 VBA估计我最短了吧{:soso_e121:}
  1. Function Regular(arg As Range) As String
  2.     Dim posStr As String, brr(100), RegX, arr, temp, i%, j%, s%
  3.     Set RegX = CreateObject("VBSCRIPT.REGEXP")
  4.     RegX.Pattern = "\d{9}[\d|\/|\-]*"
  5.     arr = Split(RegX.Execute(arg.Value).Item(0), "/")
  6.     For i = 0 To UBound(arr)
  7.         If IsNumeric(arr(i)) Then
  8.             If Len(arr(i)) = 9 Then posStr = Left(arr(i), 9 - 2)
  9.             brr(s) = posStr & Right(arr(i), 2)
  10.             s = s + 1
  11.         Else
  12.             temp = Split(arr(i), "-")
  13.             If Len(temp(0)) = 9 Then posStr = Left(temp(0), 9 - 2)
  14.             For j = Right(temp(0), 2) To Right(temp(1), 2)
  15.                 brr(s) = posStr & j
  16.                 s = s + 1
  17.             Next
  18.         End If
  19.     Next
  20.     Regular = Trim(Join(brr, " "))
  21. End Function
复制代码

评分

2

查看全部评分

TA的精华主题

TA的得分主题

发表于 2013-5-28 14:44 | 显示全部楼层
本帖最后由 delete_007 于 2013-6-25 09:33 编辑

C1 =IF(LEN(TRIM(MID(SUBSTITUTE(SUBSTITUTE($A1,"-","/"),"/",REPT(" ",99)),99*COLUMN(A:A)-98,99)))>2,TRIM(MID(SUBSTITUTE(SUBSTITUTE($A1,"-","/"),"/",REPT(" ",99)),99*COLUMN(A:A)-98,99)),IF(LEN(TRIM(MID(SUBSTITUTE(SUBSTITUTE($A1,"-","/"),"/",REPT(" ",99)),99*COLUMN(A:A)-98,99))),LEFT(B1,7)&TRIM(MID(SUBSTITUTE(SUBSTITUTE($A1,"-","/"),"/",REPT(" ",99)),99*COLUMN(A:A)-98,99)),""))

共计 374个字符
公式不能得到正确答案。


——delete_007

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?免费注册

x

评分

1

查看全部评分

您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-11-21 20:20 , Processed in 0.057031 second(s), 21 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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