Excel精英培训网

 找回密码
 注册
数据透视表40+个常用小技巧,让你一次学会!
查看: 4020|回复: 11

[已解决]解决了老问题,怎么原代码失灵了?

[复制链接]
发表于 2014-3-12 17:00 | 显示全部楼层 |阅读模式
本帖最后由 KDZ 于 2014-3-13 08:33 编辑

      
             寡妇添儿子,在众人的帮忙下,好不容易的得到代码,在解决溢、下标越界等出问题后,怎么代码达不到原来的目了?请各位大 帮一把手,把这个孩子顺利生下来!谢谢!
最佳答案
2014-3-14 09:57
我也搞不懂为什么,只能把一个数组拆分为3个小数组,不然就溢出。另外注意到你QRS列里面有非数字类型,代码中也一并考虑了。
  1. Sub 删除重复行()
  2.     Dim d, DelRng As Range, i&, p$, j%
  3.     Dim arr
  4.     Set d = CreateObject("scripting.dictionary")
  5.     With ActiveSheet
  6.         Set DelRng = .Rows(65536)
  7.         row1 = .Range("E" & .Rows.Count).End(xlUp).Row
  8.         arr = .Range("A5:I" & row1)    '前几列
  9.         brr = .Range("q5:s" & row1)    '17 18 19列
  10.         crr = .Range("v5:ac" & row1)    '22--29列
  11.         For i = 1 To UBound(arr)
  12.             If Len(crr(i, 1)) = 0 And Len(crr(i, 8)) = 0 Then   '在22列、29列都为空的行中筛选
  13.                 p = arr(i, 1) & "," & arr(i, 2) & "," & arr(i, 5) & "," & arr(i, 8)
  14.                 d(p) = d(p) & "," & i   '把1、2、5、9四列相同的行放入字典
  15.             End If
  16.         Next
  17.         dk = d.items
  18.         For k = 0 To UBound(dk)
  19.             xrr = Split(dk(k), ",")
  20.             s1 = 0: s2 = 0   's1判断19列是否有数,s2判断18列是否有数
  21.             k1 = 0: k2 = 0: k3 = 0
  22.             For m = 1 To UBound(xrr)
  23.                 i = Val(xrr(m))
  24.                 s1 = s1 + IIf(IsNumeric(brr(i, 3)), brr(i, 3), 1) '考虑到QRS列有非数字情形
  25.                 s2 = s2 + IIf(IsNumeric(brr(i, 2)), brr(i, 2), 1)
  26.             Next
  27.             For m = 1 To UBound(xrr)
  28.                 i = Val(xrr(m))
  29.                 If s1 > 0 Then
  30.                     If brr(i, 3) = 0 Then
  31.                         Set DelRng = Union(DelRng, .Rows(i + 4))
  32.                     Else
  33.                         k1 = k1 + 1
  34.                         If k1 > 1 Then Set DelRng = Union(DelRng, .Rows(i + 4))
  35.                     End If
  36.                 ElseIf s2 > 0 Then
  37.                     If brr(i, 2) = 0 Then
  38.                         Set DelRng = Union(DelRng, .Rows(i + 4))
  39.                     Else
  40.                         k2 = k2 + 1
  41.                         If k2 > 1 Then Set DelRng = Union(DelRng, .Rows(i + 4))
  42.                     End If
  43.                 Else
  44.                     If brr(i, 1) = 0 Then
  45.                         Set DelRng = Union(DelRng, .Rows(i + 4))
  46.                     Else
  47.                         k3 = k3 + 1
  48.                         If k3 > 1 Then Set DelRng = Union(DelRng, .Rows(i + 4))
  49.                     End If
  50.                 End If
  51.             Next
  52.         Next
  53.         DelRng.Delete
  54.     End With
  55. End Sub
复制代码

样表.zip

350.74 KB, 下载次数: 23

 楼主| 发表于 2014-3-13 08:34 | 显示全部楼层
回复

使用道具 举报

发表于 2014-3-13 10:48 | 显示全部楼层
重新改了下代码。虽然有点啰嗦,但条理比较清晰。
  1. Sub 删除重复行()
  2.     Dim d, DelRng As Range, i&, p$, j%
  3.     Set d = CreateObject("scripting.dictionary")
  4.     With ActiveSheet
  5.         Set DelRng = .Rows(65536)
  6.         row1 = .Range("E" & .Rows.Count).End(xlUp).Row
  7.         arr = .Range("A5:ac" & row1)

  8.         For i = 1 To UBound(arr)
  9.             If Len(arr(i, 22)) = 0 And Len(arr(i, 29)) = 0 Then   '在22列、29列都为空的行中筛选
  10.                 p = arr(i, 1) & "," & arr(i, 2) & "," & arr(i, 5) & "," & arr(i, 8)
  11.                 d(p) = d(p) & "," & i   '把1、2、5、9四列相同的行放入字典
  12.             End If
  13.         Next
  14.         dk = d.items
  15.         For k = 0 To UBound(dk)
  16.             xrr = Split(dk(k), ",")
  17.             s1 = 0: s2 = 0   's1判断19列是否有数,s2判断18列是否有数
  18.             For m = 1 To UBound(xrr)
  19.                 i = Val(xrr(m))
  20.                 s1 = s1 + arr(i, 19): s2 = s2 + arr(i, 18)
  21.             Next
  22.             If s1 > 0 Then
  23.                 For m = 1 To UBound(xrr)
  24.                     i = Val(xrr(m))
  25.                     If arr(i, 19) = 0 Then Set DelRng = Union(DelRng, .Rows(i + 4))
  26.                 Next
  27.             ElseIf s2 > 0 Then
  28.                 For m = 1 To UBound(xrr)
  29.                     i = Val(xrr(m))
  30.                     If arr(i, 18) = 0 Then Set DelRng = Union(DelRng, .Rows(i + 4))
  31.                 Next
  32.             Else
  33.                 For m = 1 To UBound(xrr)
  34.                     i = Val(xrr(m))
  35.                     If arr(i, 17) = 0 Then Set DelRng = Union(DelRng, .Rows(i + 4))
  36.                 Next
  37.             End If
  38.         Next
  39.         DelRng.Delete
  40.     End With
  41. End Sub
复制代码
回复

使用道具 举报

发表于 2014-3-13 10:54 | 显示全部楼层
代码可以简化一点:
  1. Sub 删除重复行()
  2.     Dim d, DelRng As Range, i&, p$, j%
  3.     Set d = CreateObject("scripting.dictionary")
  4.     With ActiveSheet
  5.         Set DelRng = .Rows(65536)
  6.         row1 = .Range("E" & .Rows.Count).End(xlUp).Row
  7.         arr = .Range("A5:ac" & row1)

  8.         For i = 1 To UBound(arr)
  9.             If Len(arr(i, 22)) = 0 And Len(arr(i, 29)) = 0 Then   '在22列、29列都为空的行中筛选
  10.                 p = arr(i, 1) & "," & arr(i, 2) & "," & arr(i, 5) & "," & arr(i, 8)
  11.                 d(p) = d(p) & "," & i   '把1、2、5、9四列相同的行放入字典
  12.             End If
  13.         Next
  14.         dk = d.items
  15.         For k = 0 To UBound(dk)
  16.             xrr = Split(dk(k), ",")
  17.             s1 = 0: s2 = 0   's1判断19列是否有数,s2判断18列是否有数
  18.             For m = 1 To UBound(xrr)
  19.                 i = Val(xrr(m))
  20.                 s1 = s1 + arr(i, 19): s2 = s2 + arr(i, 18)
  21.             Next
  22.             For m = 1 To UBound(xrr)
  23.                 i = Val(xrr(m))
  24.                 If s1 > 0 Then
  25.                     If arr(i, 19) = 0 Then Set DelRng = Union(DelRng, .Rows(i + 4))
  26.                 ElseIf s2 > 0 Then
  27.                     If arr(i, 18) = 0 Then Set DelRng = Union(DelRng, .Rows(i + 4))
  28.                 Else
  29.                     If arr(i, 17) = 0 Then Set DelRng = Union(DelRng, .Rows(i + 4))
  30.                 End If
  31.             Next
  32.         Next
  33.         DelRng.Delete
  34.     End With
  35. End Sub
复制代码
回复

使用道具 举报

发表于 2014-3-13 10:56 | 显示全部楼层
为什么文件这么大?请看附件。

样表.rar

367.77 KB, 下载次数: 4

回复

使用道具 举报

 楼主| 发表于 2014-3-13 13:27 | 显示全部楼层
本帖最后由 KDZ 于 2014-3-13 13:31 编辑
grf1973 发表于 2014-3-13 10:56
为什么文件这么大?请看附件。


只是最高孩次行如果是 2 行以上,只要保留基中唯一行,其它的最高孩次行也全部删除,解决了就完全解决问题了,还请赐教! 谢谢!!

样表.rar

366.3 KB, 下载次数: 5

回复

使用道具 举报

发表于 2014-3-13 13:44 | 显示全部楼层
是22、29列都为空的前提下只保留1行最高孩次吗?比如你附件中的第5行保留的话,第8行是否还要保留?
回复

使用道具 举报

发表于 2014-3-13 13:48 | 显示全部楼层
  1. Sub 删除重复行()
  2.     Dim d, DelRng As Range, i&, p$, j%
  3.     Set d = CreateObject("scripting.dictionary")
  4.     With ActiveSheet
  5.         Set DelRng = .Rows(65536)
  6.         row1 = .Range("E" & .Rows.Count).End(xlUp).Row
  7.         arr = .Range("A5:ac" & row1)

  8.         For i = 1 To UBound(arr)
  9.             If Len(arr(i, 22)) = 0 And Len(arr(i, 29)) = 0 Then   '在22列、29列都为空的行中筛选
  10.                 p = arr(i, 1) & "," & arr(i, 2) & "," & arr(i, 5) & "," & arr(i, 8)
  11.                 d(p) = d(p) & "," & i   '把1、2、5、9四列相同的行放入字典
  12.             End If
  13.         Next
  14.         dk = d.items
  15.         For k = 0 To UBound(dk)
  16.             xrr = Split(dk(k), ",")
  17.             s1 = 0: s2 = 0   's1判断19列是否有数,s2判断18列是否有数
  18.             k1 = 0: k2 = 0: k3 = 0
  19.             For m = 1 To UBound(xrr)
  20.                 i = Val(xrr(m))
  21.                 s1 = s1 + arr(i, 19): s2 = s2 + arr(i, 18)
  22.             Next
  23.             For m = 1 To UBound(xrr)
  24.                 i = Val(xrr(m))
  25.                 If s1 > 0 Then
  26.                     If arr(i, 19) = 0 Then
  27.                         Set DelRng = Union(DelRng, .Rows(i + 4))
  28.                     Else
  29.                         k1 = k1 + 1
  30.                         If k1 > 1 Then Set DelRng = Union(DelRng, .Rows(i + 4))
  31.                     End If
  32.                 ElseIf s2 > 0 Then
  33.                     If arr(i, 18) = 0 Then
  34.                         Set DelRng = Union(DelRng, .Rows(i + 4))
  35.                     Else
  36.                         k2 = k2 + 1
  37.                         If k2 > 1 Then Set DelRng = Union(DelRng, .Rows(i + 4))
  38.                     End If
  39.                 Else
  40.                     If arr(i, 17) = 0 Then
  41.                         Set DelRng = Union(DelRng, .Rows(i + 4))
  42.                     Else
  43.                         k3 = k3 + 1
  44.                         If k3 > 1 Then Set DelRng = Union(DelRng, .Rows(i + 4))
  45.                     End If
  46.                 End If
  47.             Next
  48.         Next
  49.         DelRng.Delete
  50.     End With
  51. End Sub
复制代码
这段代码只是在22、29列都为空的前提下保留1行最高孩次。
回复

使用道具 举报

 楼主| 发表于 2014-3-13 15:44 | 显示全部楼层
grf1973 发表于 2014-3-13 13:48
这段代码只是在22、29列都为空的前提下保留1行最高孩次。


你好,谢谢!答案是对的,不过用到我的表格内,又还原到“溢出”了,怎么办?请指导,谢谢!!

Book2.rar

446.85 KB, 下载次数: 8

回复

使用道具 举报

发表于 2014-3-14 09:57 | 显示全部楼层    本楼为最佳答案   
我也搞不懂为什么,只能把一个数组拆分为3个小数组,不然就溢出。另外注意到你QRS列里面有非数字类型,代码中也一并考虑了。
  1. Sub 删除重复行()
  2.     Dim d, DelRng As Range, i&, p$, j%
  3.     Dim arr
  4.     Set d = CreateObject("scripting.dictionary")
  5.     With ActiveSheet
  6.         Set DelRng = .Rows(65536)
  7.         row1 = .Range("E" & .Rows.Count).End(xlUp).Row
  8.         arr = .Range("A5:I" & row1)    '前几列
  9.         brr = .Range("q5:s" & row1)    '17 18 19列
  10.         crr = .Range("v5:ac" & row1)    '22--29列
  11.         For i = 1 To UBound(arr)
  12.             If Len(crr(i, 1)) = 0 And Len(crr(i, 8)) = 0 Then   '在22列、29列都为空的行中筛选
  13.                 p = arr(i, 1) & "," & arr(i, 2) & "," & arr(i, 5) & "," & arr(i, 8)
  14.                 d(p) = d(p) & "," & i   '把1、2、5、9四列相同的行放入字典
  15.             End If
  16.         Next
  17.         dk = d.items
  18.         For k = 0 To UBound(dk)
  19.             xrr = Split(dk(k), ",")
  20.             s1 = 0: s2 = 0   's1判断19列是否有数,s2判断18列是否有数
  21.             k1 = 0: k2 = 0: k3 = 0
  22.             For m = 1 To UBound(xrr)
  23.                 i = Val(xrr(m))
  24.                 s1 = s1 + IIf(IsNumeric(brr(i, 3)), brr(i, 3), 1) '考虑到QRS列有非数字情形
  25.                 s2 = s2 + IIf(IsNumeric(brr(i, 2)), brr(i, 2), 1)
  26.             Next
  27.             For m = 1 To UBound(xrr)
  28.                 i = Val(xrr(m))
  29.                 If s1 > 0 Then
  30.                     If brr(i, 3) = 0 Then
  31.                         Set DelRng = Union(DelRng, .Rows(i + 4))
  32.                     Else
  33.                         k1 = k1 + 1
  34.                         If k1 > 1 Then Set DelRng = Union(DelRng, .Rows(i + 4))
  35.                     End If
  36.                 ElseIf s2 > 0 Then
  37.                     If brr(i, 2) = 0 Then
  38.                         Set DelRng = Union(DelRng, .Rows(i + 4))
  39.                     Else
  40.                         k2 = k2 + 1
  41.                         If k2 > 1 Then Set DelRng = Union(DelRng, .Rows(i + 4))
  42.                     End If
  43.                 Else
  44.                     If brr(i, 1) = 0 Then
  45.                         Set DelRng = Union(DelRng, .Rows(i + 4))
  46.                     Else
  47.                         k3 = k3 + 1
  48.                         If k3 > 1 Then Set DelRng = Union(DelRng, .Rows(i + 4))
  49.                     End If
  50.                 End If
  51.             Next
  52.         Next
  53.         DelRng.Delete
  54.     End With
  55. End Sub
复制代码
回复

使用道具 举报

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

本版积分规则

小黑屋|手机版|Archiver|Excel精英培训 ( 豫ICP备11015029号 )

GMT+8, 2024-4-26 04:36 , Processed in 0.379979 second(s), 10 queries , Gzip On, Yac On.

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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