ApplicationWorksheetFunctionVLookup



  • Application.WorksheetFunction.VLookup()
    di Thomas (utente non iscritto) data: 17/01/2013 23:44:51

    salve volevo chiedervi perche il codice che ho creato non funziona. probabilmente è un errore che a molti di voi sembrerà elementare ma per me che sono le primissime volte che uso vba è un grande problema. praticamente sto cercando di fare una userform che mi permetta di modificare i dati contenuti in una tabella. quindi ho inserito una listbox contenente tutti i nomi che si aggiorna se ne aggiungo alla tabella, 3 textbox una che mi riscrive il nome che seleziono dalla listbox e le altre due che mi scrivono due valori, uno per ciascuna, anch'essi contenuti nella tabella ma nelle colonne affianco. ho inserito anche 3 optionbutton che mi dicono quale fra i valori 1, 2 e 3 è attribuito a quel nome. fin qui tutto bene il problema viene ora. in pratica ho aggiunto anche un bottone e volevo che cambiando i valori contenuti nelle textbox e cambianto la scelta fra i 3 optionbutton mi aggiornasse la tabella di excel.
    n.b. le textbox le ho rinominate in nome, prezzo, spessore mentre i 3 optionbutton li ho rinominati in unita 1,unita 2 e unita 3 e sono sicuro che non è questo il problema
     
    ' Questa è la parte che ho descritto per prima e funziona '
    Private Sub ListBox1_Click()
    Sheets("Elenco materiali").Select
    UserForm1.nome.Text = Application.WorksheetFunction.VLookup(ListBox1.Text, Range("C:F"), 1, False)
    UserForm1.prezzo.Text = Application.WorksheetFunction.VLookup(ListBox1.Text, Range("C:F"), 2, False)
    UserForm1.spessore.Text = Application.WorksheetFunction.VLookup(ListBox1.Text, Range("C:F"), 4, False)
    
    If Application.WorksheetFunction.VLookup(ListBox1.Text, Range("C:F"), 3, False) = 1 Then
    unita1.Value = True
    ElseIf Application.WorksheetFunction.VLookup(ListBox1.Text, Range("C:F"), 3, False) = 2 Then
    unita2.Value = True
    ElseIf Application.WorksheetFunction.VLookup(ListBox1.Text, Range("C:F"), 3, False) = 3 Then
    unita3.Value = True
    End If
    Sheets("Preventivo").Select
    
    End Sub
    
    ' Da qui iniziano i problemi... '
    Private Sub CommandButton1_Click()
    Sheets("Elenco materiali").Select
    
    'All'azione corrispondente alla riga qui sotto mi dice Errore Run-Time 424: Necessario Oggetto credo che il problema sia la parte prima dell'uguale ma non ne sono sicuro'
    Application.WorksheetFunction.VLookup(ListBox1.Text, Range("C:F"), 1, False).Value = nome.Value 
    Application.WorksheetFunction.VLookup(ListBox1.Text, Range("C:F"), 2, False).Value = prezzo.Value
    Application.WorksheetFunction.VLookup(ListBox1.Text, Range("C:F"), 4, False).Value = spessore.Value
    
    If unita1.Value = True Then
    Application.WorksheetFunction.VLookup(ListBox1.Text, Range("C:F"), 3, False).Value = "1"
    ElseIf unita2.Value = True Then
    Application.WorksheetFunction.VLookup(ListBox1.Text, Range("C:F"), 3, False).Value = "2"
    ElseIf unita3.Value = True Then
    Application.WorksheetFunction.VLookup(ListBox1.Text, Range("C:F"), 3, False).Value = "3"
    End If
    Sheets("Preventivo").Select
    
    
    End Sub



  • di HarryBosch data: 18/01/2013 01:27:23

    Ciao Thomas e benvenuto sul Forum
    magari domani analizzo meglio il codice, oppure interviene prima qualcun'altro ad aiutarti, che ora ho la vista annebbiata ^_^

    Intanto un consiglio personale: quando rinomini gli oggetti, nel tuo caso le textbox e gli Optionbutton, è conveniente iniziare il nome con un attributo specifico, che richiami l'oggetto stesso.
    Ad esempio per le textbox, potresti nominarle:
    txtNome, txtPrezzo e txtSpessore
    mentre gli Option:
    optUnita1, optUnita2 e optUnita3
    ciò facilita notevolmente la lettura del codice, non solo per gli altri utenti ma anche per te stesso se riprendi in mano il lavoro dopo parecchio tempo. Soprattutto quando gli elementi inseriti diventano molti.

    Come ti dicevo non ho ancora guardato bene il codice ma a prima vista non vedo il caricamento della listbox. Utilizzi un evento click sul tale lista, ma è ancora vuota... manca una parte?

    E nel button_click sicuramente ti esce un errore perché cerchi di assegnare il valore di una variabile ad una funzione che ti restituisce già un valore in se. Al massimo si può controllare se i due valori corrispondono con un IF ... = ... then





  • di Thomas (utente non iscritto) data: 18/01/2013 07:26:29

    ciao harry e grazie per la risposta. confermo che non ho scritto una parte di codice ma solo perche la prima parte funziona gia e l'ho inserita solo perche pensavo potesse facilitare la lettura del codice sotto.
    appena accendo il computer posto la prima parte caso mai perche ora sono con il tablet e non ricordo a memoria il codice.



  • di Vecchio Frac data: 18/01/2013 11:02:12

    cit. " quando rinomini gli oggetti, nel tuo caso le textbox e gli Optionbutton, è conveniente iniziare il nome con un attributo specifico, che richiami l'oggetto stesso "
    ---> Sì, e questo è quanto consiglia anche la Guida di Visual Basic, è una convenzione diffusa e universalmente accettata in questo ambiente. I prefissi sono standardizzati ormai. Ecco uno dei link dove trovare un utile riferimento:
    support.microsoft.com/kb/110264/it








  • di Vecchio Frac data: 18/01/2013 11:10:43

    Application.WorksheetFunction.VLookup(ListBox1.Text, Range("C:F"), 1, False).Value = nome.Value

    1) VLookUp non ha una proprietà Value
    2) VLookUp restituisce un valore, non si può usare per assegnargliene uno
    3) ListBox1 e nome non sono definiti (sei in uno userform?)

    Il concetto da seguire è:
    - cerco il valore nel range (C:F)
    - se lo trovo recupero il riferimento di cella
    - imposto il valore di tale cella al valore desiderato

    set c = Vlookup ecc. (o meglio Find!!)
    c = nome





  • di Thomas (utente non iscritto) data: 18/01/2013 15:09:48

    ok grazie ora provo. ma la funzione find come si usa?



  • di Vecchio Frac data: 18/01/2013 15:29:43

    set c = [A:A].Find("valore da trovare", lookin:=xlValues)
    restituisce un oggetto range se trova una cella col valore da cercare, altrimenti un oggetto impostato a Nothing:
    if not c is nothing then
    'valore trovato
    else
    'valore non trovato
    end if





  • di Thomas (utente non iscritto) data: 18/01/2013 15:32:04

    mi da ancora problemi... credo sia perche non so cosa mettere a: Dim c As...



  • di Vecchio Frac data: 18/01/2013 15:49:22

    Find restituisce un oggetto Range.
    L'esempio che segue cerca la parola "pippo" in colonna A. Se la trova evidenzia la cella trovata, altrimenti si posiziona in A1. Nota che cerca solo la prima occorrenza della parola "pippo", non le successive (per trovare i duplicati ad esempio c'è bisogno di un ciclo do ... loop o equivalenti).


     
    sub test()
    Dim c as range
        set c = [A:A].Find("pippo", lookin:=xlValues) 
        if not c is nothing then 
             c.select
        else 
            [A1].select
        end if
    end sub






  • di Vecchio Frac data: 18/01/2013 15:50:52

    cit. " non so cosa mettere a: Dim c As... "
    ---> quando hai dubbi come questo, metti Variant: dim c as variant
    Non è la soluzione migliore ma lasci a VBA l'onere di indovinare il tipo di dato giusto. Lui si occuperà di assegnare alla variabile il tipo Range. Con evidente spreco di memoria e cicli di esecuzione, certo, ma almeno non si ferma :)





  • di HarryBosch data: 18/01/2013 20:39:16

    Non ho ancora capito quello che vorresti fare. Ti va di spiegare a parole il risultato che vorresti ottenere?
    Perché da quanto capisco, sembra che in base alla riga della Listbox selezionata, si ricerchi il valore sul foglio e se corrisponde a un determinato valore (1,2,3) uno degli OptionButton si attivano ?!
    E poi nella seconda fai il contrario...

    Puoi anche allegare un file di esempio se ti va, con dati fittizi. Trovi l'apposito pulsante in ogni discussione.



  • di Thomas (utente non iscritto) data: 18/01/2013 21:11:18

    ecco fatto ho apportato le modifiche ma non ho ancora rinominato le textbox come mi avevate suggerito scusate. in ogni caso ora è funzionante! :)



  • di HarryBosch data: 19/01/2013 11:43:56

    Ciao Thomas,
    mi sono permesso di metter mano al tuo lavoro, per offrirti un punto di vista diverso: puoi fare tutte le operazioni senza mai spostarti dal foglio attivo, che è quello che raccoglie i dati.
    Ricordati che non serve quasi mai selezionare il range interessato, sia esso un foglio, un intervallo o una cella specifica.
    Si riesce praticamente sempre a lavorare con l'intervallo in questione senza utilizzare il select, ma assegnando direttamente l'azione che si vuole intraprendere.

    Inoltre hai fatto una cosa concettualmente giustissima: hai determinato l'intervallo dei materiali in maniera dinamica, utilizzando lo strumento Dati sul foglio. Solo che poi non sfrutti a dovere tale intervallo! Nel senso che ogni routine che hai scritto, hai sempre richiamato il foglio "Elenco materiali" e cercato il range in questione; non serve, perché il range("Materiali") che hai impostato nei dati, fa già tutto questo: è lui che si preoccupa di recuperare i dati da un foglio specifico e da una colonna specifica.
    Quindi, quando lo richiami con Range("Materiali"), ti trovi già nella posizione memorizzata.

    Ti ho inserito anche diversi commenti; eventualmente chiedi pure che il Forum è qua apposta ^_^
    Il file allegato è Preventivo modifiche.rar



  • di Thomas (utente non iscritto) data: 20/01/2013 15:35:00

    grazie harry nin sapevo si potesse fare perche é la primissima volta che uso vba pensa che ho saputo della sua esistenza mercoledi adesso mi studiero il codice cosi imparo ad usarlo meglio se c'e qualche cosa che non capisco del codice lo chiedo nel forum.



  • di Thomas (utente non iscritto) data: 21/01/2013 16:38:56

    scusate se riapro ma avrei delle domande in merito alle modifiche di harry o meglio in base a parti di codice che avevo scritto suggeritemi da altre persone di cui pero non conosco bene la funzione ad esempio cosa si intende con LookAt:=xlWhole della funzione find? in piu mi chiedevo se esiste una lista o se qualcuno mi puo spiegare rapidamente la funzione delle proprieta tipo value text value 2 ecc.



  • di Thomas (utente non iscritto) data: 21/01/2013 16:42:27

    inoltre ho appena notato che nei msgbox hai messo funzioni tipo vbCritical Or vbDefaultButton1, vbOKCancel Or vbQuestion cosa significano?



  • di Thomas (utente non iscritto) data: 21/01/2013 16:48:57

    che significa [g2] nella seguente formula? scusate se faccio troppe domande o se sono domande stupide ma se riesco a capire tutto mi sara piu facile fare altri programmi in futuro
     
    Sub inserisciriga()
    ' inserisciriga Macro
        Sheets("Foglio1").[A1:T1].Copy
        [g2].End(xlDown).Offset(1, -6).Insert Shift:=xlDown
        [g2].End(xlDown).Offset(0, -6).Select



  • di Vecchio Frac data: 21/01/2013 18:13:24

    cit. " cosa si intende con LookAt:=xlWhole della funzione find "
    ---> LookAt è un parametro (un'attributo) del metodo Find e lo istruisce su come impostare la ricerca del dato richiesto, se basta che si trovi nella cella anche solo una parte o se deve essere trovata la corrispondenza intera. Può avere il valore di una delle seguenti costanti: xlWhole o xlPart. Con il primo, se cerchi "arco", verranno restituite le celle che contengono "toro". Con xlPart invece verranno trovate le celle che contengono questa parola, quindi anche "marco" e "barcone".

    cit. " se esiste una lista o se qualcuno mi puo spiegare rapidamente la funzione delle proprietà tipo value text value 2"
    ---> ogni oggetto in Excel espone metodi e proprietà che sono accessibili dalla Guida (entra nell'editor di codice con Alt-F11, attiva la finestra Immediata con Ctrl-G, scrivi la parola su cui vuoi informazioni e premi il tasto F1, quindi naviga nella Guida). Ulteriori informazioni le trovi tramite Google: comincia a scrivere VBA e poi quello che cerchi e buona lettura.

    cit." nei msgbox hai messo funzioni tipo vbCritical Or vbDefaultButton1, vbOKCancel Or vbQuestion "
    ---> non sono "funzioni" ma "costanti" (vedi che cominciano con vb? è una furbizia per individuare le costanti del linguaggio) e servono a visualizzare l'icona dello stop (vbCritical) o del punto interrogativo (vbQuestion) insieme a vari tipi di pulsanti tipici delle message box: il pulsante Ok, i due pulsanti Ok e Cancel. Vai in finestra Immediata, digita msgbox e premi F1 per i dettagli.

    cit. " che significa [g2] nella seguente formula. [g2].End(xlDown).Offset(1, -6).Insert Shift:=xlDown "
    ---> è la tipica notazione a parentesi quadre che in Excel sostituisce la valutazione di un'espressione, e nel caso specifico lo si usa al posto di Range("..."). Quindi scrivere [G2] o Range("G2") è equivalente. Io lo trovo più elegante e conciso. Tra prentesi, puoi accedere a tutte le funzioni del foglio scrivendole tra quadre: [COUNTA(A:A)] equivale a scrivere in una cella =CONTA.VALORI(A:A), solo che lo usi direttamente in VBA senza passare dal Via, ritirando le ventimila lire :)

    cit. " scusate se faccio troppe domande o se sono domande stupide ma se riesco a capire tutto mi sara piu facile fare altri programmi in futuro "
    ---> Non ci son domande stupide ma solo risposte stupide, e sei caldamente invitato a fare qui tutte le domande che ti vengono in mente, e anche a cercare di rispondere ai quesiti degli altri. Solo così questo gruppo crescerà insieme.






  • di Vecchio Frac data: 21/01/2013 18:14:55

    cit. " Con il primo, se cerchi "arco", verranno restituite le celle che contengono "toro"
    ---> Ridiamo insieme della mia senilità :)
    Errata corrige:
    Con il primo, se cerchi "toro", verranno restituite le celle che contengono "toro"

    Scusate ^_^





  • di Thomas (utente non iscritto) data: 21/01/2013 18:39:59

    Grazie per aver avuto la pazienza di rispondere a tutte le mie domande