gestione errori funzioni personali



  • gestione errori funzioni personali
    di slevin19 (utente non iscritto) data: 22/07/2013 10:38:20

    Salve a tutti!!
    scusate l'assenza ma visti gli impegni lavorativi ho avuto poco tempo per "giocare" con visual basic...:(

    In questi ultimi giorni ho fatto alcuni passi avanti che probabilmente cambieranno il mio approccio ad excel...ho infatti scoperto la possibilità di scrivere funzioni in VBA e di poterle richiamare nel foglio excel! un piccolo passo per l'uomo, un grande passo per slevin19!! XD Infatti da ora quando avrò bisogno di una formula in excel potrò scriverla personalmente definendone anche i parametri!!

    Vabbe dopo questa piccola prefazione per condividere i miei progressi, avrei bisogno di un vostro aiuto proprio con l'argomento funzioni:

    ho scritto la funzione di cui ho riportato il codice sotto: tutto ok funziona quando i parametri che ho scelto sono numeri; tuttavia se i parametri sono uguali a "" la funzione mi rimanda l'errore #VALORE!

    allora ho inserito la condizione if che ho scritto sotto i trattini e mi risolve il problema solo se il primo parametro è uguale a "" e il secondo ad un numero (in pratica solo se è verificata la prima condizione dell'if e non le altre due)...

    ho già provato ad invertire le condizioni e a utilizzare ElseIf ma niente...

    Ho due domande allora :

    1) posso gestire l'errore #VALORE! e porre che se la funzione lo rimanda invece di scrivere #VALORE! mi rimanda goal = "" ??

    2) se vi risulta più facile, sapete aiutarmi a capire perchè la funzione non verifica tutte le condizioni dell'if che ho inserito??

    Spero si riesca a capire il problema e soprattutto le domande! :D
    Grazie a tutti per la disponibilità
     
    Function goal(punteggiosquadraselezionata, punteggioavversario)
    ' Funzione per calcolare il numero di goal di una squadra in base al punteggio ottenuto
    
    ' Dichiarazione delle variabili
    
    Dim goalsquadra1 As Variant
    Dim goalsquadra2 As Variant
    Dim intervallodifascia
        intervallodifascia = punteggioavversario + 3.5
        
    ' Inizio della funzione
        goalsquadra1 = Application.WorksheetFunction.VLookup(punteggiosquadraselezionata, Sheets("Tabella Matrice Goal").[C10:D19], 2, True)
        goalsquadra2 = Application.WorksheetFunction.VLookup(punteggioavversario, Sheets("Tabella Matrice Goal").[C10:D20], 2, True)
    
    ' Intervallo di fascia in caso di pareggio
    
            If goalsquadra1 = goalsquadra2 And punteggiosquadraselezionata >= punteggioavversario + intervallodifascia Then
            
                    goalsquadra1 = goalsquadra2 + 1
            Else
                    goalsquadra1 = goalsquadra1
            End If
            
    ' Risultato della funzione
    
        goal = goalsquadra1
        
        
    End Function
    
    -----------------------------------------------------------------------------
    
        If punteggiosquadraselezionata = "" Or punteggioavversario = "" Or punteggiosquadraselezionata = punteggioavversario = "" Then
            
            goal = ""
            
        Else



  • di HarryBosch data: 22/07/2013 11:23:56

    Non riesco a capire il tipo di variabili impostate. anche perché nell'intestazione della funzione non sono indicate e nelle dichiarazioni sono impostate come Variant.
    Perlomeno io non so se "punteggiosquadraselezionata" è un numero (relativo a punteggio) o una stringa (relativa a squadra selezionata).

    Puoi allegare un file di esempio così ci rendiamo conto^ :)



  • di Vecchio Frac data: 22/07/2013 11:37:42

    Ciao slevin19... complimenti per i progressi e per aver affrontato il problema del passaggio dei parametri in una UDF: controllare i parametri passati è sempre doveroso, sia se è qualcun altro che utilizza la tua funzione, sia se tu stesso, a distanza di tempo, non ti ricordi più il tipo e il valore dei parametri da passare. Blindare la funzione, come si dice in gergo, è il modo migliore per assicurare il corretto funzionamento del programma.
    Ti verrà utile anche specificare il tipo di lavoro restituito dalla Function. Intercettare gli errori e restituire un valore di un unico tipo è l'unica strada che ti permette sia la manutenzione che il corretto funzionamento del tuo codice.

    La Function goal() restituisce un numero? in caso di errore fatti ritornare -1.
    ESEMPIO:
    Function goal(punteggiosquadraselezionata, punteggioavversario) as integer
    ...
    if iserror(goalsquadra1) then
    goal = -1
    else
    goal = goalsquadra1
    end if


    Nel merito della domanda 2, posta un piccolo file di esempio con alcuni dati in modo che si possa testare la condizione.
     
     






  • di Vecchio Frac data: 22/07/2013 11:38:36

    Io e Harry spesso ci inseguiamo sempre ma convergiamo... (soprattutto se ci metto un po' a comporre messaggi lento come sono ^_^ )





  • di slevin19 data: 22/07/2013 12:56:30

    Meno male che non divergete, altrimenti sarebbe un casino!! XD

    Bene allora un passo alla volta:

    1) grazie al vostro consiglio sto curando con più attenzione i tipi di variabili e parametri.
    Fino ad ora utilizzavo solo integer con i numeri interi e variant con tutti gli altri, pensando non fosse rilevante; considerando però il consiglio di VecchioFrac e le difficoltà incontrate da Harry nell'interpretare il codice che ho scritto, ho studiato un pò i tipi di variabili e ho usato il Single con goalsquadr1 e goalsquadra2 ma ho dovuto lasciare Variant per i parametri perchè tecnicamente sono punteggio e quindi numeri decimali, però li considero anche come stringhe quando la cella è vuota quindi uguali a ""

    2) ho allegato un file di prova: nel codice non badate alle prime routine che ho utilizzato come prova per capire il meccanismo delle funzioni e i valori di alcune variabili, ma considerate solo la parte di codice relativa alla funzione GOAL.
    Ho inserito la condizione che vorrei venisse verificata prima di calcolare il punteggio e come potete vedere nel foglio di lavoro la cella C14 è vuota e quindi rispecchia la condizione, mentre la cella F14 rimanda l'errore #VALORE! e questo è il mio problema

    3) VecchioFrac ho provato con iserror come hai detto, però purtroppo non ha funzionato :(




  • di slevin19 data: 22/07/2013 13:40:34

    signori ho risolto!
    una soluzione un pò macchinosa però funziona!!
    ora vado a pranzo e quando torno la inserisco come mi dite cosa ne pensate!!

    A dopo XD



  • di slevin19 data: 22/07/2013 14:31:29

    Allora eccomi qua...come ho detto prima sono riuscito a risolvere il problema

    in pratica ho costruito un'altra funzione di tipo Booleana (condizionegoal) che verifica la condizione necessaria per il calcolo del punteggio...in seguito ho costruito una terza funzione (provagoal) che corrisponde all'unione di questa nuova con la precedente ed ora effettivamente se una delle due condizioni è falsa la cella rimane vuota

    Di seguito ho inserito il codice (che ora va pulito nei nomi delle funzioni e delle variabili che cambierò con altri più semplici ed intuibili)...che ne pensate può essere una buona soluzione o utilizzare tre funzioni è troppo macchinoso??
     
    Function goal(punteggiosquadraselezionata As Variant, punteggioavversario As Variant) As Variant
    ' Funzione per calcolare il numero di goal di una squadra in base al punteggio ottenuto
    
    ' Dichiarazione delle variabili
    
    Dim goalsquadra1 As Single
    Dim goalsquadra2 As Single
    Dim intervallodifascia
        intervallodifascia = punteggioavversario + 3.5
           
    ' Inizio della funzione
        goalsquadra1 = Application.WorksheetFunction.VLookup(punteggiosquadraselezionata, Sheets("Tabella Matrice Goal").[C10:D19], 2, True)
        goalsquadra2 = Application.WorksheetFunction.VLookup(punteggioavversario, Sheets("Tabella Matrice Goal").[C10:D20], 2, True)
        
    ' Intervallo di fascia in caso di pareggio
    
            If goalsquadra1 = goalsquadra2 And punteggiosquadraselezionata >= punteggioavversario + intervallodifascia Then
            
                    goalsquadra1 = goalsquadra2 + 1
            Else
                    goalsquadra1 = goalsquadra1
                    
            End If  'chiusura if dell'intervallo di fascia
            
    ' Risultato della funzione
    
        goal = goalsquadra1
          
        
    End Function
    
    -----------------------------------------------------------------------------
    
    Function condizionegoal(valore As Variant) As Boolean
    
    
        If valore = "" Then
    
            condizionegoal = True
        Else
        
            condizionegoal = False
        End If
    
    End Function
    
    -----------------------------------------------------------------------------
    
    Function provagoal(parametro1, parametro2) As Variant
    
    If condizionegoal(parametro1) = True Or condizionegoal(parametro2) = True Then
    
        provagoal = ""
        
    Else
    
        provagoal = goal(parametro1, parametro2)
    
    End If
    
    
    End Function