Esercizio di ricerca



  • Esercizio di ricerca
    di Vecchio Frac data: 24/03/2015 20:50:34

    Come utilizzare CERCA.VERT perché restituisca un valore in una colonna arbitraria rispetto al valore cercato?

    Allego (se riesco a formattarlo) un esempio di tabella.
    ID	fatt	data	descr	quantita	ditta
    
    300 N00101 13/02/2015 temperamatite quadrati per matite rotonde 100 pippo
    388 N00431 25/02/2015 sacchi aerati per farina bianca 75 pluto
    423 P00065 02/03/2015 pesci d'aprile surgelati pronti 200 topolino
    511 R02330 09/03/2015 autoradio finta per ingannare i ladri 125 paperino
    706 P00122 20/03/2015 inchiostro simpatico con disegno di Brontolo 50 zio paperone


    Si chiede di conoscere ad esempio la "descrizione" corrispondente alla ditta "topolino".
    Per questa risposta chiedo che i nostri utenti esperti (soprattutto i campioni delle formule!) aspettino un pochino prima di rispondere, per vedere se qualcuno ha la voglia di farsi avanti.
    In aggiunta, chiedo anche di costruire la relativa routine VBA (che faccia insomma quanto richiesto) e che abbia le caratteristiche di CERCA.VERT.
    Il premio per il vincitore (il migliore sarà a mio giudizio ovviamente) è quello di poter proporre, a sua volta, un esercizio (martedì prossimo).
    Dai provateci ^_^






  • di brontolo (utente non iscritto) data: 25/03/2015 09:29:19

    Bella iniziativa, Vecchio Frac
    Visto che, anche se indirettamente:
    - inchiostro simpatico con disegno di Brontolo
    Mi sento chiamato in causa, ho ritenuto opportuno allegare la mia proposta.



  • di brontolo (utente non iscritto) data: 25/03/2015 09:38:30

    Hoppsss!
    Il file Vecchio Frac #01
    non è fruibile (molto probabilmente è colpa del carattere "#")
    Ho inserito Vecchio Frav Ok che sembra non avere problemi; almeno nella visualizzazione.



  • di Vecchio Frac data: 25/03/2015 11:32:38

    Grazie Brontolo! In effetti non avevo idea che potesse partecipare un utente "Brontolo" ^_^
    Il primo file dà problemi per via del cancelletto.
    Ho visto il secondo file.
    1) FORMULE: la consegna era di utilizzare CERCA.VERT e non INDICE + CONFRONTA
    2) Combobox ACTIVEX: idea carina, non proprio attinente però. Spiegami il significato di selezionare Cells(96, 76) (BX96) ^_^
    3) VBA: io chiedevo di simulare la funzione CERCA.VERT per riscriverla affinchè funzionasse come la formula. Nel tuo esempio hai intercettato il Change del foglio, e il codice sfrutta l'idea della formula di cui al punto 1, incollando una formula risultante da una combinazione di INDICE e CONFRONTA.

    Hai vinto un punto per il coraggio e l'abilità, ma non hai centrato il tema ^_^
    Se vuoi puoi riprovarci :)





  • di brontolo (utente non iscritto) data: 25/03/2015 11:46:20

    Cit. ... Spiegami il significato di selezionare Cells(96, 76) (BX96)
    Sempliceme volevo bloccare le intestazioni fuori dall'area di lavoro, ma questa è solo una mia "pallosità".

    Cercherò di spremere le meningi per risolvere con CERCA.VERT; a questo proposito rimpiango spesso Symphony che consentiva di eseguire il CERCA.VERT anche nei campi precedenti.
    Magari questa può essere la buona occasione per imparare questa tecnica anche in Excel.

    Brontolo






  • di brontolo (utente non iscritto) data: 25/03/2015 12:09:38

    Perdonami Vecchio Frac.
    La Funzione:
    =CERCA($H$2;$F$2:$F$6;$D$2:$D$6)
    può essere accettabile o debbo aspettare, in religiosa attesa, la soluzione con CERCA.VERT ?

    Brontolo


  • bella trovata !
    di Luca.Donati data: 25/03/2015 12:31:34

    Ciao. No, non conosco la soluzione, ma l'iniziativa di un concorso fatto in questo modo mi piace da morire!
    Ecco, così mi arrivano le notifiche per mail...



  • di Mister_x (utente non iscritto) data: 25/03/2015 12:54:19

    ciao VF

    scusa se mi intrometto ma da help su cerca.ver() mi riporta la seguente descrizione
    Cerca un valore nella prima colonna di una matrice tabella e lo restituisce nella stessa riga di un'altra colonna.

    La parola VERT in CERCA.VERT indica l'orientamento verticale. Utilizzare la funzione CERCA.VERT invece di CERCA.ORIZZ quando i valori di confronto sono collocati in una colonna a sinistra dei dati che si desidera trovare.

    quindi da come si legge in questo
    cerca.vert( valore da cercare ; range di colonne in cui cercare, colonna da cui riporto il dato ; 0 per dato vero)
    nel nostro caso io ricerco nel range (D2:F6) ma come dice l'help la ricerca viene fatta sulla prima colonna di sinistra quindi D:D mentre noi dobbiamo fare la ricerca su F:F quindi con la funzione cerca.vert() a mio parere non arriveremo mai al dunque
    comunque non si puo' dire mai
    mentre con una funzione in VB tipo cerca.Vert si puo' risolvere la questione impostata in questa maniera circa
    Public Function Vert_Cerca(Nome As Variant, Ditta As Range, Col_Des As Variant) As Variant
    dove metto (cosa cercare ;dove cercare;la colonna da dove riportare il dato, nel nostro caso o 4 o "D")

    comunque ottima questa soluzione di coinvolgere tutti gli utenti ( non esperti ) di dare le loro soluzioni sbagliate o giuste che siano, ma con lo spirito di partecipare al problema

    ciao
    seguo anch'io con interesse questa iniziativa








  • di Toty (utente non iscritto) data: 25/03/2015 13:11:37

    Bella iniziativa, peccato ci siano pochi avventori...
    Seguo anche io l'evoluzione... Non ritenendomi esperto mi sono cimentato anche io... Attendo il via libera per postare la mia ipotesi.

    PS Cosà c'è di strano in un "temperamatite quadrati per matite rotonde" In commercio son tutti quadrati e fanno la punta a matite tonde....


  • indizio o depistaggio?
    di Luca.Donati data: 25/03/2015 13:31:48

    Non so se quello che sto per dire sia sensato. E soprattutto non saprei come metterlo in pratica concretamente.
    Per prima cosa, l'equivalente VBA di Cerca.vert è VLookup, ma va lanciato con un comando complicato, credo roba come:
    miaricerca = Application.WorksheetFunction.Vlookup(bla,bla,numColonna,True/False)
    (mezzo copiato, mezzo ricordato)
    E fin qui, c'è poco da discutere.
    Secondo me, le spine vengono fuori nel momento in cui il valore cercato sta a destra e la corrispondenza a sinistra...
    Infatti un giorno tentai di mettere un numColonna negativo e il codice mi mandò a... insomma ci siamo capiti.

    Abbozzo un'idea. Il codice potrebbe avventurarsi a fare una tabella virtuale (ma di che natura? come si fa un coso del genere?) (*) in cui la prima colonna riprende esattamente la colonna in cui sta il valore cercato, poi il resto segue e la corrispondenza si trova fatalmente a destra della prima colonna, anche se quest'ultima non è che uno specchio di quello che sta un po' più in là...

    (*) Non posto nessun codice perché non ho la minima idea di come affrontare questi quesiti.



  • di scossa data: 25/03/2015 14:29:39

    Aspettando che VF dia il via libera a tutti, suggerirei - per la soluzione FORMULA - di inserire la formula direttamente nel post, senza costringere a scaricare il file.




    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno.
    Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)



  • di Vecchio Frac data: 25/03/2015 16:18:13

    Scusate tutti, ho avuto problemi e torno ora dal p.s.
    Via libera a tutti!! :D

    Rispondo a grappolo ai diversi interventi:
    - Brontolo con CERCA: la richiesta è usare CERCA.VERT, ma mi piace la tua iniziativa e ti assegno altro mezzo punto ^_^
    - Mister_x: una soluzione c'è ^_^
    - Luca.Donati: più semplice, una scansione con ricerca e confronto
    - Toty: i miei temperamatite hanno tutti il buco rotondo, mi riferivo a quello (senza malizia tipica dei giovani) ...
    - scossa: concordo, postate qui direttamente la formula ma anche il codice VBA.

    E ora divertitevi :) ricordate che chi vince poi posterà un quiz a sua volta :P






  • di scossa data: 25/03/2015 17:14:38

    cit. V.F.: "ho avuto problemi e torno ora dal p.s."

    Spero niente di grave.

    Intanto - per la soluzione CODICE - propongo questa UDF, da usarsi in una celle così:

    =CercaVert("topolino";$F$2:$F$6;-2;0)

    dove in F2:F6 ci sono le ditte in cui cercare la stringa "topolino" (ma può essere anche una cella) e -2 rappresenta lo scarto, rispetto a tale colonna, della cella il cui valore è da restituire.


    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno.
    Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)

     
    '---------------------------------------------------------------------------------------
    ' Procedure : CercaVert
    ' Author    : Scossa
    ' Date      : 25/03/2015
    ' Purpose   : Ricerca sWath nel range Rng e restituisce il
    '             valore della cella spostata lCol rispetto alla
    '             cella dove il valore è stato trovato.
    '---------------------------------------------------------------------------------------
    '
    Public Function CercaVert( _
      ByVal sWath As String, _
      ByRef rng As Range, _
      ByVal lCol As Long, _
      Optional ByVal bPart As Boolean = False) As Variant
    
    
      Dim rFound As Range
      
      Set rFound = rng.Find(sWath, _
          LookAt:=IIf(bPart, xlPart, xlWhole), _
          SearchDirection:=xlNext)
      If Not rFound Is Nothing Then
          CercaVert = rFound.Offset(, lCol).Value
      Else
          CercaVert = CVErr(Excel.xlErrNA)
      End If
    
    End Function



  • di Vecchio Frac data: 25/03/2015 18:19:21

    Niente di grave per me, ma la collega è ancora sotto esami poverina :)

    La soluzione VBA di scossa fa quanto richiesto ma non ha tutte le caratteristiche di "CERCA.VERT(valore, matrice, indice, intervallo)", quindi non lo simula in pieno: per esempio manca del parametro "intervallo" (è quello che mi ha fatto penare un po' per tradurlo).
    CERCA.VERT esegue una ricerca un po' stocastica, non è che la Guida sia molto più esaustiva :) e comunque restituisce un valore anche nel caso non ci sia una corrispondenza esatta (tranne il caso in cui intervallo sia False e allora restituisce #N/D se non c'è corrispondenza esatta).

    Un punto e mezzo per scossa :)





  • di Luca73 data: 25/03/2015 18:20:43

    Ciao a tutti ci ho messo un po' ma ho trovato una soluzione in formula che riporto sotto.
    Le ipotesi sono:
    In H1 l'intestazione della colonna da cui si vuole cercare (es "Ditta")
    In H2 il valore che si vuole cercare nella colonna identificata in H1 (es. "Pluto")
    In I1 l'intestazione della colonna da cui si vuole il risultato (es. "Descrizione").
    La formula è matriciale e non ha limiti di righe purché siano contigue.
    Ciao a tutti

     
    =SE.ERRORE(CERCA.VERT($H$2;SE(RIF.COLONNA(SCARTO($A$1;1;0;CONTA.VALORI(A:A)-1;2))=1;SCARTO($A$1;0;-1+CONFRONTA($H$1;$A$1:$F$1;0);CONTA.VALORI(A:A);1);SCARTO($A$1;0;-1+CONFRONTA($I$1;$A$1:$F$1;0);CONTA.VALORI(A:A);1));2;FALSO);"Verifica Dati di Input")






  • di Vecchio Frac data: 25/03/2015 18:35:09

    Bravo Luca73, la formula è abbastanza ben incasinata da farti meritare il tuo punto perché... funziona!
    Ci ho messo un po' per seguirla, ma mi pare abbastanza ben contorta... non me la ricorderei :P
    Si può semplificare...

    Un punto a Luca73 :)





  • di ninai (utente non iscritto) data: 25/03/2015 18:58:26

    Ciao
    ho visto adesso e confesso di non aver letto molto attentamente, "non vorrei essere fuori tema" ma dal file di esempio e volendo obbligatoriamente usare CERCA.VERT(), in I2:
    =CERCA.VERT(SCARTO(A2;CONFRONTA(H2;F2:F6;0)-1;;);$A$2:$D$6;4)



  • di Mister_x (utente non iscritto) data: 25/03/2015 19:08:01

    ciao VF

    ho usiamo una colonna di appoggio o usiamo una matriciale

    matriciale cercando topolino usando caratteri jolly
    =SOSTITUISCI(CERCA.VERT("topolino"&"*";F2:F6&D2:D6;1;0);"topolino";"")

    ciao









  • di ninai (utente non iscritto) data: 25/03/2015 19:17:50

    MisterX, bella la tua soluzione!!!, la modifico per renderla non matriciale e generale:
    =SOSTITUISCI(CERCA.VERT(H2&"*";INDICE(F2:F6&D2:D6;);1;0);H2;"")



  • di alfrimpa data: 25/03/2015 19:24:01

    So che non serve a niente dirlo (ed è solo una mia soddisfazione personale) ma guardando la Function di Scossa ho rilevato che ha utilizzato la stessa logica che avrei adottato io con Find e Offset.

    Alfredo





  • di scossa data: 25/03/2015 19:33:59

    cit. V.F.: "....ma non ha tutte le caratteristiche di "CERCA.VERT(valore, matrice, indice, intervallo)", quindi non lo simula in pieno: per esempio manca del parametro "intervallo" (è quello che mi ha fatto penare un po' per tradurlo)"

    Sicuro?
    A me sembra di aver previsto tutti e 4 i parametri:
    Public Function CercaVert( _
    ByVal sWath As String, _
    ByRef rng As Range, _
    ByVal lCol As Long, _
    Optional ByVal bPart As Boolean = False) As Variant


    CERCA.VERT(valore, matrice, indice, intervallo)

    sWhat corrisponde a Valore
    rng corrisponde a matrice
    lCol corrisponde a indice
    bPart corrisponde ad intervallo (impostato per default a False anzichè a Vero).

    Piuttosto, bisogna renderla volatile, altrimenti se varia il valore della cella restituito il risultato della udf non cambia, quindi riporto sotto il codice aggiornato, con "intervallo" impostato a VERO.


    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno.
    Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)

     
    '---------------------------------------------------------------------------------------
    ' Procedure : CercaVert
    ' Author    : Scossa
    ' Date      : 25/03/2015
    ' Purpose   : Ricerca sWath nel range Rng e restituisce il
    '             valore della cella spostata lCol rispetto alla
    '             cella dove il valore è stato trovato.
    '---------------------------------------------------------------------------------------
    '
    Public Function CercaVert( _
      ByVal sWath As String, _
      ByRef rng As Range, _
      ByVal lCol As Long, _
      Optional ByVal bPart As Boolean = True) As Variant
    
      Application.Volatile
      Dim rFound As Range
      
      Set rFound = rng.Find(sWath, _
          LookAt:=IIf(bPart, xlPart, xlWhole), _
          SearchDirection:=xlNext)
      If Not rFound Is Nothing Then
          CercaVert = rFound.Offset(, lCol).Value
      Else
          CercaVert = CVErr(Excel.xlErrNA)
      End If
    
    End Function



  • di Vecchio Frac data: 25/03/2015 20:12:40

    Bravi Ninai e Mister_x! Anche e soprattutto nella versione generalizzata da Ninai.
    Una formula più compatta e anche più leggera da capire :)
    Ma sono state utilizzate ancora troppe funzioni... (CERCA.VERT, SCARTO e CONFRONTA; o anche SOSTITUISCI, CERCA.VERT e INDICE).
    Io proporrò una soluzione con sole DUE funzioni (o meglio una, accoppiata a CERCA.VERT).

    Un punto ciascuno a Ninai e Mister_x!

    @Scossa
    Sì avevo visto (e utilizzato nella prova) il parametro bPart, il quale fa il suo dovere, ma in un modo leggermente diverso rispetto a CERCA.VERT, per il quale "intervallo" opera abbastanza ambiguamente, producendo non dei risultati esatti o parziali, ma esatti o "approssimativi". A essere onesti neanche la mia soluzione VBA è perfettamente aderente al modello di CERCA.VERT perchè non ne ricalca esattamente lo stesos comportamento, ma a parità di condizioni la mia produce un risultato "approssimato" mentre la tua mi dà giustamente (per la sua logica) Errore 2042, cioè nessuna corrispondenza esatta invece di una approssimata.
    Comunque non mi dispiaceva la tua soluzione, elegante e concisa, ecco perchè hai guadagnato un punto e mezzo :)





  • di Vecchio Frac data: 25/03/2015 20:23:58

    A proposito, ora che mi viene in mente pubblico qui (altrimenti poi spariscono i file allegati) le soluzioni di Brontolo.
     
    'Formula:
    =SE($H$2="";"";INDICE(D$2:D$6;CONFRONTA($H$2;$F$2:$F$6;0)))
    
    'VBA
    Option Explicit
    
    Private Sub Worksheet_Change(ByVal Target As Range)
        If Target.Address = "$H$2" Then
            Cells(2, 9).FormulaLocal = "=INDICE(D$2:D$6;CONFRONTA($H$2;$F$2:$F$6;0))"
            Cells(2, 9).Copy
            Cells(2, 9).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
        Application.CutCopyMode = False
        End If
        Cells(96, 76).Select
    End Sub






  • di Luca73 data: 25/03/2015 21:16:22

    Ciao Vecchio Frac
    la mia formula è diventata complicata nel momento in cui ho voluto fare in modo che potesse cercare qualsiasi valore in qualsiasi colonna e restituire il risultato da una colonna qualsiasi.
    la formula iniziale era veramente semplice
    =CERCA.VERT(H2;SE(RIF.COLONNA(A:B)=1;F:F;D:D);2;FALSO) - ovviamente matriciale
    la filosofia di base è semplice siccome con excel non ho trovato modo per costruire una matrice semplicemente affiancando due vettori allora ho pensato di partire da una qualsiasi matrice prefatta (2 colonne) e successivamnte sostituisco la prima colonna con la colonna dove ci sono i valori che voglio ricercare e la seconda colonna con la colonna dove ci sono i risultati che voglio ottenere.
    avevo pensato anche ad una cosa molto più stupida che sarebbe la seguente:
    =CERCA.VERT(INDICE(A$2:A$6;CONFRONTA($H$2;$F$2:$F$6;0));A:F;4;FALSO)
    ma quest'ultima l'avevo scartata perchè troppo stupida in quanto usavo un INDICE + CONFRONTA per farmi dare il risultato della prima colonna e passarlo al CERCA.VERT ma così è puramente un esercizio stilistico.






  • di Vecchio Frac data: 25/03/2015 21:58:21

    cit. " in modo che potesse cercare qualsiasi valore in qualsiasi colonna e restituire il risultato da una colonna qualsiasi."
    ---> La massima generalizzazione! Grande Luca 73 :)

    Siete tutti bravissimi e straordinari e vi ringrazio di aver preso parte al giochino ^_^
    Domani pubblico le mie soluzioni... magari non piaceranno ma almeno (credo) ci siamo divertiti :)





  • di Textomb data: 25/03/2015 23:38:15

    uffa.
    non ho avuto modo di partecipare al giochino. troppi casini da gestire al momento...
    Però con il pensiero sono con Voi...!
    Notte.



  • di Mister_x (utente non iscritto) data: 25/03/2015 23:48:59

    ciao

    appena ritornato e o visto che la discussione e' stata molto seguita da tutti
    peccato che alla fine siamo subentrati noi con le nostre proposte,
    comunque un ragguaglio alla mia perche' avevo pensato anch'io all'introduzione di indice in cerca.vert, essendo questa funzione abilitata a creare matrici,ma avendo capito male la richiesta di VF pensavo che in un cerca.vert.() non bisognava utilizzare altre funzioni e' per questo che mi sono affidato ad una matriciale
    comunque visto il risultato posto anche la mia funzione in vb dove per questa servono solo tre parametri
    utilizzo
    =vertcerca("topolino";F2:F6;4) valore da cercare;colonna dove cercare;colonna dove valore da riportare


    ciao
     
    Option Explicit
    Public Function VertCerca(Nome As Variant, Ditta As Range, Col_Des As Variant) As Variant
    Application.Volatile
    Dim Ditt_a As Variant
    Dim Nriga As Long
    For Each Ditt_a In Ditta
     If Ditt_a = Nome Then
       Nriga = Ditt_a.Row
       Exit For
     End If
    Next
    If Nriga > 0 Then
      VertCerca = Cells(Nriga, Col_Des)
    Else
      VertCerca = "Valore non Trovato -> " & Nome
    End If
    End Function
    






  • di jacks (utente non iscritto) data: 26/03/2015 00:34:21

    CIAO VF, (ops scusa..)ciao vf.
    non sono un gran tecnico ne di VBA ne di excel.
    per il problema ( o per problemi simili), io utilizzo un sistema forse un po' arzigogolato, ma che ho trovato abbastanza rapido e funzionale:
    a) inserisco due o tre colonne a destra della tabella dei dati.
    b) siccome il dato da ricercare è uno (K2) che deve essere trovato nella colonna "I" inserisco nella cella "a2" la seguente formula: =SE(I2=$K$2;1;"") e la copio nelle celle successive della colonna A:A
    c) nella cella "b2" inserisco =SE(A2="";"";CONTA.NUMERI($A$2:A2)), e la copio nelle celle successive della colonna B:B, ottenendo il numero progressivo delle volte che viene rilevato il valore K2 nella colonna I:I
    d) ho inserito a sinistra della tabella una colonna con una numerazione progressiva da 1 a n
    e) la formula da inserire nella cella L2 è:=SE.ERRORE(CERCA.VERT(J2;$B$2:$I$9000;6;FALSO);"") che copio nelle celle successive della colonna L.
    con la stessa logica si possono ottenere tutte le informazioni da estrarre nella tabella es. il n.delle fatture corrispondente la data delle fatture i quantitaivi ecc., perchè è da presumere che nella colonna K esistano più celle corrispondenti a K2.
    Ovviamente in sede di procedura si possono effettuare operazioni con Vba come cancellare le formule delle colonne A e B e quelle della colonna L, creando in una riga le formule inziali che poi VBA copia nei Range definiti in base all'ampiezza del database, consolidando i dati con COPIAINCOLLASPECIALE.VALORI, in modo da rendere più leggera tutta la procedura.
    Allego il file con le formule inserite nel foglio VBA no grazie dove ho sostituito una cella nella colonna I.I per avere due risposte. (ho reso blank i numeri inseriti nella colonna J).
    Ripeto questa è una soluzione molto artigianale .
    ciao.
    CIAO



  • di scossa data: 26/03/2015 08:57:27

    @V.F.: ok, ho capito cosa intendi.


    Allora, visto che non hai precisato di non usare le WorksheetFunctions, propongo la sottostante variante


    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno.
    Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)

     
    '---------------------------------------------------------------------------------------
    ' Procedure : CercaVert
    ' Author    : Scossa
    ' Date      : 25/03/2015
    ' Purpose   : Ricerca sWath nel range Rng e restituisce il
    '             valore della cella spostata lCol rispetto alla
    '             cella dove il valore è stato trovato.
    '---------------------------------------------------------------------------------------
    '
    
    Public Function CercaVert( _
      ByVal vWath As Variant, _
      ByRef rng As Range, _
      ByVal nCol As Long, _
      Optional ByVal bPart As Boolean = False) As Variant
        
      Application.Volatile
      Dim rFound As Range
      Dim vToken As Variant
      
      
      vToken = Application.VLookup(vWath, rng, 1, --bPart)
      If Not IsError(vToken) Then
        Set rFound = rng.Find(vToken, After:=rng.Cells(rng.Rows.Count), _
            LookAt:=IIf(bPart, xlPart, xlWhole), _
            SearchDirection:=xlNext)
            CercaVert = rFound.Offset(, nCol).Value
      Else
        CercaVert = CVErr(Excel.xlErrNA)
      End If
    End Function
    
    
    


  • Fusse che fusse ^_^
    di Toty (utente non iscritto) data: 26/03/2015 09:03:01

    La mia

    Formularmente:
    supponendo la tabella A1:F6
    I3 Il nome da cercare
    F1:F6 elenco ditte
    =INDICE(A1:F6; CONFRONTA(I3; F1:F6; 0); 4)

    VBAlmente:
    Option Explicit
    Sub trovamelo()
    Dim Lista As Range, rigaA As Range
    Dim NomeA As String
    Dim r As Long

    Set Lista = Range("F1:F11")
    NomeA = InputBox("Inserisci nome ditta")



    Set rigaA = Lista.Find(NomeA, LookIn:=xlValues, LookAt:=xlWhole)

    If rigaA Is Nothing Or NomeA = "" Then
    MsgBox "nessuna corrispondenza"
    Else
    r = rigaA.Row
    MsgBox Cells(r, 4).Value

    End If
    End Sub



  • di scossa data: 26/03/2015 09:06:49

    Piccola correzione e semplificazione (bPart default True)



    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno.
    Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)

     
    '---------------------------------------------------------------------------------------
    ' Procedure : CercaVert
    ' Author    : Scossa
    ' Date      : 25/03/2015
    ' Purpose   : Ricerca sWath nel range Rng e restituisce il
    '             valore della cella spostata lCol rispetto alla
    '             cella dove il valore è stato trovato.
    '---------------------------------------------------------------------------------------
    '
    
    Public Function CercaVert( _
      ByVal vWath As Variant, _
      ByRef rng As Range, _
      ByVal nCol As Long, _
      Optional ByVal bPart As Boolean = True) As Variant
        
      Application.Volatile
      Dim rFound As Range
      Dim vToken As Variant
      
      
      vToken = Application.VLookup(vWath, rng, 1, --bPart)
      If Not IsError(vToken) Then
        Set rFound = rng.Find(vToken, After:=rng.Cells(rng.Rows.Count), _
            LookAt:=xlWhole, _
            SearchDirection:=xlNext)
            CercaVert = rFound.Offset(, nCol).Value
      Else
        CercaVert = CVErr(Excel.xlErrNA)
      End If
    End Function
    
    
    
    



  • di Vecchio Frac data: 26/03/2015 10:05:47

    Ciao ragazzi, vedo che stiamo andando avanti ^_^

    Textomb: sarà per la prossima volta. Stay tuned ;)

    Mister_x: la soluzione funziona, chiaramente, anche se la trovo migliorabile e soprattutto non simula proprio il comportamento di CERCA.VERT. Mezzo punto per te ^_^

    Jacks: mi sono ripromesso di provare a riprodurre lo scenario e le operazioni proposte. Piuttosto complicato direi... mi piace la gente che ha fantasia! mezzo punto anche per te ^_^

    Scossa: un volpone... hai utilizzato VLOOKUP per simulare CERCA.VERT (in effetti non era vietato)... è chiaro che dà il risultato migliore, aderente al comportamento della formula. Altro mezzo punto per te che hai aggirato l'ostacolo ^_^

    Toty: ti aspettavo... la formula va bene anche se non generalizza il problema perchè mi restituisce sempre il valore della quarta colonna. Il codice è onesto e fa il suo lavoro, e anche lui però non è generalizzato ma limitato alla quarta colonna. Un punto per te ^_^






  • di scossa data: 26/03/2015 12:13:07

    In effetti, il quesito non era molto chiaro.
    Però alla fine mi sembra che la richiesta sia quella, lato FORMULE, di "integrare" la funzione CERCA.VERT() per avere il valore di celle anche a sinistra della colonna di ricerca; lato VBA, di "replicare" la funzione CERCA.VERT() ma che restituisca valori anche a sinistra della colonna di ricerca.



    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno.
    Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)



  • di Vecchio Frac data: 26/03/2015 15:08:26

    Toty, va bene il risparmio ma bisogna investire :)

    Scossa, integrare CERCA.VERT è quasi esatto, si intendeva proprio sfruttare CERCA.VERT per far fare a questa funzione qualcosa per cui non sarebbe in grado da sola di fare. lato VBA, replicarne il comportamento e quindi naturalmente ottenere lo stesso risultato (io ci sono riuscito parzialmente).

    Comunque ragazzi mi avete dato soddisfazione e di questo sono contento!
    Ora prima di passare la palla a qualcun altro per la settimana prossima voglio dirvi che nessuno deve sentirsi penalizzato o "giudicato"... tutti avete avuto un'ottima parte nel giochino.
    E se oggi tocca a qualcuno, domani toccherà a qualcun altro... sarebbe bello che tutti venissero coinvolti anche a turno nella produzione di quesiti come questo :)

    Quindi alla fine di questa sfida, chiedo a MISTER_X di preparare e proporre un quesito (alla portata di tutti). Il titolo del post dovrà cominciare con "Esercizio ...".
    Non ci sono vincoli, puoi chiedere formule o codice o tutti e due. E tutti sono invitati a partecipare (magari gli utenti esperti intervengano dopo qualche ora per non tagliare le gambe agli altri).

    Nel post successivo vi allego la mia soluzione alla sfida CERCA.VERT... se volete potete commentare ma senza mandarmi a quel paese :)




  • La mia soluzione
    di Vecchio Frac data: 26/03/2015 15:12:26

    Avendo presente la tabella del primo post (che inizia in A1):
    Cerca "descr" (colonna D) dove ditta (colonna F) = "topolino"

    Formula:
    =CERCA.VERT("topolino";SCEGLI({1;2};F1:F6;D1:D6);2;0)

    In pratica:
    =CERCA.VERT (dato cercato; SCEGLI({1;2};colonna dove cercare;colonna da restituire);2;0)


     
    'In un modulo.
    'utilizzo: v_lookup(range("F1:F6"), "topolino").offset(,-2)
    Option Explicit
    
    Function v_lookup(r As Range, value As Variant, Optional interval As Boolean = True) As Variant
    Dim cell As Range, i As Integer, s As String
    'interval:
    'Valore logico che specifica se si desidera trovare una corrispondenza esatta o approssimativa mediante la funzione CERCA.VERT:
    
        'se interval è True o omesso,
        If interval = True Then
            'viene prima cercata una corrispondenza esatta
            Set cell = r.Find(value, LookAt:=xlWhole)
            If cell Is Nothing Then
                'e se non viene trovata viene cercata una corrispondenza parziale
                Set cell = r.Find(value, LookAt:=xlPart)
                If cell Is Nothing Then
                    'se non viene trovata viene restituita una corrispondenza approssimativa (il successivo valore più grande, inferiore a valore)
                    'per fare questo scorre la stringa di ricerca cercando nel range il più grande valore possibile che coincida con la ricerca parziale
                    i = Len(value) - 1
                    Do
                        s = Left(value, i)
                        Set cell = r.Find(s, LookAt:=xlPart)
                        i = i - 1
                    Loop Until Not (cell Is Nothing) Or i < 0
                    If cell Is Nothing Then
                        'se non è trovata ancora alcuna corrispondenza, restituisce il valore della prima cella del range
                        Set v_lookup = r.Cells(1)
                    Else
                        'trovata una corrispondenza parziale, restituisce il valore della cella trovata
                        Set v_lookup = cell
                    End If
                Else
                    Set v_lookup = cell
                End If
            Else
                Set v_lookup = cell
            End If
        Else
            'se interval è False viene cercata una corrispondenza esatta
            Set cell = r.Find(value, LookAt:=xlWhole)
            If cell Is Nothing Then
                'e se non viene trovata restituisce l'errore #N/D
                v_lookup = "#N/D"
            Else
                Set v_lookup = cell
            End If
        End If
    
    End Function
    
    '---------------------------------------------------------------------------------------
    ' Procedure : CercaVert
    ' Author    : Scossa
    ' Date      : 25/03/2015
    ' Purpose   : Ricerca sWath nel range Rng e restituisce il
    '             valore della cella spostata lCol rispetto alla
    '             cella dove il valore è stato trovato.
    '---------------------------------------------------------------------------------------
    '
    
    Public Function CercaVert( _
      ByVal vWath As Variant, _
      ByRef rng As Range, _
      ByVal nCol As Long, _
      Optional ByVal bPart As Boolean = True) As Variant
        
      Application.Volatile
      Dim rFound As Range
      Dim vToken As Variant
      
      
      vToken = Application.VLookup(vWath, rng, 1, --bPart)
      If Not IsError(vToken) Then
        Set rFound = rng.Find(vToken, After:=rng.Cells(rng.Rows.Count), _
            LookAt:=xlWhole, _
            SearchDirection:=xlNext)
            CercaVert = rFound.Offset(, nCol).value
      Else
        CercaVert = CVErr(Excel.xlErrNA)
      End If
    End Function






  • di scossa data: 26/03/2015 15:57:28

    cit. Vecchio Frac: "=CERCA.VERT("topolino";SCEGLI({1;2};F1:F6;D1:D6);2;0) "

    Tanto di cappello!!!!
    Bella soluzione, avevo intuito che SCEGLI() doveva entrare in gioco, ma non avevo proprio pensato di usarla così.
    Complimenti sinceri!

    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno.
    Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)



  • di scossa data: 26/03/2015 16:05:13

    Riguardo la soluzione CODICE, visto che non hai usato lo stesso numero di argomenti di CERCA.VERT(), allora propongo una variante al mio codice per evitare di farla "volatile" , con l'aggiunta di un parametro, visto che è di gran lunga meglio evitare le funzioni volatili se possibile.

    Il "trucco" è quello di passare alla UDF tutto l'intervallo di celle interessato, così come lo si passerebe a CERCA.VERT().
    In questo modo una variazione su qualsiasi cella dell'intervallo scatenerà il ricalcolo della UDF.


    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno.
    Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)



     
    '---------------------------------------------------------------------------------------
    ' Procedure : CercaVert2
    ' Author    : Scossa
    ' Date      : 25/03/2015
    ' Purpose   : Ricerca sWath nella colonna nWhere del range Rng e restituisce il
    '             valore della cella spostata lCol rispetto alla
    '             cella dove il valore è stato trovato.
    ' N.B.      : rng deve essere un range che comprenda sia la colonna di ricerca
    '             che quella di restituzione, come in CERCA.VERT()
    '---------------------------------------------------------------------------------------
    '
    Public Function CercaVert2( _
      ByVal vWath As Variant, _
      ByRef rng As Range, _
      ByVal nWhere As Long, _
      ByVal nCol As Long, _
      Optional ByVal bPart As Boolean = True) As Variant
        
      
      Dim rFound As Range
      Dim vToken As Variant
      
      Set rng = Intersect(rng, rng.Columns(nWhere))
      vToken = Application.VLookup(vWath, rng, 1, --bPart)
      If Not IsError(vToken) Then
        Set rFound = rng.Find(vToken, After:=rng.Cells(rng.Rows.Count), _
            LookAt:=xlWhole, _
            SearchDirection:=xlNext)
            CercaVert2 = rFound.Offset(, nCol).Value
      Else
        CercaVert2 = CVErr(Excel.xlErrNA)
      End If
    End Function
    
    



  • di Luca73 data: 26/03/2015 16:11:45

    Mi associ a scossa.
    Ecco come fare ad accostare due vettori a formare una matrice
    grazie.





  • di Vecchio Frac data: 26/03/2015 20:27:49

    Grazie a tutti voi.
    State onorando questo forum :)





  • di Mister_x (utente non iscritto) data: 27/03/2015 00:11:27

    ciao VF

    ho visto adesso che mi hai designato per proporre un nuovo esercizio,
    ti dico a priori che io non sono propio portato per proporre un qualche problema, in quanto nella mia vita di tecnico sono sempre stato quello, che il cliente chiedeva se era possibile, e io dovevo dare un parere, in riunione, se era fattibile la cosa e in che misura si poteva arrivare al pensiero del cliente. calcolando il materiele le macchine da utilizzare i tempi di occorrenza , e tutto quello inerente alla produzione di un test di campionatura da parte mia, prima di mandarlo in produzione di miglioni di pezzi
    quindi se qualcuno si propone per questo,dando un problema da risolvere,
    io come al solito, partecipando, vedro di risolvere il problema come ho sempre fatto

    PS ripeto che per noi si dovrebbe aspettare almeno il giorno dopo prima di intervenire con le nostre formule contorte

    ciao






  • di lepat (utente non iscritto) data: 27/03/2015 07:48:26

    la formula =CERCA.VERT (dato cercato; SCEGLI({1;2};colonna dove cercare;colonna da restituire);2;0)
    mi da errore ed evidenzia l'uno di {1;2} dicendo di modificare l'indice



  • di scossa data: 27/03/2015 08:11:21

    Dipende dalla versione di Excel: col 2010 sostituisci con {12}


    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno.
    Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)




  • di lepat (utente non iscritto) data: 27/03/2015 08:43:58

    Grazie, funziona, qual'è il significato di {12} ?



  • di Luca73 data: 27/03/2015 09:25:26

    Ciao
    una domanda anche io
    intuisco il funzionamento del vettore {1?2} (il ? significa i diversi segni di divisione colonne).
    Ritengo che il vettore in questione sia un vettore di una riga e due colonne dove la formula scegli sostituisce il valore 1 e 2 con i vettor1 (1 colonna n righe) creando cos' una matrice di due colonne e n righe che viene usata come matrice di ricerca per Cerca.vert.

    La mia domanda riguarda il fatto che per farla funzionare io ho dovuto inserire la virgola (,) non il puntoevirgola (;) nè il backslash ()?

    io uso Microsoft office professional plus 10 e alla formula =AMBIENTE.INFO("VERSIONE") mi dice 14.0

    per scrivere la matrice
    1 2
    5 A
    devo inserire la formula ={1,25,"A"}

    perche?
    Ciao e grazie
    Luca





  • di marinoernestoch data: 27/03/2015 12:20:03

    Salve a tutti.
    Probabilmente sono rincitrullito, ma , a memoria, mi pare che la cerca.vert non accetti il valore di risposta fuori dal range della tabella. invece, la funzione CERCA potrebbe soddisfare l'esigenza, ma c'è un ma: la colonna con i valori da ricercare deve essere in ordine, e questo non mi pare il caso.
    Ad un problema simile, tempo addietro, ho usato la formula:
    =INDICE(A2:F6;CONFRONTA(F8;F2:F6;0);1)
    dove i dati della tabella vanno da A2 ad F6 (il titolo è sopra, in riga 1), il valore da ricercare è in F8 e il valore da ottenere è in colonna A.
    Non so se come soluzione è soddisfacente



  • di jacks (utente non iscritto) data: 27/03/2015 14:21:28

    Ciao a tutti,
    ripropongo una mia soluzone piuttosto artigianale, ma penso che funzioni.
    non sto a spiegare come funziona, però dico che :
    a) il data base si puo' allargare all'infinito (fino a 9000 righe) .
    b) ogni volta che si inserisce un nuovo record, è necessario cliccare sul pulsante "consolida dati modificati", per avere il filtro univoco nella colonna"o"
    c) scegliere quindi la ditta.
    d) si possono estrarre tutti i campi dei record interessati.
    la soluzione non è tecnicamente perfetta, ma credo che funzioni .
    ciao



  • di jacks (utente non iscritto) data: 27/03/2015 14:34:18

    il file da vedere è "copia vecchio frac OK 1 jacks" il foglio è "activex"
    scusate



  • di Vecchio Frac data: 28/03/2015 12:35:03

    Visto che Mister_x non se la sente di proporre un quesito nuovo, c'è qualcuno che ha voglia di farlo? o anche più d'uno? ^_^ scossa, per esempio, vuoi rompere il ghiaccio?





  • di Vecchio Frac data: 28/03/2015 12:36:23

    Per chi ha problemi con i separatori delle matrici nelle formule: mandate una mail di reclamo a Microsoft che ha cambiato le carte in tavola sia tra una versione l'altra che tra una versione localizzata e l'altra :)





  • di scossa data: 29/03/2015 00:23:25

    @V.F.: accetto volentieri l'invito, ma poiché martedì non credo di avere tempo per pubblicarlo, l'esercizio lo proporrò domani.
    Una cosa semplice semplice.
    Ovviamente l'onere del giudizio resta tuo.


    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno.
    Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)