ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[求助] 请问如何实现不重复抽取?

[复制链接]

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-6-8 09:22 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助

嗯嗯,完美解决问题!~谢谢谢谢!

TA的精华主题

TA的得分主题

发表于 2018-6-8 09:26 | 显示全部楼层
太强大了,好好学习

TA的精华主题

TA的得分主题

发表于 2018-6-8 09:27 | 显示全部楼层
  1. Sub test()
  2.   Dim r%, i%
  3.   Dim arr, brr, crr()
  4.   Dim d As Object
  5.   Set d = CreateObject("scripting.dictionary")
  6.   With Worksheets("sheet1")
  7.     r = .Cells(.Rows.Count, 1).End(xlUp).Row
  8.     arr = .Range("a2:d" & r)
  9.   End With
  10.   For i = 1 To UBound(arr)
  11.     If Not d.exists(arr(i, 1)) Then
  12.       m = 1
  13.       ReDim brr(1 To UBound(arr, 2), 1 To m)
  14.     Else
  15.       brr = d(arr(i, 1))
  16.       m = UBound(brr, 2) + 1
  17.       ReDim Preserve brr(1 To UBound(arr, 2), 1 To m)
  18.     End If
  19.     For j = 1 To UBound(arr, 2)
  20.       brr(j, m) = arr(i, j)
  21.     Next
  22.     d(arr(i, 1)) = brr
  23.   Next
  24.   ReDim drr(1 To d.Count * 2, 1 To 4)
  25.   m = 0
  26.   For Each aa In d.keys
  27.     arr = d(aa)
  28.     ReDim brr(1 To UBound(arr, 2), 1 To UBound(arr))
  29.     For i = 1 To UBound(arr)
  30.       For j = 1 To UBound(arr, 2)
  31.         brr(j, i) = arr(i, j)
  32.       Next
  33.     Next
  34.     ReDim crr(1 To UBound(brr))
  35.     For i = 1 To UBound(brr)
  36.       crr(i) = i
  37.     Next
  38.     For i = 1 To Application.Min(UBound(crr), 2)
  39.       n = Int(Rnd() * (UBound(crr) - i)) + i + 1
  40.       temp = crr(i)
  41.       crr(i) = crr(n)
  42.       crr(n) = temp
  43.       m = m + 1
  44.       For j = 1 To UBound(brr, 2)
  45.         drr(m, j) = brr(crr(i), j)
  46.       Next
  47.     Next
  48.   Next
  49.   With Worksheets("sheet2")
  50.     .Range("a2").Resize(m, UBound(drr, 2)) = drr
  51.   End With
  52.   
  53. End Sub
复制代码

TA的精华主题

TA的得分主题

发表于 2018-6-8 09:28 | 显示全部楼层
凑个热闹。

工单质量检查.rar

27.43 KB, 下载次数: 8

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-6-8 11:50 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2018-6-8 12:07 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
采用不重复的随机函数

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-6-24 19:01 | 显示全部楼层

您好,这个代码非常好用,但我在使用的过程中还有发现了一个问题:每次随机抽取出来的值,工单号,姓名,领导是对应的,但工单号所对应的工单群号不对,我自己尝试了去设置断点找出原因,可是找不出来,您能再指导一下吗?~~

TA的精华主题

TA的得分主题

发表于 2018-6-24 21:11 | 显示全部楼层
harrisondan2000 发表于 2018-6-24 19:01
您好,这个代码非常好用,但我在使用的过程中还有发现了一个问题:每次随机抽取出来的值,工单号,姓名, ...

'看了一下相同姓名的所在"工单所在群"可以不同,很难理解,原来代码没有考虑这种可能

'一般来说相同姓名"对应领导"、"工单所在群"应该一样的,唯一可以不同的是"工单",但是事实并不是这样

'换种方法给你重写了一遍,自己测试一下

Option Explicit

Sub test()
  Dim arr, t, i, j, k, kk, n, m
  arr = Range("a2:d" & Cells(Rows.Count, "a").End(xlUp).Row + 1)
  ReDim brr(1 To Rows.Count, 1 To UBound(arr, 2))
  t = arr: Call msort(arr, t, 1, UBound(arr, 1) - 1, 1, UBound(arr, 2), 1)
  For i = 1 To UBound(arr, 1) - 1
    For j = i To UBound(arr, 1) - 1
      If arr(j, 1) <> arr(j + 1, 1) Then
        If j - i + 1 <= 2 Then '同名<=2人直接获取
          For k = i To j
            n = n + 1
            For kk = 1 To UBound(arr, 2): brr(n, kk) = arr(k, kk): Next
          Next
        Else
          Randomize
          For k = i To i + 1 '同名>2人随机取同名中的2人
            n = n + 1: m = Int(Rnd * (j - k + 1)) + k
            For kk = 1 To UBound(arr, 2)
              t = arr(k, kk): arr(k, kk) = arr(m, kk): arr(m, kk) = t
            Next
            For kk = 1 To UBound(arr, 2): brr(n, kk) = arr(k, kk): Next
          Next
        End If
        i = j: Exit For
      End If
  Next j, i
  With [f2]
    .Resize(Rows.Count - 1, UBound(brr, 2)).ClearContents
    .Resize(n, UBound(brr, 2)) = brr
  End With
End Sub

Function msort(arr, temp, first, last, left, right, key)
  Dim i, j, k, kk, mid
  If first <> last Then
    mid = Int((first + last) / 2)
    msort arr, temp, first, mid, left, right, key
    msort arr, temp, mid + 1, last, left, right, key
    i = first: j = mid + 1: k = first
    While i <= mid And j <= last
      If arr(i, key) <= arr(j, key) Then
        For kk = left To right: temp(k, kk) = arr(i, kk): Next
        k = k + 1: i = i + 1
      Else
        For kk = left To right: temp(k, kk) = arr(j, kk): Next
        k = k + 1: j = j + 1
      End If
    Wend
    While i <= mid
      For kk = left To right: temp(k, kk) = arr(i, kk): Next
      k = k + 1: i = i + 1
    Wend
    While j <= last
      For kk = left To right: temp(k, kk) = arr(j, kk): Next
      k = k + 1: j = j + 1
    Wend
    For i = first To last
      For j = left To right
        arr(i, j) = temp(i, j)
    Next j, i
  End If
End Function

TA的精华主题

TA的得分主题

发表于 2018-6-24 21:22 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
harrisondan2000 发表于 2018-6-24 19:01
您好,这个代码非常好用,但我在使用的过程中还有发现了一个问题:每次随机抽取出来的值,工单号,姓名, ...

Option Explicit

Sub jimin()
  Dim dic(2), i, t, arr, m, n, s, key, kk
  For i = 0 To UBound(dic)
    Set dic(i) = CreateObject("scripting.dictionary")
  Next
  arr = [a1].CurrentRegion
  For i = 2 To UBound(arr, 1)
    If dic(0).exists(arr(i, 1)) Then
      t = dic(0)(arr(i, 1))
      ReDim Preserve t(UBound(t) + 1)
      t(UBound(t)) = arr(i, 3)
      dic(0)(arr(i, 1)) = t
      dic(2)(arr(i, 3)) = arr(i, 4)
    Else
      dic(0)(arr(i, 1)) = Array(arr(i, 3))
      dic(1)(arr(i, 1)) = arr(i, 2)
      dic(2)(arr(i, 3)) = arr(i, 4)
    End If
  Next
  ReDim brr(1 To dic(0).Count * 2, 1 To 4) As String
  Randomize
  For Each key In dic(0).keys
    t = dic(0)(key)
    For i = 0 To UBound(t)
      m = Int(Rnd * (UBound(t) + 1))
      s = t(i): t(i) = t(m): t(m) = s
    Next
    s = dic(1)(key)
    n = n + 1
    brr(n, 1) = key: brr(n, 3) = t(0)
    brr(n, 2) = s: brr(n, 4) = dic(2)(t(0))
    If UBound(t) > 0 Then
      n = n + 1
      brr(n, 1) = key: brr(n, 3) = t(1)
      brr(n, 2) = s: brr(n, 4) = dic(2)(t(1))
    End If
  Next
  With [f2]
    .Resize(Rows.Count - 1, UBound(brr, 2)).ClearContents
    .Resize(Rows.Count - 1, UBound(brr, 2)).NumberFormatLocal = "@"
    .Resize(UBound(brr, 1), UBound(brr, 2)) = brr
  End With
End Sub

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-6-24 22:56 来自手机 | 显示全部楼层
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2025-1-16 09:08 , Processed in 0.025067 second(s), 8 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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