Somma se in VBA



  • Somma se in VBA
    di Mangusta (utente non iscritto) data: 31/12/2012 15:09:44

    Questo post è a puro scopo didattico e direi por masochisti:

    se volessi tradurre in codice la sunzione sumif senza utilizzare application.workbook come si potrebbe fare?

    in pratica facciamo finta di non avere funzione somma se e di doverla inventare!



  • di isy@ (utente non iscritto) data: 01/01/2013 10:33:38

    Ciao

    Citazione: in pratica facciamo finta di non avere funzione somma se e di doverla inventare!

    Non corrisponde esattamente alla funzione macro...
    Ecco un esempio
     
    Sub Somma_se_VBA()
        Dim r   As Long
        Dim i   As Long, j As Variant
        Dim ka, kb, k()
        Dim x As Variant
        x = 12.5 'valore da cercare
        r = Range("A" & Rows.Count).End(3).Row
    
        ka = Range("A1:B" & r)  'Range di una o più colonne
        kb = Range("C1:C" & r)  'nota: Somma i valori da una sola colonna!
    
        ReDim k(1 To UBound(ka, 1), 1 To 1)
        j = 0
        For i = 1 To UBound(ka, 1)
            If ka(i, 1) = x Then
                j = kb(i, 1) + j
                k(i, 1) = j
            End If
        Next
        'risultato in colonna E
        Range("E1").Resize(UBound(k, 1)) = k
    
        Cells(UBound(k, 1), 6) = j  'Risultato Finale
    End Sub
    



  • di Mangusta (utente non iscritto) data: 01/01/2013 10:58:07

    Grazie grazie!!! mi studio il codice!!!



  • di Vecchio Frac data: 01/01/2013 11:12:07

    Mangusta, ti invito a produrre una tua soluzione ^_^ anche in linguaggio naturale! chiediti: a cosa serve la funzione? di che parametri ha bisogno? come la dovrei costruire? cosa deve fare e cosa voglio che restituisca?

    @isy
    io costruirei una Function, non una Sub, perchè quello che chiede mangusta è, appunto, simulare una funzione che dia un risultato.

    Io sto pensando intanto alla mia...





  • di isy@ (utente non iscritto) data: 01/01/2013 12:17:19

    ciao

    Ciatazione: io costruirei una Function, non una Sub

    Ecco la Function, che opera come nel precedente post..
    Questo codice "però" non è ottimizzato per operare in un foglio di 1.000.000 di righe!
     
    '=MyFunc(A1:B10;3,1;"C")
    
    Function MyFunc(RangeA As Range, MyArg1 As Variant, ColX As String)
        For Each celle In RangeA
            If celle.Value = MyArg1 Then
                MyFunc = MyFunc + Cells(celle.Row, ColX).Value
            End If
        Next
    End Function



  • di Vecchio Frac data: 01/01/2013 12:22:13

    Faccio una proposta veloce veloce.
    La funzione SOMMA_CONDIZIONALE accetta tre parametri come SOMMA.SE:
    - intervallo (il range contenente i valori di riferimento)
    - criterio (che può essere un valore stringa o un range a sua volta, che contiene il criterio da applicare)
    - int_somma (il range che contiene l'intervallo da cui pescare i dati da sommare). Questo parametro è facoltativo e, se omesso, si utilizza intervallo.

    La funzioncina è talmente semplice che risulta imprecisa e non fedele del tutto all'originale.
    Infatti il "criterio" considerato è sempre e solo l'uguaglianza; bisognerebbe costruire un parser del criterio (che dovrebbe poter scriversi anche come ">15" oppure "<>pippo"). Qui però l'operazione la vedo complessa in poche righe di codice; sarebbe da studiarsi una bella soluzione con le "espressioni regolari" (capitolo lungo, interessante e piuttosto difficile quanto potentissimo).

    Si usa così, anche in un foglio di lavoro oltre che in una macro per farsi restituire un valore:
    valore = somma_condizionale([A1:A7],"pippo",[B1:B7])
    in valore troveremo la somma delle celle corrispondenti che contengono "pippo" (posto che un elenco di nomi sia in A e una serie di valori da sommare in B).
     
    Option Explicit
    
    Function somma_condizionale(intervallo As Range, criterio As Variant, Optional int_somma As Range)
    Dim cella As Range, somma As Long, i As Long, intervallo_somma As Range
    
        If int_somma Is Nothing Then
            Set intervallo_somma = intervallo
        Else
            Set intervallo_somma = int_somma
        End If
    
        For Each cella In intervallo
            i = i + 1
            If cella = (criterio) Then
                somma = somma + intervallo_somma(i)
            End If
        Next
        somma_condizionale = somma
    End Function
    






  • di Vecchio Frac data: 01/01/2013 12:44:48

    @isy
    mi hai battuto di pochi minuti ^_^ i nostri due codici sono concettualmente identici... mangusta potrà esaminarli e valutarne le piccole differenze :)