Excel MIN e ContaSe



  • Excel: MIN e Conta.Se
    di JackQueen data: 05/02/2015 17:55:14

    Salve a tutti, sono un nuovo utente appena iscritto. Ho riscontrato alcune difficoltà con Excel e su alcuni ragionamenti e vorrei un vostro parere:
    ho una colonna in cui sono presenti diversi valori numerici; con la funzione conta.se riesco a determinare il numero di valori minori, ad esempio, di 3. Ovvero se avessi i valori: 2,1,4,5,2,3,2 attraverso conta.se trovo che il numero di valori minori a 3 è 4.
    Se adesso però vorrei sapere quale di questi valori è il massimo come posso procedere?



  • di Mister_x (utente non iscritto) data: 05/02/2015 18:31:15

    ciao

    i tuoi dati in colonna A:A
    in B1=PICCOLO(A1:A7;CONTA.SE(A1:A7;" <3"))

    2 --- 2,7
    1
    4
    5
    2,7
    3
    2


    ciao







  • di Vecchio Frac data: 05/02/2015 18:32:04

    ^_^
     
    Option Explicit
    
    Function max_if(r As Range, crit As Integer) As Long
    Dim cell As Range, rng As Range
        For Each cell In r
            If cell < crit Then
                If rng Is Nothing Then
                    Set rng = cell
                Else
                    Set rng = Union(rng, cell)
                End If
            End If
        Next
        max_if = Application.Max(rng)
    End Function






  • di ninai (utente non iscritto) data: 05/02/2015 19:07:06

    Ciao
    Mistex, interessante l'uso controintuitivo che hai fatto di PICCOLO(), non ci avrei pensato, avrei usato:
    =MAX(INDICE((A1:A7<3)*A1:A7;))



  • di scossa data: 05/02/2015 20:51:09

    Visto che la formula di ninai non posso "tagliarla" se non con una matriciale, propongo un codice anch'io, da usarsi come da esempio seguente:

    =max_se(A1:A7;"<3")


    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)

     
    Function max_se(ByVal rng As Range, ByVal sCrit As String) As Long
        max_se = Evaluate("=MAX(INDEX((" & rng.Address & sCrit & ")*" & rng.Address & ",))")
    End Function
    



  • di Vecchio Frac data: 05/02/2015 20:59:42

    No no, non vale, niente Evaluate che sono capaci tutti di applicare a VBA le formule di Excel ^_^
    Devi correggere la mia versione e magari prevedere un parametro anche per valutare il criterio (perchè fermarsi al confronto "minore di"? )...

    LOL... non sto naturalmente parlando sul serio :)





  • di scossa data: 05/02/2015 21:55:32

    Non puoi passare il criterio, che deve essere per forza una stringa, e non usare Evaluate.

    Si può tenere Application.Max() "esterno" all'Evaluate, ma cambia poco.



    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)

     
    Function max_se2(ByVal rng As Range, ByVal sCrit As String) As Long
      With Application
        max_se2 = .Max(.Evaluate("Index((" & rng.Address & sCrit & ")*" & rng.Address & ",)"))
      End With
    End Function
    



  • di scossa data: 05/02/2015 22:03:33

    Ecco il tuo codice (col ciclo For) modificato per passare il criterio, da usarsi:

    =max_if2(A1:A7;"<3")


    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)

     
    Function max_if2(r As Range, sCrit As String) As Long
    Dim cell As Range, rng As Range
        For Each cell In r
            If Evaluate(cell.Address & sCrit) Then
                If rng Is Nothing Then
                    Set rng = cell
                Else
                    Set rng = Union(rng, cell)
                End If
            End If
        Next
        max_if2 = Application.Max(rng)
    End Function



  • di Vecchio Frac data: 05/02/2015 22:30:28

    cit. "Non puoi passare il criterio, che deve essere per forza una stringa, e non usare Evaluate. "
    ---> L'affermazione è troppo "assoluta" per essere vera ^_^
    Posso passare un criterio, che è una stringa, ma non devo per forza usare Evaluate.

    Impraticabile naturalmente e valido solo per scopi didattici.
    Dovrei cioè prevedere, a botte di Select Case, i criteri che mi servono e gestirli da codice.
    Visto che era solo per dire, non insisto più ^_^
     
    Prototipo:
    function m(rng as range, operator as string, value as long)
        for each cell in rng
            select case operator
            case "<": if cell < value then set r = Union (r, rng)
            case ">": if cell > value ...
            case "<=": ....
            ecc.
            end select
        next
        m = Max(r)
    end function
      






  • di scossa data: 05/02/2015 23:04:19

    cit. VF: " L'affermazione è troppo "assoluta" per essere vera"

    Beh certo, ovvio che mi riferivo ad una soluzione appunto "praticabile". Ma la tua soluzione è meglio archiviarla, si sa mai che MS elimini il metodo Application.Evaluate nella prossima versione di Excel/VBA


    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 JackQueen (utente non iscritto) data: 06/02/2015 00:12:14

    Grazie mille a tutti per la risposta ho scelto di mettere in pratica il primo esempio perchè sono obbligato a lavorare solo sulle formule su celle e non posso implementare il tutto con vba...ne approfitto (perdonatemi) di chiedervi allora come potrei, sempre utilizzando le formule, visionare i valori contati dal conta.se? e quindi dall'esempio come posso visualizzare, dopo aver determinato che conta.se è 4, i valori 2,1,2,2?



  • di Mister_x (utente non iscritto) data: 06/02/2015 00:40:12

    ciao
    in questo caso sarebbe utile utilizzare VBA, ma dato che non si puo fare in C1

    C1=SE(RIF.RIGA(A1)<=CONTA.SE(A$1:A$7;" <3");PICCOLO(A$1:A$7;RIF.RIGA(A1));"")

    e trascini in giu' Ps attento ai riferimenti relativi $

    2-------- 2,7---- 1
    1-------- ---- 2
    4-------- ---- 2
    5-------- ---- 2,7
    2,7
    3
    2

    ciao





  • di scossa data: 06/02/2015 09:44:10

    @ Vecchio Frac:

    Ieri ho pensato e ripensato ad una alternativa alla tua proposta senza Evaluate().
    Ho partorito l'UDF che riporto sotto e che sostituisce il costrutto Select Case con un'unica istruzione.

    Sarebbe interessante riuscire ad eliminare il ciclo For...Next, ma senza Evaluate() mi sembra improbabile.




    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)

     
    Function Max_SeOP(ByVal rng As Range, ByVal sOp As String, nVal As Double) As Double
      Dim vVal As Variant
      Dim aVal As Variant
      Dim j As Long
      
      aVal = Application.Transpose(rng)
      
      For j = LBound(aVal) To UBound(aVal)
        vVal = aVal(j)
        aVal(j) = (sOp = "<") * (vVal < nVal) * vVal + (sOp = "<=") * (vVal <= nVal) * vVal + (sOp = ">") * (vVal > nVal) * vVal + _
          (sOp = ">=") * (vVal >= nVal) * vVal + (sOp = "<>") * (vVal <> nVal) * vVal
      Next
      Max_SeOP = Application.Max(aVal)
      
    End Function
    
    



  • di Vecchio Frac data: 06/02/2015 11:48:18

    +1
    Qui ragazzi ci vuole un applauso a scossa (lo sapevo che bisognava stimolarlo nel punto giusto ^_^)

    cit. "Sarebbe interessante riuscire ad eliminare il ciclo For...Next"
    ---> Mi è venuto in mente adesso che si potrebbe usare Switch. Per chi ha voglia di provarci :)

    cit. "si sa mai che MS elimini il metodo Application.Evaluate nella prossima versione di Excel/VBA"
    ---> Io spero sempre che implementi finalmente python for Office :)





  • di JackQueen (utente non iscritto) data: 06/02/2015 12:50:07

    Grazie mille :) mi serviva proprio il vostro aiuto, ho messo "Risolto" alla discussione. A presto



  • di scossa data: 06/02/2015 16:10:31

    cit. V.F.: " Io spero sempre che implementi finalmente python for Office :) "

    Io cosa che vorrei maggiormente è che aggiornassero quella schifosissima funzione CONCATENA() con una versione che permetta di passare un range di celle come argomento: =CONCATENA(A1:B5) e le concatenasse, magari specificando pure una stringa di concatenamento (style join()), =CONCATENA(A1:B5; "|")



    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: 06/02/2015 16:34:26

    Sì, per appiattire un range. Al momento vedere tutti quegli & rende abbastanza illeggibili le formule.
    Ma non solo quello. Ce ne sarebbe di roba da migliorare, a partire dall'infame localizzazione delle formule (e se io non ho la tastiera italiana? come faccio a scrivere =SOMMA.PIù.SE? LOL)





  • di JackQueen data: 24/02/2015 12:59:16

    Scusatemi se riapro una piccola parentesi ma vorrei capire solo una cosa: sempre per lo stesso discorso come mai se applico la formula =GRANDE(matrice;CONTA.SE(matrice;">"&cella)) mi torna il minimo dei valori maggiori del valore della cella?