ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[求助] 遍历工作表查找指定数据。

[复制链接]

TA的精华主题

TA的得分主题

发表于 2019-3-23 11:29 | 显示全部楼层 |阅读模式
遍历指定工作薄,并按照要求提前满足条件的数据那一行,大神帮忙看看

遍历工作表查找对应数据.rar

16.99 KB, 下载次数: 230

TA的精华主题

TA的得分主题

发表于 2019-3-23 11:39 | 显示全部楼层
有点意思,我用SQL语句试一试、

TA的精华主题

TA的得分主题

发表于 2019-3-23 11:48 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
用for each 遍历worksheets,用FIND找姓名字段.find可以获取到地址

TA的精华主题

TA的得分主题

发表于 2019-3-23 12:05 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖最后由 lsc900707 于 2019-3-23 13:00 编辑

就是一个跨簿查询的问题。

Sub gj23w98()
    Dim crr(1 To 9999, 1 To 4)
    brr = [a2].CurrentRegion
    Set wb = GetObject(ThisWorkbook.Path & "\" & "原始数据.xlsx")
    With wb
        For Each sht In .Sheets
            arr = sht.[a1].CurrentRegion
            For i = 2 To UBound(arr)
                For k = 2 To UBound(brr)
                    If arr(i, 1) = brr(k, 1) Then
                        m = m + 1
                        For j = 1 To 4
                            crr(m, j) = arr(i, j)
                        Next
                    End If
                Next
            Next
        Next
    End With
    If m Then
        Range("c3:f" & Rows.Count).ClearContents
        [c3].Resize(m, 4) = crr
    End If
End Sub





TA的精华主题

TA的得分主题

发表于 2019-3-23 12:48 | 显示全部楼层
  1. 代码如下,可惜完成了一般。SQL语句模式和数组也不兼容。in运算符里面的字符串是要单引号的,而正常数据的字符串是双引号的。SQL能否结合数组来运行,看来我还需要考虑清楚。
复制代码
  1. Sub FuYun_SQL()
  2.     Dim cnn As Object, rst As Object
  3.     Dim Mypath As String, Str_cnn As String, path1$
  4.     Dim Sql As String, Sql1 As String
  5.     Dim Sht As Worksheet, Sht_name As String
  6.     Dim i As Long
  7.     Dim wb As Workbook
  8.     Dim arr, nRow%, insStr$
  9.     With Worksheets("sheet1")
  10.         nRow = .Cells(.Rows.Count, 1).End(3).Row
  11.         arr = .Range("a3:a" & nRow)
  12.     End With
  13.    

  14.    
  15.     Set cnn = CreateObject("adodb.connection")
  16.     path1 = "\原始数据.xlsx"
  17.     Mypath = ThisWorkbook.Path & path1
  18.     If Application.Version < 12 Then
  19.         Str_cnn = "Provider=Microsoft.jet.OLEDB.4.0;Extended Properties=Excel 8.0;Data Source=" & Mypath
  20.     Else
  21.         Str_cnn = "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0;Data Source=" & Mypath
  22.     End If
  23.     cnn.Open Str_cnn

  24.      Set wb = GetObject(Mypath)

  25.     Sql1 = "SELECT 姓名,数学成绩,语文成绩,英语成绩"
  26.     For Each Sht In wb.Worksheets
  27.         Sht_name = Sht.Name
  28.         If Sht_name <> ActiveSheet.Name Then
  29.          
  30.             Sql = Sql & Sql1 & " FROM [" & Sht_name & "$] where 姓名 in('小红','小白') UNION ALL "
  31.             
  32.         End If
  33.     Next
  34.     Sql = Left(Sql, Len(Sql) - 11) & "ORDER BY 姓名"
  35.     Set rst = cnn.Execute(Sql)
  36.     Cells.ClearContents

  37.     Range("a2").CopyFromRecordset rst
  38.     cnn.Close
  39.     Set cnn = Nothing
  40. End Sub
复制代码

TA的精华主题

TA的得分主题

发表于 2019-3-23 12:53 | 显示全部楼层
放在汇总工作簿的sheet1中
如果要放到公共模块中,需要将下面的Me改为thisworkbook.sheets("sheet1")
  1. Sub main()
  2.     Dim LastRow As Long, i As Long
  3.     Dim strCrit As String, strSQL As String
  4.     Dim fName As String
  5.     Dim conn As Object, Rst As Object
  6.    
  7.     LastRow = Cells(Rows.Count, 1).End(xlUp).Row
  8.     If LastRow = 2 Then '没有输入查询条件
  9.         If (MsgBox("查询条件为空,是否输出所有数据?", vbYesNo)) = vbYes Then '输出所有数据
  10.             strCrit = ";"
  11.         Else    '取消查询
  12.             Exit Sub
  13.         End If
  14.     ElseIf LastRow = 3 Then     '只有一个条件
  15.         strCrit = " WHERE 姓名='" & Range("A3").Value & "';"
  16.     Else                    '多个查询条件
  17.         For i = 3 To LastRow
  18.             If strCrit = "" Then
  19.                 strCrit = " WHERE 姓名 in ('" & Cells(i, 1).Value & "'"
  20.             Else
  21.                 strCrit = strCrit & ",'" & Cells(i, 1).Value & "'"
  22.             End If
  23.         Next i
  24.         strCrit = strCrit & ")"
  25.     End If
  26.     '删除原有查询结果
  27.     LastRow = Cells(Rows.Count, 3).End(xlUp).Row
  28.     If LastRow > 2 Then
  29.         Range("C3:F" & LastRow).ClearContents
  30.     End If
  31.    
  32.     fName = ThisWorkbook.Path & "\原始数据.xlsx"
  33.     Set conn = CreateObject("ADODB.Connection")
  34.     Set Rst = CreateObject("ADODB.Recordset")
  35.     conn.Open "provider=microsoft.ace.oledb.12.0;extended properties=excel 12.0;data source=" & fName
  36.     Set Rst = conn.openschema(20)

  37.     Do While Not Rst.EOF
  38.         If Rst!TABLE_TYPE = "TABLE" Then
  39.             strSQL = "SELECT * FROM [" & Rst!TABLE_NAME & "]" & strCrit
  40.             LastRow = Me.Cells(Me.Rows.Count, 3).End(xlUp).Row
  41.             Me.Cells(LastRow + 1, "C").CopyFromRecordset conn.Execute(strSQL)
  42.         End If
  43.         Rst.movenext
  44.     Loop
  45.     Set Rst = Nothing
  46.     conn.Close
  47.     Set conn = Nothing
  48.     MsgBox "完成"
  49. End Sub
复制代码

TA的精华主题

TA的得分主题

发表于 2019-3-23 12:55 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
还有一个问题就是数据源中的工作表名含有".",需要删掉,否则出错

TA的精华主题

TA的得分主题

发表于 2019-3-23 14:46 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
qingc0221 发表于 2019-3-23 12:53
放在汇总工作簿的sheet1中
如果要放到公共模块中,需要将下面的Me改为thisworkbook.sheets("sheet1")

看来,这种还是不适合用SQL语句。不过你处理where的方法,我需要学习。

TA的精华主题

TA的得分主题

 楼主| 发表于 2019-3-23 16:03 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2019-3-24 13:55 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
  1. Sub 查找多个值()  '查找多个值
  2. Dim Path As String
  3. Dim findstr As String
  4. Dim findarr
  5. Range("c3:f2000").ClearContents
  6. Path = ThisWorkbook.Path & IIf(Right(ThisWorkbook.Path, 1) = "", "", "")  '取得路径,为下一步打开工作簿做准备
  7. Application.ScreenUpdating = False
  8. Set wb = Workbooks.Open(Filename:=Path & "原始数据.xlsx")       '打开该路径下的工作簿,方便提取原始数据
  9. Dim sht As Worksheet
  10. Dim rng As Range
  11. Dim rng2 As Range
  12. Dim Fistadd As String
  13. Dim Nofind As String
  14. Dim Numb As Integer
  15. Dim arr()
  16.     Set rng2 = ThisWorkbook.Sheets("sheet1").Range("a3:a" & ThisWorkbook.Sheets("sheet1").Cells(Rows.Count, 1).End(xlUp).Row)     '要查找的值,该值可能存在多个,将每个值存入数组
  17.    
  18.      If rng2.Count = 1 Then                       '当rng2为当个单元格时,复制给arr总是报错,没办法用只能用if区分处理了
  19.         ReDim findarr(1 To 1, 1 To 1)           '当单个单元格时,先用redim重新定义数组维度,然后复制
  20.         findarr(1, 1) = rng2.Value
  21.      Else                                       '让rng2为单元格区域是一次性复制
  22.         findarr = rng2.Value
  23.    
  24.     End If
  25.    
  26.     For j = 1 To UBound(findarr, 1)                            '先从第一要个值开始查找,然后循环遍历后,再查找第二个
  27.     Debug.Print LBound(findarr, 1)
  28.     findstr = findarr(j, 1)
  29.     For Each sht In ActiveWorkbook.Sheets
  30.         Set rng = sht.Range("a1").CurrentRegion.Find(findstr)
  31.         If Not rng Is Nothing Then
  32.             Fistadd = sht.Range("a1").CurrentRegion.Find(findstr).Address
  33.               Do
  34.                 Item = Item + 1
  35.                 ReDim Preserve arr(1 To 4, 1 To Item)
  36.                 arr(1, Item) = rng.Value                 '姓名
  37.                 arr(2, Item) = rng.Offset(0, 1).Value   '数学成绩
  38.                 arr(3, Item) = rng.Offset(0, 2).Value   '语文成绩
  39.                 arr(4, Item) = rng.Offset(0, 3).Value   '英语成绩
  40.                 Set rng = sht.Range("a1").CurrentRegion.FindNext(rng)
  41.                 If rng.Address = Fistadd Then Exit Do
  42.                Loop
  43.         
  44.         Else
  45.             
  46.             Rem 当查找的名称在原始数据表里的所有工作簿中都没查找到,则记入未查找的名称,最后通过msgbox弹出
  47.             Numb = Numb + 1
  48.             If Numb = ActiveWorkbook.Sheets.Count Then      '当Numb等于工作表个数时,则说明所有的工作表都没查到此数
  49.                 Nofind = findstr & "," & Nofind
  50.                 Numb = 0                                       'numb等于工作表个数时,最后要变为0,一遍再次循环使用,如果清零的话Numb会累加,比如实际中有两个没找到的,那么
  51.             End If                                             '前文的Numb就等于两倍的工作表个数了,这样这要有二个以上(包括两个)的名字没找到,这个会使Numb > ActiveWorkbook.Sheets.Count,这样等式就永远不相等了
  52.             Rem ******************************************************************************************
  53.         
  54.         
  55.         End If
  56.     Next
  57. Next

  58. On Error Resume Next                                        '当所有姓名都没查到是,数组为空这时u=ubound(arr,2)会报错,本来想用Len(Join(arr, ",")) = 0 来判断数组是不是为空。
  59. u = UBound(arr, 2)                                          '但是join函数用于一维数组,这条路行不通,查了半天还是得用on error resume next  和if err.number来处理
  60. If Err.Number <> 0 Then
  61.     ActiveWorkbook.Close fasle
  62.     Application.ScreenUpdating = True
  63.     MsgBox "所有姓名查找不到"

  64. Else
  65.     ActiveWorkbook.Close fasle
  66.     Application.ScreenUpdating = True
  67.     ThisWorkbook.Sheets("sheet1").Range("c3").Resize(u, 4) = WorksheetFunction.Transpose(arr)
  68.     If Len(Nofind) > 0 Then MsgBox "下列姓名查询不到:" & Nofind
  69. End If
  70. End Sub
复制代码
vba刚入门,有瑕疵的地方,欢迎大家指正
sshot-1.png

遍历工作表查找对应数据.rar

30.79 KB, 下载次数: 156

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

本版积分规则

关闭

最新热点上一条 /1 下一条

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

GMT+8, 2024-4-26 22:42 , Processed in 0.047090 second(s), 12 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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