none
Retornar o menor valor maior que zero condicionado RRS feed

  • Pergunta

  • Prezados, boa noite!

    Conforme imagem em anexo, de B3:F35, temos a amostra abaixo.

    Zona Família Embalagem          Tipo $PVV
    Sul Cane 300              Boi  R$    3,00
    Sul Cane 500               Ave  R$    9,00
    Leste Cane 300            Peixe  R$  19,00
    Sul Cane 500            Boi  R$    7,00

    O VBA que segue, retornar o menor valor maior que zero, o mesmo que posso obter com a formula matricial {=MÍNIMOA(SE((F4:F35)>0;(F4:F35)))}, mas o meu objetivo é obter o menor valor condicionando conforme ZONA, FAMILIA, TIPO.

    ub MenorValorMaiorQZero()
        Dim Minimo
        Dim i As Long
        
        Minimo = "A"
        For i = 1 To ActiveSheet.UsedRange.Rows.Count
            If Cells(i, "F").Value <> 0 And Cells(i, "F").Value <> "" Then
                If Minimo = "A" Then
                    Minimo = Cells(i, "F").Value
                Else
                    If Cells(i, "F").Value < Minimo Then
                        Minimo = Cells(i, "F").Value
                    End If
                End If
            End If
        Next
        
        
        'MsgBox "Mínimo: " & Minimo
            
        Range("I27").Select
        ActiveCell.FormulaR1C1 = Minimo
        
        
    End Sub

    Ratificando, tenho um valor de PVV para uma série de produtos classificados por ZONA, FAMÍLIA (DE PRODUTO), EMBALAGEM e TIPO, quero retornar o menor valor maior que zero, dessas categorias previamente organizadas em H3:L9.

    Alguém sabe? No aguardo e obrigado!



    :P

    sexta-feira, 13 de junho de 2014 00:39

Respostas

  • Paulo, agora entendi o que vc quer fazer em VBA, graças ao nosso amigo: Felipe Costa Gualberto.

    Esse é o Código, que faz a verificação cruzando os valores familia, embalagem, tipo.

    Ficou um pouco grande, mas pode ser corrigido através de uma sub verificar_venda(familia as string,  embalagem as string, tipo as string, Zona as string) 

    Espero que ajude.

    Sub menor()

    Dim menor As String
    Dim ponteiro As String
    Dim valores As Variant
    Dim familia As String
    Dim embalagem As String
    Dim tipo As String
    Dim Total As Integer
    Dim i As Integer
    Dim j As Integer
    Dim k As Integer

    Total = Range("F4", Plan1.Range("f4").End(xlDown).Offset(0, 0).Address).Rows.Count


    For j = 4 To 9
    ponteiro = "-"
    menor = 0
    familia = Range("h" & j).Value
    embalagem = Range("i" & j).Value
    tipo = Range("j" & j).Value


    For i = 4 To Total + 4
    If (Range("c" & i).Value = familia And Range("d" & i).Value = embalagem And Range("e" & i).Value = tipo And Range("b" & i).Value = "Sul") Then
    If (Range("f" & i).Value > 0 And Range("f" & i).Value <> "-") Then
    ponteiro = Range("f" & i).Value

    For k = i To Total + 4
    If (Range("c" & k).Value = familia And Range("d" & k).Value = embalagem And Range("e" & k).Value = tipo And Range("b" & k).Value = "Sul") Then
    If (Range("f" & k).Value < ponteiro And Range("f" & k).Value <> "-" And Range("f" & k).Value > 0) Then

    menor = Range("f" & k).Value

    Else

    menor = ponteiro

    End If
    End If

    Next k

    Exit For

    Else

    menor = ponteiro
    Exit For

    End If
    Else
    menor = ponteiro
    End If

    Next i


    Range("k" & j).Value = menor

    Next j

    '-----------------------------------------------------------------------------------------------------

    For j = 4 To 9
    ponteiro = "-"
    menor = 0
    familia = Range("h" & j).Value
    embalagem = Range("i" & j).Value
    tipo = Range("j" & j).Value


    For i = 4 To Total + 4
    If (Range("c" & i).Value = familia And Range("d" & i).Value = embalagem And Range("e" & i).Value = tipo And Range("b" & i).Value = "Leste") Then
    If (Range("f" & i).Value > 0 And Range("f" & i).Value <> "-") Then
    ponteiro = Range("f" & i).Value

    For k = i To Total + 4
    If (Range("c" & k).Value = familia And Range("d" & k).Value = embalagem And Range("e" & k).Value = tipo And Range("b" & k).Value = "Leste") Then
    If (Range("f" & k).Value < ponteiro And Range("f" & k).Value <> "-" And Range("f" & k).Value > 0) Then

    menor = Range("f" & k).Value

    Else

    menor = ponteiro

    End If
    End If

    Next k

    Exit For

    Else

    menor = ponteiro
    Exit For

    End If
    Else
    menor = ponteiro
    End If

    Next i


    Range("l" & j).Value = menor

    Next j


    End Sub


    sábado, 14 de junho de 2014 18:25

Todas as Respostas

  • Boa noite Paulo.

    Eu no seu lugar não usaria Macro para uma tarefa dessas. Um simples Tabela Dinâmica resolve seu problema com muito mais facilidade e flexibilidade.

    Já pensou a respeito?

    Abraço.


    Filipe Magno

    sexta-feira, 13 de junho de 2014 01:46
  • Olá Paulo!

    Sua necessidade pode ser atendida melhorando sua fórmula matricial. A fórmula matricial baseando-se na sua imagem acima, na célula K4 seria:

    =MÍNIMO(SE(($B$4:$B$35&$C$4:$C$35&$D$4:$D$35&$E$4:$E$35=K$3&$H4&$I4&$J4)*SE(($F$4:$F$35)<>0;1);$F$4:$F$35))

    * Não esquecer de dar Crtl + Shift + Enter ao invés de enter.

    Essa fórmula você poderá arrastar para a direita e bara baixo para cobrir todos os campos da sua tabela em K4:L9.

    Se todos os Preços da sua fonte estiverem zerados para o critério a fórmula retornará "0", então se quiser você pode fazer uma condição para trazer alguma mensagem ao invés de zero, por exemplo:

    =SE(MÍNIMO(SE(($B$4:$B$35&$C$4:$C$35&$D$4:$D$35&$E$4:$E$35=K$3&$H4&$I4&$J4)*SE(($F$4:$F$35)<>0;1);$F$4:$F$35))=0;"Valores Zerados";MÍNIMO(SE(($B$4:$B$35&$C$4:$C$35&$D$4:$D$35&$E$4:$E$35=K$3&$H4&$I4&$J4)*SE(($F$4:$F$35)<>0;1);$F$4:$F$35)))

    Neste caso, se todos os valores para os critérios estiverem zerados, vai trazer a mensagem "Valores Zerados".

    Abraços!


    Rafael Kamimura

    • Sugerido como Resposta Rafael Kamimura sexta-feira, 13 de junho de 2014 12:16
    sexta-feira, 13 de junho de 2014 11:27
  • Não vou poder explicar agora, mas não posso usar dinâmica nesse caso.

    Obrigado!


    :P

    sexta-feira, 13 de junho de 2014 12:10
  • Não vou poder explicar agora, mas não posso usar dinâmica nesse caso.

    Obrigado!


    :P

    Olá Paulo! Você não pôde usar dinâmica, mas as fórmulas que passei te atenderam? Se sim, marque como resposta para fechar o thread!

    Abraços!


    Rafael Kamimura

    sexta-feira, 13 de junho de 2014 18:18
  • Paulo, vê se o código abaixo te ajuda.

    Ele verifica o valor menor da coluna "F" a partir da linha 4.

    Sub menor()

    Dim menor As String
    Dim ponteiro As String
    Dim temp As Variant
    Dim orde As String
    Dim valores As Variant


    menor = 0
    ponteiro = range("f4").Value

    valores = range("F4", Plan1.range("f4").End(xlDown).Offset(0, 0).Address)

    For Each temp In valores

    If (temp < ponteiro) Then
    If (temp > 0) Then
    menor = temp
    ponteiro = temp
    End If
    End If
    If (temp > ponteiro) Then
    If (ponteiro > 0) Then
    menor = ponteiro
    End If
    End If

    Next



    range("i27").Value =  menor

    End Sub


    • Sugerido como Resposta Supimpa sexta-feira, 13 de junho de 2014 23:12
    • Editado Supimpa sábado, 14 de junho de 2014 00:06
    • Não Sugerido como Resposta Supimpa sábado, 14 de junho de 2014 00:58
    sexta-feira, 13 de junho de 2014 22:46
  • =MÍNIMO(SE((F4:F35>0)*(B4:B35="Sul")*(C4:C35="Carne")*(E4:E35="Boi");F4:F35))

    Felipe Costa Gualberto - http://www.ambienteoffice.com.br

    sábado, 14 de junho de 2014 01:35
    Moderador
  • Paulo, agora entendi o que vc quer fazer em VBA, graças ao nosso amigo: Felipe Costa Gualberto.

    Esse é o Código, que faz a verificação cruzando os valores familia, embalagem, tipo.

    Ficou um pouco grande, mas pode ser corrigido através de uma sub verificar_venda(familia as string,  embalagem as string, tipo as string, Zona as string) 

    Espero que ajude.

    Sub menor()

    Dim menor As String
    Dim ponteiro As String
    Dim valores As Variant
    Dim familia As String
    Dim embalagem As String
    Dim tipo As String
    Dim Total As Integer
    Dim i As Integer
    Dim j As Integer
    Dim k As Integer

    Total = Range("F4", Plan1.Range("f4").End(xlDown).Offset(0, 0).Address).Rows.Count


    For j = 4 To 9
    ponteiro = "-"
    menor = 0
    familia = Range("h" & j).Value
    embalagem = Range("i" & j).Value
    tipo = Range("j" & j).Value


    For i = 4 To Total + 4
    If (Range("c" & i).Value = familia And Range("d" & i).Value = embalagem And Range("e" & i).Value = tipo And Range("b" & i).Value = "Sul") Then
    If (Range("f" & i).Value > 0 And Range("f" & i).Value <> "-") Then
    ponteiro = Range("f" & i).Value

    For k = i To Total + 4
    If (Range("c" & k).Value = familia And Range("d" & k).Value = embalagem And Range("e" & k).Value = tipo And Range("b" & k).Value = "Sul") Then
    If (Range("f" & k).Value < ponteiro And Range("f" & k).Value <> "-" And Range("f" & k).Value > 0) Then

    menor = Range("f" & k).Value

    Else

    menor = ponteiro

    End If
    End If

    Next k

    Exit For

    Else

    menor = ponteiro
    Exit For

    End If
    Else
    menor = ponteiro
    End If

    Next i


    Range("k" & j).Value = menor

    Next j

    '-----------------------------------------------------------------------------------------------------

    For j = 4 To 9
    ponteiro = "-"
    menor = 0
    familia = Range("h" & j).Value
    embalagem = Range("i" & j).Value
    tipo = Range("j" & j).Value


    For i = 4 To Total + 4
    If (Range("c" & i).Value = familia And Range("d" & i).Value = embalagem And Range("e" & i).Value = tipo And Range("b" & i).Value = "Leste") Then
    If (Range("f" & i).Value > 0 And Range("f" & i).Value <> "-") Then
    ponteiro = Range("f" & i).Value

    For k = i To Total + 4
    If (Range("c" & k).Value = familia And Range("d" & k).Value = embalagem And Range("e" & k).Value = tipo And Range("b" & k).Value = "Leste") Then
    If (Range("f" & k).Value < ponteiro And Range("f" & k).Value <> "-" And Range("f" & k).Value > 0) Then

    menor = Range("f" & k).Value

    Else

    menor = ponteiro

    End If
    End If

    Next k

    Exit For

    Else

    menor = ponteiro
    Exit For

    End If
    Else
    menor = ponteiro
    End If

    Next i


    Range("l" & j).Value = menor

    Next j


    End Sub


    sábado, 14 de junho de 2014 18:25
  • Obrigado a todos! 

    Com base na sua resposta Rafael consegui adaptar a minha solução e avançar. Muito obrigado!



    :P

    sábado, 30 de agosto de 2014 13:53