Cercavert su più colonne



  • Cerca.vert su più colonne
    di Sbizzy data: 17/01/2014 18:24:56

    Buonasera a tutti,

    Problema: ho una matrice 15x80 (15 righe 80 colonne), costituita da sedici tabelle 15x5 l'una. Devo poter impostare una formula tale che mi cerchi un valore nella colonna centrale di ogni tabella (per intenderci le colonne C, H, M, R etc..) e restituisca il valore della colonna più a destra della corrispettiva tabella (ad esempio se il valore è in C3, voglio come risultato il contenuto di E3, se il valore è in R15, il risultato sarà il valore di T15).

    E' fattibile? Se si, come?

    NB: se può essere d'aiuto, il valore che sto cercando è univoco nella matrice e NON può trovarsi in altre colonne se non quelle centrali di ognuna delle sedici tabelle.

    Grazie in anticipo!



  • di ninai (utente non iscritto) data: 17/01/2014 18:37:50

    allega un file di esempio



  • di Sbizzy data: 17/01/2014 18:46:56

    Allegato.

    Non ho il pc del lavoro, quindi ho creato una versione ridotta con solo 2 delle sedici tabelle. Spero si capisca.



  • di ninai (utente non iscritto) data: 17/01/2014 19:17:33

    ciao
    una possibilità, se i numeri da cercare sono univoci,
    in B21:
    =MATR.SOMMA.PRODOTTO(($C$3:$J$17=B20)*($E$3:$L$17))
    e trascini a destra
    ovviamente con 16 tabelle i range vanno adeguati



  • di Sbizzy data: 17/01/2014 19:46:35

    Ciao.

    Grazie della risposta!
    La formula funziona, l'unico problema è che io ho messo solo valori numerici nell'esempio, ma potrebbero essere dati alfanumerici, del tipo "1-via" oppure lettere nelle colonne 5.
    In tal caso la formula non funziona.



  • di ninai (utente non iscritto) data: 17/01/2014 20:03:06

    Con le formule al momento non saprei come fare, sicuramente qualcuno con VBA ti aiuterà.
    Io, in modo "cesereccio" , ti consiglierei di spostare le tabelle in orizzontale oppure crearti una matrice "fantasma" con dei collegamenti di cella per rendere la matrice utilizzabile con cerca.vert().



  • di Sbizzy data: 17/01/2014 20:12:39

    La matrice "fantasma" la utilizzavo prima di scoprire VBA, potrei usarla come soluzione provvisoria finchè non mi aiuta qualcun altro.

    Grazie mille!



  • di Roberto (utente non iscritto) data: 17/01/2014 23:01:34

    Non dici cosa vuoi fare se viene trovato il valore.
    Nella routine che vedi sotto compare semplicemente un messaggio che mostra il valore trovato.
    non sapendo come ottieni il valore da cercare, ho provvisoriamente assunto che il valore da cercare sia immesso nella cella a20.

     
    Sub sbizzy()
    Dim valore As Variant, trovato As Variant, x As Variant
    Dim riga As Integer, colonna As Integer
    With Worksheets("Foglio1") '----------------->da cambiare
    valore = .Range("a20").Value
        For riga = 1 To 15
            For colonna = 3 To 78 Step 5
                 x = .Cells(riga, colonna).Value
                 If x = valore Then
                    trovato = .Cells(riga, colonna + 2).Value
                    MsgBox trovato
                    End If
            Next colonna
    Next riga
    End With
    End Sub



  • di Sbizzy data: 18/01/2014 16:38:40

    Ciao Roberto,

    allora la matrice la prendo da un altro file excel (ho già una macro che la copia e la traspone); poi da un sw esterno prendo un'altra tabella che mi da una lista di valori (io ne ho messi 3 per fare un esempio nelle celle b20-c20-d20). Nella cella sottostante, voglio che venga messo il valore che viene trovato nella matrice con la logica che ho illustrato prima.

    Quindi la macro dovrebbe cercare il valore di b20 nella matrice, se lo trovasse riportare il valore nella cella b21, altrimenti b21=0. Poi passa a c20, cerca il valore nella matrice e il risultato lo mette in c21...e cosi via

    Spero sia chiaro, alla peggio lunedi mando il file completo dal lavoro...

    Grazie, ciao.



  • di scossa (utente non iscritto) data: 19/01/2014 11:40:03

    in B21
    =SE.ERRORE(CERCA.VERT(D20;$C$3:$E$17;3;0);0)+SE.ERRORE(CERCA.VERT(D20;$H$3:$J$17;3;0);0)

    Ovviamente aggiungere +SE.ERRORE(....... per le altre 3 tabelle.



  • di Sbizzy data: 19/01/2014 13:50:38

    Ciao scossa,

    la formula funziona come quella di ninai, ovvero solo se la colonna 5 avesse sempre valori numerici. In più, le tabelle sono 15 e la formula sarebbe infinita...Per ora sto modificando la macro di roberto per adattarla, domani la testo e vediamo cosa esce fuori.

    nel frattempo grazie a tutti!!!



  • di scossa (utente non iscritto) data: 19/01/2014 14:18:15

    cit.: "...ovvero solo se la colonna 5 avesse sempre valori numerici"

    =SE.ERRORE(CERCA.VERT(D20;$C$3:$E$17;3;0);"") & SE.ERRORE(CERCA.VERT(D20;$H$3:$J$17;3;0);"")

    cit.: "n più, le tabelle sono 15 e la formula sarebbe infinita.."

    ops... avevo capito 5 tabelle ...... pardon

    Una soluzione vba quindi potrebbe andarti bene?



  • di Sbizzy data: 19/01/2014 14:29:51

    Si sicuramente meglio VBA se possibile.

    Comunque ho guardato sul pc di lavoro e il file è leggermente più complesso dell'esempio...ne faccio una versione identica con valori inventati per farvi capire cosa devo fare con esattezza e poi la allego.



  • di Sbizzy data: 19/01/2014 15:21:28

    Ok, inserito il secondo file (sbizzy.rar).

    Ha due fogli, nel secondo c'è la matrice con solo 2 tabelle anzichè le 15 del file originale, ma credo che l'unica cosa che cambi sia un ciclo più esteso. Nel primo foglio ci sono due tabelle, che di fatto sono la trasposta delle altre, ma con le sole colonne 3 e 5. Quello che voglio è una macro che riempia le celle gialle con i valori ricavati nel modo già illustrato (legge il valore della cella sopra, lo cerca nella matrice e restituisce il valore della cella 2 volte a destra, ovvero in colonna 5).




  • di ninai (utente non iscritto) data: 19/01/2014 18:46:23

    Ciao
    alla luce di questo nuovo allegato, avendo l'indicazione della tabella, le cose cambiano.
    Se ho ben interpretato il problema:
    in C7: =SE.ERRORE(CERCA.VERT(C6;SCARTO('Tabella vecchia'!$A$3;0;1+CONFRONTA($A6;'Tabella vecchia'!$A$1:$Y$1;0);15;3);3;FALSO);"")
    e trascini fino a Q7 e poi copi incolli nelle altre righe. ti allego esempio con 5 tabelle. (file Sbizzy1)



  • di scossa data: 19/01/2014 19:59:56

    La semplicissima udf sottostante fa quello che ti serve.

    da usare così:
    in C7 scrivi
    =FindInTab(C6;'Tabella vecchia'!$A$3:$E$17;3;2)
    e trascini fino a Q7

    in C10 scrivi
    =FindInTab(C9;'Tabella vecchia'!$F$3:$J$17;3;2)
    e trascini fino a Q10

     
    '---------------------------------------------------------------------------------------
    ' UDF       : FindInTab
    ' Author    : scossa
    ' Date      : 19/01/2014
    ' Purpose   :
    '---------------------------------------------------------------------------------------
    '
    Public Function FindInTab(ByVal vWhat As Variant, ByRef rngTab As Range, _
      ByVal nColSerch As Long, ByVal nOffset As Long) As Variant
    
      Dim rngFnd As Range
      Dim vRet_ As Variant
      If vWhat = "" Then
        vRet_ = ""
      Else
        Set rngFnd = rngTab.Columns(nColSerch).Find(what:=vWhat, LookIn:=xlValues, lookat:=xlWhole)
        If Not rngFnd Is Nothing Then
          vRet_ = rngFnd.Offset(, nOffset).Value
        Else
          vRet_ = "" '
        End If
      End If
      FindInTab = vRet_
    
    End Function
    



  • di Sbizzy data: 19/01/2014 20:52:58

    Entrambe le soluzioni sono carine, ma entrambe hanno lo stesso limite: se un codice di colonna 3 nella "tabella vecchia" è in tabella 1, ma nella tabella da aggiornare è in tabella 2, non viene trovato il valore di colonna 5!

    Per esempio E7, E8 e E9 sono vuote perchè i codici prima erano nella tabella 2, ora sono in tabella 1. In quelle celle dovrei vedere i valori della colonna 5 della tabella 2 in "tabella vecchia", ovvero E7=ok, E8=IN e E9=ok

    Il codice di roberto funzionava da questo punto di vista, mi serve solo che venga adattato perchè la matrice si trova in un altro foglio e perchè viene solo visualizzato il testo del risultato in base al valore del codice nella cella impostata in riga 5 (valore = .Range("a20").Value)



  • di scossa data: 19/01/2014 21:33:42

    Ok, adesso ho capito.

    Sostituisci la udf col codice sottostante.

    da usare:

    in C7 scrivi
    =FindInTab(C6;'Tabella vecchia'!$A$3:$J$17;{38};2)
    e trascini fino a Q7

    in C10 scrivi
    =FindInTab(C9;'Tabella vecchia'!$A$3:$J$17;{38};2)
    e trascini fino a Q10
     
    '---------------------------------------------------------------------------------------
    ' Procedure : FindInTab
    ' Author    : scossa
    ' Date      : 19/01/2014
    ' Purpose   :
    '---------------------------------------------------------------------------------------
    '
    Public Function FindInTab(ByVal vWhat As Variant, ByRef rngTab As Range, _
      ByRef nColSearch As Variant, ByVal nOffset As Long) As Variant
    
      Dim rngFnd As Range
      Dim rngSearch As Range
      Dim j As Long
      Dim vRet_ As Variant
      If vWhat = "" Then
        vRet_ = ""
      Else
        Set rngSearch = rngTab.Columns(nColSearch(1))
        For j = 2 To UBound(nColSearch)
          Set rngSearch = Union(rngSearch, rngTab.Columns(nColSearch(j)))
        Next
        Set rngFnd = rngSearch.Find(what:=vWhat, LookIn:=xlValues, lookat:=xlWhole)
        If Not rngFnd Is Nothing Then
          vRet_ = rngFnd.Offset(, nOffset).Value
        Else
          vRet_ = "" '
        End If
      End If
      Set rngSearch = Nothing
      FindInTab = vRet_
    End Function
    



  • di Sbizzy data: 19/01/2014 22:45:58

    Ho messo quello che hai detto, ma mi da solo "#VALORE" o celle vuote...

    Sinceramente è un codice molto diverso dalle poche macro che so fare, quindi non saprei nemmeno come cercare l'errore...



  • di scossa data: 20/01/2014 08:24:06

    cit.: "Ho messo quello che hai detto, ma mi da solo "#VALORE" o celle vuote...
    Sinceramente è un codice molto diverso dalle poche macro che so fare, quindi non saprei nemmeno come cercare l'errore... "

    Ho allegato il file di esempio (sbizzy_scossa.xlsm)



  • di scossa data: 20/01/2014 08:27:45

    Gli argomenti della UDF sono
    vWhat la stringa da cercare
    rngTab il range completo dellla matrice di tutte le tabelle
    nColSearch le colonne in cui cercare vWhat (in forma di matrice: {381318 ......}
    nOffset le colonne di scostamento dalla cella in cui vWhat è stato trovato (può essere negativo per le celle a sx) e di cui si vuole restituito il valore



  • di Sbizzy data: 20/01/2014 11:07:59

    Ok ora li vedo...visto che sono al lavoro lo testo sul file completo e ti faccio sapere.

    Comunque vada, grazie infinite!!!



  • di Sbizzy data: 21/01/2014 16:07:00

    Ok problema risolto con successo.

    Grazie mille a tutti!!!