ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[求助] [求助] VBA怎样根据总表中数据按类别筛选数据到相应表中?

[复制链接]

TA的精华主题

TA的得分主题

发表于 2024-3-27 12:23 | 显示全部楼层 |阅读模式
本帖最后由 my3022 于 2024-3-27 12:25 编辑

image.jpg image.png
由于工作需要统计九类特殊群体学生,并要求分类打印装档,如果手动筛选粘贴到相应的表中太费时费力,而且如果总表中有数据变化(如有增加或减少,或学生信息发生变化),相应表又要重新复制过去,太麻烦不方便,所以请各位大佬帮搞下自动把各种类型的学生提取到相应表中。
也就是说,我只需要把总表的数据录入好,后面的9张分表就会自动提取生成该类型的学生信息,以后有变化也只需要更新总表,9张分表中涉及的数据也会同步更新。

image.png


附件名册.rar

26.16 KB, 下载次数: 17

TA的精华主题

TA的得分主题

发表于 2024-3-27 13:35 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
大哥,你模拟数据的时候,至少身份证不要同一个号码吧

TA的精华主题

TA的得分主题

发表于 2024-3-27 13:46 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
image.jpg

TA的精华主题

TA的得分主题

发表于 2024-3-27 13:48 | 显示全部楼层
直接新建表格,后期有其他类型也会自动增加的,试一下

附件名册.rar

39.29 KB, 下载次数: 21

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2024-3-27 14:35 | 显示全部楼层
总表拆分

附件供参考。。。

附件名册2.7z

37.76 KB, 下载次数: 22

TA的精华主题

TA的得分主题

发表于 2024-3-27 14:35 | 显示全部楼层
参与一下。。。

  1. Sub ykcbf()  '//2024.3.27
  2.     Dim arr, brr, d
  3.     Set d = CreateObject("scripting.dictionary")
  4.     Application.ScreenUpdating = False
  5.     Application.DisplayAlerts = False
  6.     Dim tm: tm = Timer
  7.     Set ws = ThisWorkbook
  8.     Set sh = ws.Sheets("总表")
  9.     arr = sh.UsedRange
  10.     For Each sht In Sheets
  11.         If sht.Name <> sh.Name Then
  12.             sht.Delete
  13.         End If
  14.     Next
  15.     For i = 4 To UBound(arr)
  16.         s = Trim(arr(i, 8))
  17.         If Not d.Exists(s) Then Set d(s) = CreateObject("scripting.dictionary")
  18.         d(s)(i) = i
  19.     Next i
  20.     On Error Resume Next
  21.     For Each k In d.keys
  22.         sh.Copy after:=Sheets(Sheets.Count)
  23.         Set sht = Sheets(Sheets.Count)
  24.         m = 0
  25.         ReDim brr(1 To d(k).Count, 1 To UBound(arr, 2))
  26.         With sht
  27.             .Name = k
  28.             .UsedRange.Offset(3 + d(k).Count).Clear
  29.             .DrawingObjects.Delete
  30.             For Each kk In d(k).keys
  31.                 m = m + 1
  32.                 brr(m, 1) = m
  33.                 For j = 2 To UBound(arr, 2)
  34.                     brr(m, j) = arr(kk, j)
  35.                 Next
  36.             Next
  37.             .Columns(4).NumberFormatLocal = "@"
  38.             .[a4].Resize(m, UBound(arr, 2)) = brr
  39.         End With
  40.     Next k
  41.     sh.Activate
  42.     Set d = Nothing
  43.     Application.DisplayAlerts = True
  44.     Application.ScreenUpdating = True
  45.     MsgBox "共用时:" & Format(Timer - tm) & "秒!"
  46. End Sub

复制代码


评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2024-3-27 14:40 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
  1. Sub test0()
  2.   
  3.   Dim ar, dict As Object, wks As Worksheet, ran As Range
  4.   Dim rowsHeight() As Double, strKey As String
  5.   Dim i As Long, j As Long, titleRow As Long, splitCol As Long
  6.   
  7.   titleRow = 3   '标题所在 行
  8.   splitCol = 8   '拆分依据 列
  9.   
  10.   DoApp False
  11.   
  12.   For Each wks In Worksheets
  13.     If wks.Name <> "总表" Then wks.Delete
  14.   Next
  15.   
  16.   ReDim rowsHeight(1 To titleRow + 1)
  17.   Set dict = CreateObject("Scripting.Dictionary")
  18.   
  19.   With Worksheets(1)
  20.     For j = 1 To UBound(rowsHeight)
  21.       rowsHeight(j) = .Rows(j).RowHeight
  22.     Next
  23.     With .Range("A1").CurrentRegion
  24.       ar = .Value
  25.       Set ran = .Resize(titleRow)
  26.     End With
  27.     For i = titleRow + 1 To UBound(ar) '- 1
  28.       strKey = Trim(ar(i, splitCol))
  29.       If Len(strKey) Then
  30.         If Not dict.Exists(strKey) Then Set dict(strKey) = ran
  31.         Set dict(strKey) = Union(dict(strKey), .Range("A" & i).Resize(, UBound(ar, 2)))
  32.       End If
  33.     Next
  34.   End With
  35.   
  36.   For j = 0 To dict.Count - 1
  37.     With Worksheets.Add(After:=Worksheets(Worksheets.Count))
  38.       ran.Copy
  39.       .Range("A1").PasteSpecial xlPasteColumnWidths
  40.       dict.Items()(j).Copy .Range("A1")
  41.       For i = 1 To UBound(rowsHeight) - 1
  42.         .Rows(i).RowHeight = rowsHeight(i)
  43.       Next
  44.       .Rows(i & ":" & .Cells.Find("*", , xlValues, , xlByRows, xlPrevious).Row).RowHeight = rowsHeight(i)
  45.       .Name = dict.Keys()(j)
  46.       .DrawingObjects.Delete
  47.     End With
  48.   Next
  49.   
  50.   Worksheets(1).Activate
  51.   
  52.   Set ran = Nothing
  53.   Set dict = Nothing
  54.   DoApp
  55.   Beep
  56. End Sub

  57. Function DoApp(Optional b As Boolean = True)
  58.   With Application
  59.     .ScreenUpdating = b
  60.     .DisplayAlerts = b
  61.     .Calculation = -b * 30 - 4135
  62.   End With
  63. End Function
复制代码

TA的精华主题

TA的得分主题

发表于 2024-3-27 14:49 | 显示全部楼层
  1. ' 以下4法,均是平时练习,未设格式

  2. Sub test1() '数组 快排
  3.   Dim data, wks As Worksheet
  4.   Dim i As Long, j As Long, rowSize As Long
  5.   Dim titleRow As Long, splitCol As Long

  6.   titleRow = 3  '标题所在 行
  7.   splitCol = 8  '拆分依据 列

  8.   DoApp False

  9.   Worksheets("总表").Activate
  10.   For Each wks In Worksheets
  11.     If wks.Name <> ActiveSheet.Name Then wks.Delete
  12.   Next
  13.   With Range("A1").CurrentRegion
  14.     data = .Resize(.Rows.Count + 1).Value
  15.   End With
  16.   QuickSort data, titleRow + 1, UBound(data) - 1, 1, UBound(data, 2), splitCol
  17.   rowSize = titleRow
  18.   For i = titleRow + 1 To UBound(data) - 1
  19.     rowSize = rowSize + 1
  20.     For j = 1 To UBound(data, 2)
  21.       data(rowSize, j) = data(i, j)
  22.     Next
  23.     If data(i, splitCol) <> data(i + 1, splitCol) Then
  24.       Worksheets.Add(After:=Worksheets(Worksheets.Count)).Name = data(i, splitCol)
  25.       With ActiveSheet
  26.         .Range("A1").Resize(rowSize, j - 1) = data
  27.         .Columns.AutoFit
  28.       End With
  29.       rowSize = titleRow
  30.     End If
  31.   Next
  32.   Worksheets(1).Activate
  33.   DoApp
  34.   Beep
  35. End Sub

  36. Sub test2() 'ADO + SQL
  37.   Dim Conn As Object, rs As Object
  38.   Dim strConn As String, SQL As String, str_ As String
  39.   Dim wks As Worksheet, data, titleRow As Long, splitCol As Long

  40.   titleRow = 3  '标题所在 行
  41.   splitCol = 8  '拆分依据 列

  42.   DoApp False

  43.   Worksheets("总表").Activate
  44.   For Each wks In Worksheets
  45.     If wks.Name <> ActiveSheet.Name Then wks.Delete
  46.   Next
  47.   Set Conn = CreateObject("ADODB.Connection")
  48.   Set rs = CreateObject("ADODB.Recordset")
  49.   If Application.Version < 12 Then
  50.     strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties=Excel 8.0;Data Source="
  51.   Else
  52.     strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0;Data Source="
  53.   End If
  54.   Conn.Open strConn & ThisWorkbook.FullName
  55.   With Range("A1").CurrentRegion
  56.     data = .Resize(titleRow).Value
  57.     str_ = .Parent.Name & "$" & Intersect(.Offset(0), .Offset(titleRow - 1)).Address(0, 0)
  58.   End With

  59.   SQL = "SELECT DISTINCT [" & data(titleRow, splitCol) & "] FROM [" & str_ & "]"
  60.   rs.Open SQL, Conn, 1, 3
  61.   SQL = "SELECT * FROM [" & str_ & "] WHERE TRIM([" & data(titleRow, splitCol) & "])='[str_]'"
  62.   While Not rs.EOF
  63.     str_ = rs.Fields(0).Value
  64.     Worksheets.Add(After:=Worksheets(Worksheets.Count)).Name = str_
  65.     With ActiveSheet
  66.       .Range("A1").Resize(titleRow, UBound(data, 2)) = data
  67.       .Range("A" & titleRow + 1).CopyFromRecordset Conn.Execute(Replace(SQL, "[str_]", str_))
  68.       .Columns.AutoFit
  69.     End With
  70.     rs.MoveNext
  71.   Wend
  72.   rs.Close
  73.   Set rs = Nothing
  74.   Conn.Close
  75.   Set Conn = Nothing
  76.   Worksheets(1).Activate
  77.   DoApp
  78.   Beep
  79. End Sub

  80. Sub test3() ' 字典
  81.   Dim dict As Object, wks As Worksheet
  82.   Dim data, i As Long, j As Long, strKey As String
  83.   Dim titleRow As Long, splitCol As Long

  84.   titleRow = 3  '标题所在 行
  85.   splitCol = 8  '拆分依据 列

  86.   DoApp False

  87.   Worksheets("总表").Activate
  88.   For Each wks In Worksheets
  89.     If wks.Name <> ActiveSheet.Name Then wks.Delete
  90.   Next
  91.   Set dict = CreateObject("Scripting.DictionAry")
  92.   With Range("A1").CurrentRegion
  93.     j = .Columns.Count
  94.     data = .Columns(splitCol)
  95.   End With
  96.   For i = titleRow + 1 To UBound(data)
  97.     strKey = data(i, 1)
  98.     If Len(strKey) Then
  99.       If Not dict.Exists(strKey) Then Set dict(strKey) = Range("A1").Resize(titleRow, j)
  100.       Set dict(strKey) = Union(dict(strKey), Range("A" & i).Resize(1, j))
  101.     End If
  102.   Next
  103.   For i = 0 To dict.Count - 1
  104.     With Worksheets.Add(After:=Worksheets(Worksheets.Count))
  105.       .Name = dict.Keys()(i)
  106.       dict.Items()(i).Copy .Range("A1")
  107.       .Columns.AutoFit
  108.     End With
  109.   Next
  110.   Worksheets(1).Activate
  111.   Set dict = Nothing
  112.   DoApp
  113.   Beep
  114. End Sub

  115. Sub test4() '字典定位 数组嵌套  测试过30W+数据,速度最快
  116.   Dim data, temp() As String, results(), dict As Object, wks As Worksheet
  117.   Dim i As Long, j As Long, posRow As Long
  118.   Dim titleRow As Long, splitCol As Long

  119.   titleRow = 3  '标题所在 行
  120.   splitCol = 8  '拆分依据 列

  121.   DoApp False

  122.   Worksheets("总表").Activate
  123.   For Each wks In Worksheets
  124.     If wks.Name <> ActiveSheet.Name Then wks.Delete
  125.   Next

  126.   Set dict = CreateObject("Scripting.Dictionary")
  127.   data = Range("A1").CurrentRegion
  128.   ReDim temp(1 To UBound(data), 1 To UBound(data, 2))
  129.   For j = 1 To UBound(data, 2)
  130.     For i = 1 To titleRow
  131.       temp(i, j) = data(i, j)
  132.     Next
  133.   Next
  134.   For i = titleRow + 1 To UBound(data)
  135.     If Not dict.Exists(data(i, splitCol)) Then dict(data(i, splitCol)) = dict.Count + 1
  136.   Next
  137.   ReDim results(1 To dict.Count, 1 To 2)
  138.   For i = 1 To dict.Count
  139.     results(i, 1) = titleRow
  140.     results(i, 2) = temp
  141.   Next
  142.   For i = titleRow + 1 To UBound(data)
  143.     posRow = dict(data(i, splitCol))
  144.     results(posRow, 1) = results(posRow, 1) + 1
  145.     For j = 1 To UBound(data, 2)
  146.       results(posRow, 2)(results(posRow, 1), j) = data(i, j)
  147.     Next
  148.   Next
  149.   For i = 1 To dict.Count
  150.     With Worksheets.Add(After:=Worksheets(Worksheets.Count))
  151.       .Name = results(i, 2)(titleRow + 1, splitCol)
  152.       .Range("A1").Resize(results(i, 1), UBound(data, 2)) = results(i, 2)
  153.       .Columns.AutoFit
  154.     End With
  155.   Next
  156.   Worksheets(1).Activate
  157.   Set dict = Nothing
  158.   DoApp
  159.   Beep
  160. End Sub

  161. Function QuickSort(ar, u As Long, d As Long, l As Long, r As Long, pos As Long)
  162.   Dim t As Long, b As Long, x As Long, y As Long, pivot As String, swap
  163.   t = u
  164.   b = d
  165.   pivot = ar((u + d) \ 2, pos)
  166.   While t <= b
  167.     Do
  168.       If StrComp(ar(t, pos), pivot, vbTextCompare) = -1 Then t = t + 1 Else Exit Do
  169.     Loop While t < d
  170.     Do
  171.       If StrComp(pivot, ar(b, pos), vbTextCompare) = -1 Then b = b - 1 Else Exit Do
  172.     Loop While b > u
  173.     If t < b Then
  174.       For x = l To r
  175.         swap = ar(t, x): ar(t, x) = ar(b, x): ar(b, x) = swap
  176.       Next
  177.       t = t + 1: b = b - 1
  178.     Else
  179.       If t = b Then t = t + 1: b = b - 1
  180.     End If
  181.   Wend
  182.   If u < b Then QuickSort ar, u, b, l, r, pos
  183.   If t < d Then QuickSort ar, t, d, l, r, pos
  184. End Function

  185. Function DoApp(Optional b As Boolean = True)
  186.   With Application
  187.     .ScreenUpdating = b
  188.     .DisplayAlerts = b
  189.     .Calculation = -b * 30 - 4135
  190.   End With
  191. End Function
复制代码

评分

2

查看全部评分

TA的精华主题

TA的得分主题

发表于 2024-3-27 14:52 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
灌一灌.zip (49.24 KB, 下载次数: 20)

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-3-27 14:54 | 显示全部楼层
本帖最后由 my3022 于 2024-3-27 15:02 编辑

谢谢三位大佬了,是不是总表有数据变化都只能重新拆分,不能同步更新
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-11-17 21:41 , Processed in 0.049758 second(s), 16 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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