VBAExcel中的复杂搜索和返回函数
我是VBA新手,正在努力寻找解决方案,但在这里找不到答案 我有一个每天都在增长的大型数据库。数据库由两张表组成。表1用于捕获A列到BF列的数据和跨度。表2仅仅是一个收集点,其中充满了从表1收集数据的公式。我没有创建这个工作簿/数据库,我认为它设计得不是很好,但我必须使用它;而改变它并不是一个真正的选择 我需要做的是: 我需要创建第三张工作表(已创建工作表),该工作表将生成以下复杂搜索 我需要1个单元格作为输入名称的入口点。我需要在数据库中搜索AO到AX列中该名称的每个实例,从第一个条目(第17行)到最后一个条目(记住每天有20到40个新条目,因此它必须能够增长)。这是最简单的部分 我需要从我的搜索中收到4件东西VBAExcel中的复杂搜索和返回函数,excel,vba,Excel,Vba,我是VBA新手,正在努力寻找解决方案,但在这里找不到答案 我有一个每天都在增长的大型数据库。数据库由两张表组成。表1用于捕获A列到BF列的数据和跨度。表2仅仅是一个收集点,其中充满了从表1收集数据的公式。我没有创建这个工作簿/数据库,我认为它设计得不是很好,但我必须使用它;而改变它并不是一个真正的选择 我需要做的是: 我需要创建第三张工作表(已创建工作表),该工作表将生成以下复杂搜索 我需要1个单元格作为输入名称的入口点。我需要在数据库中搜索AO到AX列中该名称的每个实例,从第一个条目(第17行
我可以用countifs做这个
现在,大老板当然希望在A、B和C列中找到这些名字出现的任何行的信息。由于“Charlie”可能出现在8列中的任何一列和当前超过2000行的任何一行中,并且可能出现多次,因此VBA显然是我的最佳解决方案,但作为VBA新手,我正在努力找到代码和变量的正确组合 开始:这里是一个通用的findall函数,您可以使用它查找搜索范围内的所有单元格:
Function FindAll(What, _
Optional SearchWhat As Variant, _
Optional LookIn, _
Optional LookAt, _
Optional SearchOrder, _
Optional SearchDirection As XlSearchDirection = xlNext, _
Optional MatchCase As Boolean = False, _
Optional MatchByte, _
Optional SearchFormat) As Range
'LookIn can be xlValues or xlFormulas, _
LookAt can be xlWhole or xlPart, _
SearchOrder can be xlByRows or xlByColumns, _
SearchDirection can be xlNext, xlPrevious, _
MatchCase, MatchByte, and SearchFormat can be True or False. _
Before using SearchFormat = True, specify the appropriate settings for the Application.FindFormat _
object; e.g. Application.FindFormat.NumberFormat = "General;-General;""-"""
Dim SrcRange As Range
If IsMissing(SearchWhat) Then
Set SrcRange = ActiveSheet.UsedRange
ElseIf TypeOf SearchWhat Is Range Then
Set SrcRange = IIf(SearchWhat.Cells.Count = 1, SearchWhat.Parent.UsedRange, SearchWhat)
ElseIf TypeOf SearchWhat Is Worksheet Then
Set SrcRange = SearchWhat.UsedRange
Else: SrcRange = ActiveSheet.UsedRange
End If
If SrcRange Is Nothing Then Exit Function
'get the first matching cell in the range first
With SrcRange.Areas(SrcRange.Areas.Count)
Dim FirstCell As Range: Set FirstCell = .Cells(.Cells.Count)
End With
Dim CurrRange As Range: Set CurrRange = SrcRange.Find(What:=What, After:=FirstCell, LookIn:=LookIn, LookAt:=LookAt, _
SearchDirection:=SearchDirection, MatchCase:=MatchCase, MatchByte:=MatchByte, SearchFormat:=SearchFormat)
If Not CurrRange Is Nothing Then
Set FindAll = CurrRange
Do
Set CurrRange = SrcRange.Find(What:=What, After:=CurrRange, LookIn:=LookIn, LookAt:=LookAt, _
SearchDirection:=SearchDirection, MatchCase:=MatchCase, MatchByte:=MatchByte, SearchFormat:=SearchFormat)
If CurrRange Is Nothing Then Exit Do
If Application.Intersect(FindAll, CurrRange) Is Nothing Then
Set FindAll = Application.Union(FindAll, CurrRange)
Else: Exit Do
End If
Loop
End If
End Function
找到范围后,您可以循环遍历范围中的每一行(例如Rng.行中的每一rw),并将A、B和C列中的数据提取到目标工作表
******编辑******
所以我想我会把代码放在一起,因为提取这些数据有点困难。我认为以下几点应该对你有用
目前,在第3页的“A1”中输入搜索词,它将使用同一页第2行之后的数据填充B:D列
Sub ExtractData()
Dim wsSrc As Worksheet: Set wsSrc = Worksheets("Sheet1")
Dim wsDest As Worksheet: Set wsDest = Worksheets("Sheet3")
Dim LastRow As Long, RowCounter As Long
Dim SearchRange As Range, FoundRange As Range, rw As Range
Dim Val As String: Val = wsDest.Range("A1")
With wsSrc
LastRow = .UsedRange.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
Set SearchRange = .Range("AO17", .Cells(LastRow, "AX")) 'AO-AX
Set FoundRange = FindAll(Val, SearchRange)
End With
'Clear Destination Sheet (except header row)
With wsDest
On Error Resume Next
Application.Intersect(wsDest.UsedRange, wsDest.UsedRange.Offset(1, 0)).ClearContents
On Error GoTo 0
End With
' Copy Data
RowCounter = 2
Set FoundRange = Union(FoundRange, FoundRange.EntireRow.Rows) 'Expand Range to entire rows of Range
For Each rw In FoundRange.Rows
wsDest.Cells(RowCounter, 2) = wsSrc.Cells(rw.Row, 1)
wsDest.Cells(RowCounter, 3) = wsSrc.Cells(rw.Row, 2)
wsDest.Cells(RowCounter, 4) = wsSrc.Cells(rw.Row, 3)
RowCounter = RowCounter + 1
Next rw
End Sub
Function FindAll(What, _
Optional SearchWhat As Variant, _
Optional LookIn, _
Optional LookAt, _
Optional SearchOrder, _
Optional SearchDirection As XlSearchDirection = xlNext, _
Optional MatchCase As Boolean = False, _
Optional MatchByte, _
Optional SearchFormat) As Range
'LookIn can be xlValues or xlFormulas, _
LookAt can be xlWhole or xlPart, _
SearchOrder can be xlByRows or xlByColumns, _
SearchDirection can be xlNext, xlPrevious, _
MatchCase, MatchByte, and SearchFormat can be True or False. _
Before using SearchFormat = True, specify the appropriate settings for the Application.FindFormat _
object; e.g. Application.FindFormat.NumberFormat = "General;-General;""-"""
Dim SrcRange As Range
If IsMissing(SearchWhat) Then
Set SrcRange = ActiveSheet.UsedRange
ElseIf TypeOf SearchWhat Is Range Then
Set SrcRange = IIf(SearchWhat.Cells.Count = 1, SearchWhat.Parent.UsedRange, SearchWhat)
ElseIf TypeOf SearchWhat Is Worksheet Then
Set SrcRange = SearchWhat.UsedRange
Else: SrcRange = ActiveSheet.UsedRange
End If
If SrcRange Is Nothing Then Exit Function
'get the first matching cell in the range first
With SrcRange.Areas(SrcRange.Areas.Count)
Dim FirstCell As Range: Set FirstCell = .Cells(.Cells.Count)
End With
Dim CurrRange As Range: Set CurrRange = SrcRange.Find(What:=What, After:=FirstCell, LookIn:=LookIn, LookAt:=LookAt, _
SearchDirection:=SearchDirection, MatchCase:=MatchCase, MatchByte:=MatchByte, SearchFormat:=SearchFormat)
If Not CurrRange Is Nothing Then
Set FindAll = CurrRange
Do
Set CurrRange = SrcRange.Find(What:=What, After:=CurrRange, LookIn:=LookIn, LookAt:=LookAt, _
SearchDirection:=SearchDirection, MatchCase:=MatchCase, MatchByte:=MatchByte, SearchFormat:=SearchFormat)
If CurrRange Is Nothing Then Exit Do
If Application.Intersect(FindAll, CurrRange) Is Nothing Then
Set FindAll = Application.Union(FindAll, CurrRange)
Else: Exit Do
End If
Loop
End If
End Function
开始:这里是一个通用的findall函数,可用于查找搜索范围内的所有单元格:
Function FindAll(What, _
Optional SearchWhat As Variant, _
Optional LookIn, _
Optional LookAt, _
Optional SearchOrder, _
Optional SearchDirection As XlSearchDirection = xlNext, _
Optional MatchCase As Boolean = False, _
Optional MatchByte, _
Optional SearchFormat) As Range
'LookIn can be xlValues or xlFormulas, _
LookAt can be xlWhole or xlPart, _
SearchOrder can be xlByRows or xlByColumns, _
SearchDirection can be xlNext, xlPrevious, _
MatchCase, MatchByte, and SearchFormat can be True or False. _
Before using SearchFormat = True, specify the appropriate settings for the Application.FindFormat _
object; e.g. Application.FindFormat.NumberFormat = "General;-General;""-"""
Dim SrcRange As Range
If IsMissing(SearchWhat) Then
Set SrcRange = ActiveSheet.UsedRange
ElseIf TypeOf SearchWhat Is Range Then
Set SrcRange = IIf(SearchWhat.Cells.Count = 1, SearchWhat.Parent.UsedRange, SearchWhat)
ElseIf TypeOf SearchWhat Is Worksheet Then
Set SrcRange = SearchWhat.UsedRange
Else: SrcRange = ActiveSheet.UsedRange
End If
If SrcRange Is Nothing Then Exit Function
'get the first matching cell in the range first
With SrcRange.Areas(SrcRange.Areas.Count)
Dim FirstCell As Range: Set FirstCell = .Cells(.Cells.Count)
End With
Dim CurrRange As Range: Set CurrRange = SrcRange.Find(What:=What, After:=FirstCell, LookIn:=LookIn, LookAt:=LookAt, _
SearchDirection:=SearchDirection, MatchCase:=MatchCase, MatchByte:=MatchByte, SearchFormat:=SearchFormat)
If Not CurrRange Is Nothing Then
Set FindAll = CurrRange
Do
Set CurrRange = SrcRange.Find(What:=What, After:=CurrRange, LookIn:=LookIn, LookAt:=LookAt, _
SearchDirection:=SearchDirection, MatchCase:=MatchCase, MatchByte:=MatchByte, SearchFormat:=SearchFormat)
If CurrRange Is Nothing Then Exit Do
If Application.Intersect(FindAll, CurrRange) Is Nothing Then
Set FindAll = Application.Union(FindAll, CurrRange)
Else: Exit Do
End If
Loop
End If
End Function
找到范围后,您可以循环遍历范围中的每一行(例如Rng.行中的每一rw),并将A、B和C列中的数据提取到目标工作表
******编辑******
所以我想我会把代码放在一起,因为提取这些数据有点困难。我认为以下几点应该对你有用
目前,在第3页的“A1”中输入搜索词,它将使用同一页第2行之后的数据填充B:D列
Sub ExtractData()
Dim wsSrc As Worksheet: Set wsSrc = Worksheets("Sheet1")
Dim wsDest As Worksheet: Set wsDest = Worksheets("Sheet3")
Dim LastRow As Long, RowCounter As Long
Dim SearchRange As Range, FoundRange As Range, rw As Range
Dim Val As String: Val = wsDest.Range("A1")
With wsSrc
LastRow = .UsedRange.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
Set SearchRange = .Range("AO17", .Cells(LastRow, "AX")) 'AO-AX
Set FoundRange = FindAll(Val, SearchRange)
End With
'Clear Destination Sheet (except header row)
With wsDest
On Error Resume Next
Application.Intersect(wsDest.UsedRange, wsDest.UsedRange.Offset(1, 0)).ClearContents
On Error GoTo 0
End With
' Copy Data
RowCounter = 2
Set FoundRange = Union(FoundRange, FoundRange.EntireRow.Rows) 'Expand Range to entire rows of Range
For Each rw In FoundRange.Rows
wsDest.Cells(RowCounter, 2) = wsSrc.Cells(rw.Row, 1)
wsDest.Cells(RowCounter, 3) = wsSrc.Cells(rw.Row, 2)
wsDest.Cells(RowCounter, 4) = wsSrc.Cells(rw.Row, 3)
RowCounter = RowCounter + 1
Next rw
End Sub
Function FindAll(What, _
Optional SearchWhat As Variant, _
Optional LookIn, _
Optional LookAt, _
Optional SearchOrder, _
Optional SearchDirection As XlSearchDirection = xlNext, _
Optional MatchCase As Boolean = False, _
Optional MatchByte, _
Optional SearchFormat) As Range
'LookIn can be xlValues or xlFormulas, _
LookAt can be xlWhole or xlPart, _
SearchOrder can be xlByRows or xlByColumns, _
SearchDirection can be xlNext, xlPrevious, _
MatchCase, MatchByte, and SearchFormat can be True or False. _
Before using SearchFormat = True, specify the appropriate settings for the Application.FindFormat _
object; e.g. Application.FindFormat.NumberFormat = "General;-General;""-"""
Dim SrcRange As Range
If IsMissing(SearchWhat) Then
Set SrcRange = ActiveSheet.UsedRange
ElseIf TypeOf SearchWhat Is Range Then
Set SrcRange = IIf(SearchWhat.Cells.Count = 1, SearchWhat.Parent.UsedRange, SearchWhat)
ElseIf TypeOf SearchWhat Is Worksheet Then
Set SrcRange = SearchWhat.UsedRange
Else: SrcRange = ActiveSheet.UsedRange
End If
If SrcRange Is Nothing Then Exit Function
'get the first matching cell in the range first
With SrcRange.Areas(SrcRange.Areas.Count)
Dim FirstCell As Range: Set FirstCell = .Cells(.Cells.Count)
End With
Dim CurrRange As Range: Set CurrRange = SrcRange.Find(What:=What, After:=FirstCell, LookIn:=LookIn, LookAt:=LookAt, _
SearchDirection:=SearchDirection, MatchCase:=MatchCase, MatchByte:=MatchByte, SearchFormat:=SearchFormat)
If Not CurrRange Is Nothing Then
Set FindAll = CurrRange
Do
Set CurrRange = SrcRange.Find(What:=What, After:=CurrRange, LookIn:=LookIn, LookAt:=LookAt, _
SearchDirection:=SearchDirection, MatchCase:=MatchCase, MatchByte:=MatchByte, SearchFormat:=SearchFormat)
If CurrRange Is Nothing Then Exit Do
If Application.Intersect(FindAll, CurrRange) Is Nothing Then
Set FindAll = Application.Union(FindAll, CurrRange)
Else: Exit Do
End If
Loop
End If
End Function
欢迎来到StackOverflow。请注意,这不是免费的代码编写服务。然而,我们渴望帮助其他程序员(和有抱负的人)编写他们自己的代码。请阅读上的帮助主题。您可能还想在这样做的同时获得一枚徽章。之后,请使用您迄今为止编写的VBA代码更新您的问题,以便完成您希望完成的任务。我们会在这里等你。准备好帮助您完成代码了吗。@拉尔夫。谢谢你的评论。我认为我在我的问题上做得相当好。我实际上没有任何关于这个问题的代码,因为我昨天刚开始学习VBA,我迷路了。我已经学会了如何选择单元格和更改工作表等基本知识,但这仍然是我无法理解的。我会继续努力,希望能写一些代码来做点什么,但我知道你们不是来为大家写代码的。如果我的问题表明这是我的目标,我深表歉意。欢迎来到StackOverflow。请注意,这不是免费的代码编写服务。然而,我们渴望帮助其他程序员(和有抱负的人)编写他们自己的代码。请阅读上的帮助主题。您可能还想在这样做的同时获得一枚徽章。之后,请使用您迄今为止编写的VBA代码更新您的问题,以便完成您希望完成的任务。我们会在这里等你。准备好帮助您完成代码了吗。@拉尔夫。谢谢你的评论。我认为我在我的问题上做得相当好。我实际上没有任何关于这个问题的代码,因为我昨天刚开始学习VBA,我迷路了。我已经学会了如何选择单元格和更改工作表等基本知识,但这仍然是我无法理解的。我会继续努力,希望能写一些代码来做点什么,但我知道你们不是来为大家写代码的。我的ap