Macro di ricerca valori



  • Macro di ricerca valori
    di Spinn (utente non iscritto) data: 17/02/2013 18:26:33

    Ciao raga. Mi sono annegato in un bicchiere d'acqua per un programmino elementare di base.

    1) Inserisco due contatori: “x” per la colonna C e “y” per la colonna A;
    2) parto dalla cella C1;
    3) dovrei spazzolare tutte le celle di colonna A finchè non ne trovo una col contenuto uguale al contenuto della cella C1;
    4) se non lo trovo scendo in cella A2 per andare a cercare il contenuto uguale a C1;
    5) arrivo in fondo alla colonna A e la cella uguale non la trovo:
    6) contrassegno di giallo la cella C1 quale segno di non avere trovato la gemella nella colonna A:
    7) ritorno al punto 3) e faccio la stessa cosa per la cella C2):
    8) spazzolo la colonna A e trovo la cella A9 col contenuto uguale a C2;
    9) prendo il contenuto di D2 e lo porto in B9;
    10) contrassegno di rosso la cella A9 per indicare che l’ho trovata:
    11) ritorno al punto 2) e riparto dalla cella C3:
    12) e così via fino alla fine.

    Dunque si lavora su quattro colonne (A,B,C,D). Il termine di confronto delle celle di colonna A sta nel contenuto delle celle di colonna C.
    In colonna A esiste un solo corrispondente di una cella di colonna C. Voglio dire che non ci sono contenuti nelle colonne B e D che si ripetono.

     
    Private Sub CommandButton1_Click()
    For x = 1 To 40
    Next
    For y = 1 To 40
    Next
    If Cells(x, "c") = Cells(x, "a") Then
    Cells(x, "b") = Cells(x, "d")
    Selection.Interior.Color Index.Range(x, "a")
    Cells(y, "b") = Cells(x, "b")
    End If
    End Sub



  • di Mabolsie (utente non iscritto) data: 17/02/2013 20:19:36

    Prova così, ciao Max
     
    Private Sub CommandButton1_Click()
    For x = 1 To 40
    If Cells(x, "c") = Cells(x, "a") Then
    Cells(x, "b") = Cells(x, "d")
    Selection.Interior.Color Index.Range(x, "a")
    Next
    For y = 1 To 40
    Cells(y, "b") = Cells(x, "b")
    Next
    End If
    End Sub
    



  • di Spinn (utente non iscritto) data: 17/02/2013 20:43:47

    Errore di compilazione. For senza Next



  • di Vecchio Frac data: 17/02/2013 20:54:28

    Eh già... leggete bene il codice: il primo For x è esterno all'If che però non viene chiuso, e c'è un End If finale che manda in confusione l'interprete.
    Comunque l'algoritmo di Spinn è molto chiaro, basta solo tradurlo correttamente in codice (forza Mabolsie, non stai rispettando le indicazioni fornite... riprova ^_^).





  • di mabolsie (utente non iscritto) data: 17/02/2013 21:07:49

    Desisto !!



  • di Vecchio Frac data: 17/02/2013 21:09:14

    Mai arrendersi ^_^
    Io ho provato così, mi sembra che funzioni.
    Naturalmente il range [C1:C10] va impostato correttamente.
    Spinn ci dirà se il range è dinamico (non è nota a priori la sua estensione) o fisso; nel primo caso basterà qualche accorgimento per individuare il range giusto da scandagliare.
     
    Option Explicit
    
    Sub cerca_trova()
    Dim c As Range, cella As Range
        
        For Each cella In [C1:C10]
            Set c = [A:A].Find(what:=cella, LookIn:=xlValues)
            If c Is Nothing Then
                cella.Interior.ColorIndex = 36   'giallo chiaro
            Else
                c.Offset(, 1) = cella.Offset(, 1)
                c.Interior.ColorIndex = 3   'rosso
            End If
        Next
    End Sub






  • di Spinn (utente non iscritto) data: 17/02/2013 21:51:40

    A Vecchio Frac. Ciò che hai scritto mi sembra arabo perchè non c'ho capito niente. Comunque la provo poi ti so dire. Col Range ("C1:C10") non capisco cosa vuoi dirmi. Grazie comunque. Ciao



  • di Vecchio Frac data: 18/02/2013 09:44:44

    @Spinn
    Ho solo interpretato il tuo ottimo pseudocodice in istruzioni VBA.

    Viene scansionato il range C1:C10 cella per cella e se viene trovata una corrispondenza con quanto c'è in colonna A tinge la cella di rosso e riporta nella cella a fianco il valore della cella di confronto di colonna C. Se non viene trovata la corrispondenza, la cella di colonna C viene tinta di giallo chiaro.

    Quando farai la prova e incollerai questo codice nel tuo file, dovrai cambiare questo riferimento scrivendo il range interessato del progetto reale, questo è solo un esempio. Dal tuo post iniziale sembra che le celle interessate siano 40, ma questo ancora non l'hai detto, nè hai detto se il range in colonna C è predeterminato o variabile.




  • Macro di ricerca valori
    di Dpinn (utente non iscritto) data: 19/02/2013 10:09:33

    Dear Vecchio Frac,
    il tuo programmino funziona! Per farlo lavorare anche sulla riga 40 ho però dovuto modificare il Range (C1:C41) e comunque sulla riga 1 non lavora e non so come farglielo fare.
    Hai stravolto la mia impostazione di usare due contatori per cui a livello didattico non ho imparato come avrei dovuto procedere. Sono sul sito per imparare perché, come hai notato, sono ancora all’età della pietra e se tu usi il bronzo o il ferro io non mi evolvo. Per cui potresti tu gentilmente sviluppare la soluzione partendo dalla mia impostazione? Non possiedo testi di sintassi sul VBA (di sviluppo sì) per cui se cui tu usi l’istruzione “Dim” capisco solo che funziona, ma non il perché. Thank you. Bye



  • di Vecchio Frac data: 19/02/2013 10:36:35

    Va bene. Ho capito la tua esigenza.
    Finalmente uno che non vuole il pesce, vuole imparare a pescare ^_^, bravo.
    Appena posso mi dedico anche a te.
    Il problema della prima riga è perchè Find purtroppo non tiene conto della cella di partenza. Risolveremo anche questo ;)





  • di Vecchio Frac data: 19/02/2013 21:41:19

    Eco qui due codici a confronto, quello che ti ho postato e uno nuovo, diverso dal mio ma più vicino al tuo, che usa due contatori di interi per scandire le colonne A e C. Entrambi i codici sono ampiamente commentati.
    Buona lettura :)
     
    'versione breve - la puoi inserire in un modulo e lanciarla con Alt-F8
    Option Explicit
    
    Sub cerca_trova()
    'dichiaro il nome e il tipo delle variabili in gioco
    Dim c As Range      'contiene la cella di colonna A se trovata
    Dim cella As Range  'variabile contatore di tipo range (per scorrere la colonna C)
        
        'imposto un ciclo nelle celle da C1 a C40
        For Each cella In [C1:C40]
            'viene cercata (Find) in colonna A la cella corrente del ciclo
            'la variabile "c" viene impostata diversamente se la cella viene trovata
            Set c = [A:A].Find(what:=cella, LookIn:=xlValues)
            'se "c" non risulta valorizzata, la corrispondenza non è stata trovata
            If c Is Nothing Then
                '...quindi la cella attiva viene tinta di giallo chiaro
                cella.Interior.ColorIndex = 36   'giallo chiaro
            Else
                '...altrimenti la cella che si trova una colonna a destra rispetto alla
                'cella di colonna A che è stata trovata uguale alla cella corrente
                'in colonna C (A --> B), assume il valore della cella che si trova una colonna a
                'destra rispetto alla cella corrente (C --> D)
                c.Offset(, 1) = cella.Offset(, 1)
                '...e il suo interno viene tinto di rosso
                c.Interior.ColorIndex = 3   'rosso
            End If
        'proseguimento della scansione del range C1:C40
        Next
    End Sub
    
    
    'versione lunga - se la associ a un command button, va inserita nella zona codice del foglio
    'in cui si trova il command button
    'la direttiva che segue è importante, meglio esplicitarla sempre
    Option Explicit
    
    Private Sub CommandButton1_Click()
    'dichiaro il nome e il tipo delle variabili in gioco
    Dim x As Integer    'identifica la riga corrente della colonna C
    Dim y As Integer    'identifica la riga corrente della colonna A
    Dim bFound As Boolean   'indica se è stata trovata una corrispondenza in C
    
        'avvio un ciclo dalla riga 1 alla riga 40 per la colonna C
        For x = 1 To 40
            'presumo che non ci sia una corrispondenza tra A e C
            bFound = False
            'avvio un secondo ciclo per le righe da 1 a 40 della colonna A
            'così confronto ogni cella di colonna C con le celle di col. A
            For y = 1 To 40
                'se la riga x di colonna C corrisponde alla y-esima di col. A...
                If Cells(x, "C") = Cells(y, "A") Then
                    '...nella y-esima riga di colonna B scrivo il valore
                    'della x-esima riga di colonna D...
                    Cells(y, "B") = Cells(x, "D")
                    '...e la cella attuale di colonna A diventa rossa
                    Cells(y, "A").Interior.ColorIndex = 3   'rosso
                    'mi tengo segnato che ho trovato una corrispondenza
                    bFound = True
                End If
            'proseguo il ciclo y fino ad esaurire le celle di colonna A
            Next y
            'al termine delle celle di colonna A, s enon è stata trovata
            'una corrispondenza, la relativa cella x-esima di colonna C
            'viene tinta di giallo chiaro
            If Not bFound Then Cells(x, "C").Interior.ColorIndex = 36  'giallo chiaro
        'proseguo il ciclo x fino ad esaurire le celle di colonna C
        Next x
        'messaggio conclusivo
        MsgBox "Fatto!"
    End Sub
    





  • Macro di ricerca valori
    di Spinn (utente non iscritto) data: 19/02/2013 22:01:58

    Me lo stampo e me lo leggo. Poi lo provo. Grazie mille.


  • Macro di ricerca valori
    di Spinn (utente non iscritto) data: 20/02/2013 16:15:26

    Per Vecchio Frac. Le versione lunga funziona mentre la versione breve non funziona più. La versione breve aveva anche il problema del Find che sul rigo 1 non funziona. Comunque grazie.



  • di Vecchio Frac data: 20/02/2013 17:37:41

    Davvero curioso, per due motivi:
    - dalle mie prove la mia versione "breve" funziona bene anche con la prima cella;
    - non capisco perchè comunque non funziona più, hai cambiato qualche parametro? ricevi qualche tipo di errore? se i dati risiedono in un range diverso, hai aggiornato il range di riferimento?

    Comunque l'importante è la valenza didattica dell'esempio.
    Almeno per darti l'idea che possono esistere approcci diversi e quindi soluzioni diverse... fare in modo che poi tutto funzioni è solo questione di adattare il concetto al reale in modo comprensibile ad Excel :)




  • Macro di ricerca valori
    di Spinn (utente non iscritto) data: 20/02/2013 20:16:26

    Nell'ultima versione breve rispetto alla prima hai cambiato "Dim c As Range 'contiene la cella di colonna A se trovata
    Dim cella As Range ".
    Non ricevo messaggi d'errore, non ho cambiato i parametri e i dati sono sempre lì. Comunque l'importante è cominciare a lavorare, studiare ed essere tenaci. Ciao e grazie.