Excel精英培训网

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

[已解决]d.Remove (ar(i, 1)) 出错

[复制链接]
发表于 2015-10-8 07:28 | 显示全部楼层 |阅读模式
本帖最后由 605751967 于 2015-10-8 18:31 编辑

d.Remove (ar(i, 1))   出错。
最佳答案
2015-10-8 11:52
再换一种算法:
使用1个字典、A列B列各一次循环,最后对字典结果再进行一次循环检查以便输出结果:
  1. Sub test2()
  2.     Dim ar, kr, tr, dic, i&, k1&, k2&, k3&, k4&, m&, r&, t$$$$, tms#
  3.     tms = Timer
  4.    
  5.     [d1].CurrentRegion.Offset(1) = ""
  6.    
  7.     m = [a65536].End(3).Row - 1
  8.     ar = [a2].Resize(m)
  9.    
  10.     Set dic = CreateObject("Scripting.Dictionary")
  11.     For i = 1 To m
  12.         t = ar(i, 1): If Len(t) Then dic(t) = 1 'A列有标记=1
  13.     Next
  14.    
  15.     m = [b65536].End(3).Row - 1
  16.     ar = [b2].Resize(m)
  17.     For i = 1 To m
  18.         t = ar(i, 1)
  19.         If Len(t) Then
  20.             If Not dic.Exists(t) Then 'A0B1
  21.                 dic(t) = 2 'A没有B有标记为=2
  22.             Else
  23.                 If dic(t) = 1 Then dic(t) = 3 '标记=1时则为A有 且B有 改标记=3
  24.             End If
  25.         End If
  26.     Next
  27.    
  28.     kr = dic.keys
  29.     tr = dic.items
  30.     ReDim br(1 To dic.Count, 1 To 4)
  31.     For i = 0 To dic.Count - 1
  32.         r = tr(i): t = kr(i)
  33.         If r = 1 Then k1 = k1 + 1: br(k1, 1) = t '标记=1时仅A有B没有
  34.         If r = 2 Then k2 = k2 + 1: br(k2, 2) = t '标记=2时仅B有A没有
  35.         If r = 3 Then k3 = k3 + 1: br(k3, 3) = t '标记=3时A有B也有
  36.         k4 = k4 + 1: br(k4, 4) = t '字典中留下的就是A+B合成(A有 or B有)
  37.     Next
  38.    
  39.     MsgBox Format(Timer - tms, "0.00s")
  40.     [d2].Resize(dic.Count, 4) = br
  41. End Sub
复制代码

二列数.rar

10.8 KB, 下载次数: 11

发表于 2015-10-8 09:41 | 显示全部楼层
思路有漏洞吧。。

判断Dic存在的时候,如果B列有重复的且在A列出现即DIC中存在,第一次存在判断的时候,D REMOVE后,第二次再REMOVE肯定出问题了。

思路的漏洞就是没有规避这种情况:B列有重复,且在A列出现。你自己再想想思路。
回复

使用道具 举报

发表于 2015-10-8 10:16 | 显示全部楼层
逻辑上就行不通,实践当然通不过
改了下想法:
Dim arr, ar, i&, br(0 To 2)
    t = Timer
    [C2:G65536].ClearContents
    arr = Range("A2:A" & Cells(Rows.Count, 1).End(3).Row)
    ar = Range("B2:B" & Cells(Rows.Count, 2).End(3).Row)
    ReDim crr(1 To UBound(arr) + UBound(ar), 0 To 3)
    Set dic = CreateObject("scripting.dictionary")
    Set d = CreateObject("scripting.dictionary")
    For i = 1 To UBound(ar)
       If Len(ar(i, 1)) Then
        dic(ar(i, 1)) = ""
        d(ar(i, 1)) = 1
       End If
    Next
    For i = 1 To UBound(arr)
      If Len(arr(i, 1)) Then
        If d(arr(i, 1)) > 0 Then d(arr(i, 1)) = 2
        dic(arr(i, 1)) = ""
      End If
    Next
    For Each tmp In d.keys
       br(d(tmp)) = br(d(tmp)) + 1
       crr(br(d(tmp)), d(tmp)) = tmp
    Next
    i = 0
    For Each tmp In dic.keys
       i = i + 1
       crr(i, 3) = tmp
    Next
    Range("C2").Resize(i, 4) = crr
    MsgBox Format(Timer - t, "0.00秒")

评分

参与人数 1 +1 收起 理由
605751967 + 1 评分有限

查看全部评分

回复

使用道具 举报

发表于 2015-10-8 10:55 | 显示全部楼层
使用一个字典,A列B列各一次循环完成分类。
结果再加一次字典结果检查循环,总计3次循环过程,完成输出。
  1. Option Base 1
  2. Sub test()
  3.     Dim ar, dic, i&, k1&, k2&, k3&, k4&, m&, t$$, tr, tms#
  4.     tms = Timer
  5.    
  6.     [d1].CurrentRegion.Offset(1) = "" '清空输出区域
  7.    
  8.     m1 = [a65536].End(3).Row - 1 '获取A列最大行数m1
  9.     ar = [a2].Resize(m1) '读取A列数据到数组ar

  10.     m2 = [b65536].End(3).Row - 1 '获取B列最大行数m2
  11.     ReDim br1(m1, 1), br2(m2, 1), br3(m1, 1), br4(m1 + m2, 1)
  12.     '建立存放结果的数组br1、br2、br3、br4 (不超过可能个数)

  13.     Set dic = CreateObject("Scripting.Dictionary") '建立字典dic
  14.     For i = 1 To m1 '遍历A列数据
  15.         t = ar(i, 1): If Len(t) Then If Not dic.Exists(t) Then dic(t) = t: k4 = k4 + 1: br4(k4, 1) = t
  16.         '如不为空则检查是否已经存入字典、并将第1次结果存入br4 即【A+B合成】(A or B)
  17.     Next
  18.    
  19.     ar = [b2].Resize(m2) '读取B列数据到数组ar (数组ar重复使用)
  20.     For i = 1 To m2 '遍历B列数据
  21.         t = ar(i, 1)
  22.         If Len(t) Then '如不为空
  23.             If dic.Exists(t) Then '如字典存在 则A1B1 即AB都有
  24.                 If Len(dic(t)) Then dic(t) = "": k3 = k3 + 1: br3(k3, 1) = t
  25.                 '如字典Item结果不为空则属于第1次出现,标记Item为空 并记入br3【AB都有】
  26.                 '如Item为空 则为标记已重复 不用统计【重要技巧】
  27.             Else '如字典不存在 A0B1 即B有A没有
  28.                 k2 = k2 + 1: br2(k2, 1) = t '记入br2【B有A没有】
  29.                 k4 = k4 + 1: br4(k4, 1) = t '记入br4【A+B合成】(A or B)
  30.                 dic(t) = "" '该值Item标记为空 防止重复统计【重要技巧】
  31.             End If
  32.         End If
  33.     Next
  34.     '以上检查完毕,但A有B没有结果只存在于字典中,还需要检查输出

  35.     tr = dic.items '提取字典中结果(A有B有时为空、B有时为空、仅A有B没有才是结果)
  36.     For i = 0 To UBound(tr) '遍历字典结果
  37.         t = tr(i): If Len(t) Then k1 = k1 + 1: br1(k1, 1) = t
  38.         '如果Item不为空才是仅A有B没有的正确结果 输出到br1
  39.     Next
  40.      
  41.     '以下为输出   
  42.     [d2].Resize(k1) = br1
  43.     [e2].Resize(k2) = br2
  44.     [f2].Resize(k3) = br3
  45.     [g2].Resize(k4) = br4
  46.     MsgBox Format(Timer - tms, "0.00s")
  47. End Sub
复制代码

AB.zip

14.55 KB, 下载次数: 3

回复

使用道具 举报

发表于 2015-10-8 11:52 | 显示全部楼层    本楼为最佳答案   
再换一种算法:
使用1个字典、A列B列各一次循环,最后对字典结果再进行一次循环检查以便输出结果:
  1. Sub test2()
  2.     Dim ar, kr, tr, dic, i&, k1&, k2&, k3&, k4&, m&, r&, t$$$$, tms#
  3.     tms = Timer
  4.    
  5.     [d1].CurrentRegion.Offset(1) = ""
  6.    
  7.     m = [a65536].End(3).Row - 1
  8.     ar = [a2].Resize(m)
  9.    
  10.     Set dic = CreateObject("Scripting.Dictionary")
  11.     For i = 1 To m
  12.         t = ar(i, 1): If Len(t) Then dic(t) = 1 'A列有标记=1
  13.     Next
  14.    
  15.     m = [b65536].End(3).Row - 1
  16.     ar = [b2].Resize(m)
  17.     For i = 1 To m
  18.         t = ar(i, 1)
  19.         If Len(t) Then
  20.             If Not dic.Exists(t) Then 'A0B1
  21.                 dic(t) = 2 'A没有B有标记为=2
  22.             Else
  23.                 If dic(t) = 1 Then dic(t) = 3 '标记=1时则为A有 且B有 改标记=3
  24.             End If
  25.         End If
  26.     Next
  27.    
  28.     kr = dic.keys
  29.     tr = dic.items
  30.     ReDim br(1 To dic.Count, 1 To 4)
  31.     For i = 0 To dic.Count - 1
  32.         r = tr(i): t = kr(i)
  33.         If r = 1 Then k1 = k1 + 1: br(k1, 1) = t '标记=1时仅A有B没有
  34.         If r = 2 Then k2 = k2 + 1: br(k2, 2) = t '标记=2时仅B有A没有
  35.         If r = 3 Then k3 = k3 + 1: br(k3, 3) = t '标记=3时A有B也有
  36.         k4 = k4 + 1: br(k4, 4) = t '字典中留下的就是A+B合成(A有 or B有)
  37.     Next
  38.    
  39.     MsgBox Format(Timer - tms, "0.00s")
  40.     [d2].Resize(dic.Count, 4) = br
  41. End Sub
复制代码
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-25 14:46 , Processed in 0.443022 second(s), 13 queries , Gzip On, Yac On.

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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