Vba 如何在Excel工作簿的所有工作表中搜索字符串?

Vba 如何在Excel工作簿的所有工作表中搜索字符串?,vba,excel,Vba,Excel,我编写了一个宏,它将在Excel工作簿的所有工作表中搜索字符串。此宏将激活第一个工作表以及工作表中包含搜索字符串的单元格。如果未找到,则会显示一条消息 我想扩展此功能,以涵盖包含此字符串的所有工作表,而不仅仅是第一个工作表。所以我修改了宏,但它没有按预期工作。我已经给出了下面的代码,并在显示错误的地方进行了注释 Dim sheetCount As Integer Dim datatoFind Sub Button1_Click() Find_Data End Sub Private Su

我编写了一个宏,它将在Excel工作簿的所有工作表中搜索字符串。此宏将激活第一个工作表以及工作表中包含搜索字符串的单元格。如果未找到,则会显示一条消息

我想扩展此功能,以涵盖包含此字符串的所有工作表,而不仅仅是第一个工作表。所以我修改了宏,但它没有按预期工作。我已经给出了下面的代码,并在显示错误的地方进行了注释

Dim sheetCount As Integer
Dim datatoFind

Sub Button1_Click()

Find_Data

End Sub

Private Sub Find_Data()
    Dim counter As Integer
    Dim currentSheet As Integer
    Dim notFound As Boolean
    Dim yesNo As String

    notFound = True

    On Error Resume Next
    currentSheet = ActiveSheet.Index
    datatoFind = InputBox("Please enter the value to search for")
    If datatoFind = "" Then Exit Sub
    sheetCount = ActiveWorkbook.Sheets.Count
    If IsError(CDbl(datatoFind)) = False Then datatoFind = CDbl(datatoFind)
    For counter = 1 To sheetCount
        Sheets(counter).Activate

        Cells.Find(What:=datatoFind, After:=ActiveCell, LookIn:=xlFormulas, LookAt _
        :=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
        False, SearchFormat:=False).Activate

        If InStr(1, ActiveCell.Value, datatoFind) Then
            If HasMoreValues(counter + 1) Then 'Not completing the method and directly entering
                yesNo = MsgBox("Do you want to continue search?", vbYesNo)
                If yesNo = vbNo Then
                    notFound = False
                    Exit For
                End If
            End If
            Sheets(counter).Activate
        End If
    Next counter
    If notFound Then
        MsgBox ("Value not found")
        Sheets(currentSheet).Activate
    End If
End Sub

Private Function HasMoreValues(ByVal sheetCounter As Integer) As Boolean
    HasMoreValues = False
    Dim str As String

    For counter = sheetCounter To sheetCount
        Sheets(counter).Activate

        str = Cells.Find(What:=datatoFind, After:=ActiveCell, LookIn:=xlFormulas, LookAt _
        :=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
        False, SearchFormat:=False).Value 'Not going further than this i.e. following code is not executed

        If InStr(1, str, datatoFind) Then
            HasMoreValues = True
            Exit For
        End If
    Next counter
End Function

问题是
Cells.Find
返回一个范围。当您在函数中使用它时,您可以这样使用它:

Cells.Find(...).Value
Cells.Find(...).text
但返回的范围未正确转换为.value。您可以使用
.text
而不是
.value
来解决此问题,如下所示:

Cells.Find(...).Value
Cells.Find(...).text
或者完全:

str = Cells.Find(What:=datatoFind, After:=ActiveCell, LookIn:=xlFormulas, LookAt _
  :=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
  False, SearchFormat:=False).text

为了完全正确,您可能应该
将查找结果设置为一个范围变量,然后通过该变量访问它,以防find搜索不返回任何结果。但是,根据文档
Cells.Find
始终返回一个单元格的范围,因此您可能会没事。

我能够解决我的问题,并为可能需要它的人发布了代码

Dim sheetCount As Integer
Dim datatoFind

Sub Button1_Click()

    Find_Data

End Sub

Private Sub Find_Data()
    Dim counter As Integer
    Dim currentSheet As Integer
    Dim notFound As Boolean
    Dim yesNo As String

    notFound = True

    On Error Resume Next
    currentSheet = ActiveSheet.Index
    datatoFind = StrConv(InputBox("Please enter the value to search for"), vbLowerCase)
    If datatoFind = "" Then Exit Sub
    sheetCount = ActiveWorkbook.Sheets.Count
    If IsError(CDbl(datatoFind)) = False Then datatoFind = CDbl(datatoFind)
    For counter = 1 To sheetCount
        Sheets(counter).Activate

        Cells.Find(What:=datatoFind, After:=ActiveCell, LookIn:=xlFormulas, LookAt _
        :=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
        False, SearchFormat:=False).Activate

        If InStr(1, StrConv(ActiveCell.Value, vbLowerCase), datatoFind) Then
            notFound = False
            If HasMoreValues(counter) Then
                yesNo = MsgBox("Do you want to continue search?", vbYesNo)
                If yesNo = vbNo Then
                    Sheets(counter).Activate
                    Exit For
                End If
            Else
                Sheets(counter).Activate
                Exit For
            End If
            Sheets(counter).Activate
        End If
    Next counter
    If notFound Then
        MsgBox ("Value not found")
        Sheets(currentSheet).Activate
    End If
End Sub

Private Function HasMoreValues(ByVal sheetCounter As Integer) As Boolean
    HasMoreValues = False
    Dim str As String
    Dim lastRow As Long
    Dim lastCol As Long
    Dim rRng  As Excel.Range

    For counter = sheetCounter + 1 To sheetCount
        Sheets(counter).Activate

        lastRow = ActiveCell.SpecialCells(xlLastCell).Row
        lastCol = ActiveCell.SpecialCells(xlLastCell).Column

        For vRow = 1 To lastRow
            For vCol = 1 To lastCol
                str = Sheets(counter).Cells(vRow, vCol).Text
                If InStr(1, StrConv(str, vbLowerCase), datatoFind) Then
                    HasMoreValues = True
                    Exit For
                End If
            Next vCol

            If HasMoreValues Then
                Exit For
            End If
        Next vRow

        If HasMoreValues Then
            Sheets(sheetCounter).Activate
            Exit For
        End If
    Next counter
End Function

这里有一个更简单的解决方案,对大多数人来说可能很好:

这是一个宏,它将以正确的设置快速打开“查找”对话框,以便在工作簿中的所有工作表中进行搜索

Sub FindInWorkbook()
    SendKeys "^f%t%hw{ENTER}%n"
End Sub

很抱歉,但是您的代码有一些不一致之处,我无法准确地理解您试图做什么。请描述当一张工作表中有多个匹配项时,您的程序应该做什么。顺便说一句,看看FindNext方法我的代码做了以下工作:1。在所有工作表中搜索第一个可用匹配项。如果找到,则会激活工作表和搜索字符串所在的单元格。2.搜索下一个可用的匹配项。如果存在,则会显示一个带有是/否的msgbox,表示有更多搜索可用。你想继续吗?如果是,则显示下一个可用匹配项,如第1点所述,然后搜索下一个可用匹配项,依此类推,直到所有匹配项都已用尽。3.如果没有可用的匹配项,则进程停止。还有,这个FindNext是谁的方法,“单元格”还是“表格”?对不起,我遗漏了什么。。。Control+F有什么问题?(查找?)默认设置仅搜索活动工作表,但在“查找”对话框上的选项中,可以将搜索范围更改为工作簿。我确信有一种方法可以通过编程方式调用内置函数,从而节省不必要的工作。@Richard,我创建的方法仅使用此功能,即录制宏并根据需要进行更改。但我想扩展此功能以继续搜索,这会产生如上所述的问题。我尝试了您使用.Text而不是.Value的方法,但可能会出现重复的问题。无论如何,我刚刚找到了一个解决问题的方法,我现在将在这里发布同样的方法。谢谢您的帮助。@samar您是否尝试过在查找结果中设置
Range
变量,然后使用Range.Cells(1,1).Text获取文本?请描述您所做的更改,以便将来的读者能够从中受益。代码墙很少有用。