2011-01-19 7 views
5

He escrito una macro que buscará una cadena en todas las hojas de un archivo de Excel. Esta macro activará la primera hoja y la celda de la hoja que contiene la cadena de búsqueda. Si no se encuentra, entonces mostrará un mensaje. Esta macro funciona bien. Quería extender esta funcionalidad para cubrir todas las hojas que contienen esta cadena y no la primera. Entonces modifiqué la macro pero no está funcionando como esperaba. He proporcionado el código a continuación y también he comentado en el lugar donde está mostrando el error.búsqueda de cadenas en todas las hojas de un archivo de Excel usando macros

 
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 


+0

Lo sentimos, pero su código tiene algunas inconsistencias y No puedo entender exactamente lo que estás tratando de hacer. Por favor, describa qué debe hacer su programa cuando hay múltiples coincidencias en una Hoja. Y por cierto, eche un vistazo al método FindNext –

+0

Mi código hace lo siguiente: 1. busca la primera coincidencia disponible en todas las hojas. Si se encuentra, activa la hoja y la celda en la que está presente la cadena de búsqueda. 2. busca la siguiente coincidencia disponible. Si está presente, entonces muestra un msgbox con sí/no que dice que hay más búsquedas disponibles. ¿Quieres continuar? En caso afirmativo, la siguiente coincidencia disponible se muestra como se menciona en el punto 1 y luego busca la próxima coincidencia disponible, y así sucesivamente hasta que se agoten todas las coincidencias. 3. Si no hay coincidencias disponibles, el proceso se detiene. ¿También de quién es este método FindNext, "Cells" o "Sheets"? – samar

+0

Lo siento, me estoy perdiendo algo ... ¿qué pasa con Control + F? (¿encontrar?) El valor predeterminado busca solo la hoja activa, pero en Opciones en el diálogo Buscar puede cambiar el ámbito de búsqueda por el libro. Estoy seguro de que habría una forma de llamar programáticamente la función incorporada y ahorrarse trabajo innecesario. – RichardW1001

Respuesta

4

pude resolver mi problema y han publicado el código para los que lo requieran

 

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 

Saludos,

Samar

-1

El problema es que Cells.Find devuelve un rango. Cuando se utiliza en su función HasMoreValues, se utiliza de esta manera:

Cells.Find(...).Value 

Pero la gama de regresar no convierte a un .value correctamente. Puedes solucionar este problema mediante el uso de .text en lugar de .value, así:

Cells.Find(...).text 

o completamente:

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

Para ser totalmente correcta, probablemente debería set el resultado del hallazgo de una variable de rango, y luego acceda a eso, en caso de que la Búsqueda de búsqueda no devuelva nada. Sin embargo, de acuerdo con la documentación Cells.Find siempre devuelve un rango de una celda, por lo que puede estar bien.

+0

intenté su manera de usar .Text en lugar de .Value pero está dando el mismo problema. De todos modos, acabo de encontrar una solución al problema y publicaré el mismo aquí ahora. Gracias por tu ayuda. – samar

+1

@samar ¿Ha intentado establecer una variable 'Range' en el resultado de Find, y luego usando Range.Cells (1,1) .Text para obtener el texto? – Steven

Cuestiones relacionadas