2011-01-19 12 views
5

Ho scritto una macro che cercherà una stringa in tutti i fogli di un file excel. Questa macro attiverà il primo foglio e la cella nel foglio che contiene la stringa di ricerca. Se non viene trovato, mostrerà un messaggio. Questa macro funziona bene. Volevo estendere questa funzionalità per coprire tutti i fogli che contengono questa stringa e non la prima. Così ho modificato la macro ma non funziona come previsto. Ho dato il codice qui sotto e ho anche commentato nel punto in cui mostra l'errore.cerca la stringa in tutti i fogli di un file excel utilizzando le macro

 
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

Ci dispiace, ma il vostro codice ha un paio di incongruenze e Non riesco a capire esattamente cosa stai cercando di fare. Descrivi cosa dovrebbe fare il programma quando ci sono più corrispondenze in un foglio. E BTW, dai un'occhiata al metodo FindNext –

+0

Il mio codice effettua le seguenti operazioni: 1. cerca la prima corrispondenza disponibile in tutti i fogli. Se trovato, attiva il foglio e la cella in cui è presente la stringa di ricerca. 2. cerca la prossima corrispondenza disponibile. Se presente, mostra un messaggio msg con sì/no che dice che ci sono più ricerche disponibili. Vuoi continuare? Se sì, la prossima partita disponibile viene mostrata come indicato al punto 1, quindi cerca la prossima partita disponibile e così via fino a quando tutte le partite sono esaurite. 3. Se non è disponibile alcuna corrispondenza, il processo si interrompe. Anche il cui metodo è questo FindNext, "Celle" o "Fogli"? – samar

+0

Mi dispiace, mi manca qualcosa ... cosa c'è di sbagliato in Control + F? (trova?) La ricerca predefinita riguarda solo il foglio attivo, ma nelle Opzioni della finestra di dialogo Trova è possibile modificare l'ambito di ricerca nella cartella di lavoro. Sono sicuro che ci sarebbe un modo per chiamare programmaticamente la funzione integrata e risparmiare lavoro inutile. – RichardW1001

risposta

4

sono stato in grado di risolvere il mio problema e hanno inviato il codice per coloro che ne avessero bisogno

 

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 

saluti,

Samar

-1

Il problema è che Cells.Find restituisce un intervallo. Quando lo si utilizza nella funzione HasMoreValues, si utilizza in questo modo:

Cells.Find(...).Value 

Ma la gamma restituita non si converte in un .value correttamente. È possibile risolvere questo problema utilizzando .text invece di .value, in questo modo:

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 

Per essere completamente corretta, probabilmente si dovrebbe set il risultato del trovare per una variabile Range, e poi accedervi tramite questo, nel caso in cui la ricerca Trova non restituisca nulla. Tuttavia, secondo la documentazione Cells.Find restituisce sempre un intervallo di una cella, quindi potrebbe essere okay.

+0

ho provato il tuo modo di usare .Text invece di .Value ma sta dando lo stesso problema. Comunque ho appena trovato una soluzione al problema e posterò lo stesso qui ora. Grazie per l'aiuto. – samar

+1

@samar Hai provato a impostare una variabile 'Range' sul risultato di Trova e quindi a usare Range.Cells (1,1) .Text per ottenere il testo? – Steven

Problemi correlati