funzione vlookup



  • funzione vlookup
    di ambrovba data: 21/10/2017 18:01:57

    Ciao a tutti,

    volevo creare una macro che elimina in un file tutte le righe che contengono lo stesso dato contenuto in file diverso. Sostanzialmente devo fare un cerca verticale.
    Inizialmente l'avevo impostato con due cicli for ma si bloccava per la mole dei dati penso, poi ho scoperto la funzione vlookup ma non riesco ad ottenere il risultato che vorrei perché alcune righe vengono eliminate altre no

    - il ciclo for mi fa muore nelle righe del file A (parto dAll'ultima per evitare che il ciclo salti le righe quando una viene cancellata)
    - vlookup controlla se il valore è nel file B
    - se non c'è interviene AVANTI che fa continuare il for
    - se c'è la riga viene eliminata
    dov'è l'errore?
    Il codice è il seguente
     
    Sub cv()
    On Error GoTo AVANTI
    Dim i As Integer
    dim nc as string
    
    For i = 1389 To 1 step -1
    nc = Application.WorksheetFunction.VLookup(Cells(i, 6),Workbooks("FileB").Worksheets("report").Range(Cells(2, 2), Cells(5987, 2)), 1, False)
    Cells(i, 6).EntireRow.Delete
    Next
    
    AVANTI:
    i = i - 1
    Resume Next
    
    End Sub



  • di alfrimpa data: 21/10/2017 19:08:18

    Ciao ambrovba

    Onestamente non mi è molto chiaro il tuo codice.

    Puoi allegare un file di esempio con i dati (nos sensibili) spiegando quello che vuoi fare perché non vedo molto l'utilizzo del vlookup

    Alfredo





  • di ambrovba data: 21/10/2017 19:31:08

    Ciao alfrimpa,

    Ora non riesco ad allegare i file perché sono fuori.

    Comunque ho due file: file A e file B.

    Io voglio una macro che elimini in file A tutte le righe che contengono nella colonna 6 lo stesso valore che nel file B è contenuto nella colonna 2.

    Nel mio immaginario il vlookup lo uso per trovare nel file B il valore del file A, quando lo trova allora cancello la riga nel file A (cells.entirerow.delete) se non lo trova entra in gioco AVANTI.

    È più chiaro o ti servono i file?






  • di Zer0Kelvin data: 21/10/2017 20:50:17

    Ciao.
    Potresti usare qualcosa di simile (vedi sotto), comunque in base al tipo di valori cercati la funzione Find potrebbe fallire.
    Sempre meglio allegare un file, in questi casi. 
     
    Sub tttest()
    Dim R1 As Range, R2 As Range
    Dim C As Long
        With Workbooks("FileB").Worksheets("report")
            Set R1 = .Range(.Cells(2, 2), .Cells(5987, 2))
        End With
        For C = 1389 To 1 Step -1
            Set R2 = R1.Find(Cells(C, 6))
            If Not R2 Is Nothing Then Cells(C, 6).EntireRow.Delete
        Next C
    End Sub



  • di ambrovba data: 21/10/2017 21:26:20

    Ciao Zer0Kelvin,

    funziona esattamente il codice fatto da te. Grazie mille

    Però vorrei capire meglio alcune cose.
    1- Come faccio a far funzionare la macro senza che vada io ad aprire il file B?
    2- il ciclo with che utilizzi cosa fa esattamente?
    3- non riesco a capire come leggere logicamente questi due passaggi
    Set R2 = R1.Find(Cells(C, 6))
    If Not R2 Is Nothing ecc ecc
    anche se capisco il risultato.


    PS
    io all'inizio avevo pensato di fare tipo
    For 1389 to 1
    for 5987 to 2
    if cellA=cellB then
    cellA.delete
    end
    next
    next
    ma si bloccava tutto, è possibile fosse colpa della mole di righe da controllare?



  • di Zer0Kelvin data: 21/10/2017 23:13:45

    Non speravo funzionasse al primo colpo ma, a caval donato...
    Passando ai tuoi quesiti:
    1) puoi aprire il file da codice con un'istruzione analoga a quella sotto riportata; se il file non si trova nella stessa directory della cartella di lavoro devi indicare il percorso completo (es. "C:MiacartellaFileB")
    2) Il With...End With serve a rendere implicito il riferimento ad un oggetto, in questo caso serve solo a rendere più snello il codice (vedi esempio). Nota che i riferimenti a Range e Cells all'interno del With sono preceduti da un punto.
    3) Il metodo Range.Find(Valore) ricerca Valore all'interno di Range; se Valore viene trovato, restituisce la cella contenente Valore, altrimenti restituisce Nothing.


    I due cicli For...Next nidificati si possono usare, ma Find è più veloce.
    Forse il programma si bloccava perchè c'era qualcosa di errato all'interno dei cicli.
     
    '1)
    Workbooks.Open("FileB") ' apre FileB
    'ATTENZIONE, dopo l'esecuzione di questa istruzione, il Workbook attivo è quello di FileB
    'Per rendere di nuovo attivo il Workbook che contiene la macro usare
    ThisWorkbook.Activate ' altrimenti la macro non funziona correttamente
    'Puoi chiudere il file precedentemente aperto con
    Workbooks("FileB").Close
    
    '2)
    With Sheets("Foglio1")
            .Range("A1")
    End With
    'Equivalente a
    Sheets("Foglio1").Range("A1")
    



  • di ambrovba data: 22/10/2017 14:41:28

    Grazie per i punti 2 e 3, mentre ho un problema col punto 1 con la stringa che chiude il file B mentre quella che lo apre funziona perfettamente.

    l'errore che mi dà è "indice non è incluso nell'intervallo"

    riallego tutto il codice
     
    Sub tttest()
    Dim R1 As Range, R2 As Range
    Dim C As Long
    
    Workbooks.Open ("C:UsersambrogioDesktopNuova cartellamacroFile") ' funziona
        With Workbooks("File").Worksheets("report")
            Set R1 = .Range(.Cells(2, 2), .Cells(5987, 2))
        End With
    
    ThisWorkbook.Activate
    
        For C = 1389 To 1 Step -1
            Set R2 = R1.Find(Cells(C, 6))
            If Not R2 Is Nothing Then Cells(C, 6).EntireRow.Delete
        Next C
    Workbooks("C:UsersambrogioDesktopNuova cartellamacroFile").Close 'dà errore ovunque lo metta
    
    End Sub



  • di Zer0Kelvin data: 22/10/2017 22:36:51

    In Workbooks(Nomefile) nomefile è solo il nome del file, senza il percorso.